diff --git a/sls/trunk/Makefile.am b/sls/trunk/Makefile.am index 31cfe385ac90359e6aee4f99e3c2165670474b43..666f69bc98e9324d04550412920c83655da5d8ce 100644 --- a/sls/trunk/Makefile.am +++ b/sls/trunk/Makefile.am @@ -33,7 +33,9 @@ sls_SOURCES= src/sls.hh \ src/connection.cc \ src/client.hh \ src/client.cc \ + src/client_console.hh \ src/client_console.cc \ + src/client_daemon.hh \ src/client_daemon.cc CLEANFILES= *~ '\#*' diff --git a/sls/trunk/src/client.cc b/sls/trunk/src/client.cc index 48880188d2f7e37319c95901a58fdae3be7708cc..2299a06a603ff7809db38495f4593dbe55e686c8 100644 --- a/sls/trunk/src/client.cc +++ b/sls/trunk/src/client.cc @@ -18,56 +18,68 @@ #include "sls.hh" #include "client.hh" +#include "client_console.hh" +#include "client_daemon.hh" + +static inline Client *login_fail(Connection &c); /******************************************************************************* ** Method of Classes *******************************************************************************/ Client *Client::login(Connection &c) { + + // read login info string slogin = c.recvln(); string spass = c.recvln(); // FIXME: find better method than fucking magic number + char clientbuf[512]; char loginbuf[512]; char passbuf[512]; - + // cut read data + if (sscanf(slogin.c_str(), "%512s %512s\n", clientbuf, loginbuf) != 2) + return login_fail(c); if (sscanf(spass.c_str(), "PASS %512s\n", passbuf) != 1) return login_fail(c); - if (sscanf(slogin.c_str(), "HOST %512s\n", loginbuf) == 1) { - // check login and password - - // Register login and pass in client + // create client + Client *real_client; + if (strcmp(clientbuf, "HOST") == 0) + real_client = new Daemon(c); + else if (strcmp(clientbuf, "USER") == 0) + real_client = new Console(c); + else + return login_fail(c); - // Print succefful login - std::cout << "Connection id " << c.getid() << ": Host " << loginbuf - << " logged from " << c.getremoteip() - << " on port " << c.getremoteport() << ".\n"; - return new Daemon(c); - } - else if (sscanf(slogin.c_str(), "USER %512s\n", loginbuf) == 1) { - return new Console(c); + // check login and password and register it in DB if success + if (real_client->trust(loginbuf, passbuf) == false) { + delete real_client; + return login_fail(c); } - return login_fail(c); -} + // Print succefful login + std::cout << "CId " << c.getid() << ": Host " << loginbuf + << " logged from " << c.getremoteip() + << " on port " << c.getremoteport() << ".\n"; -Client *Client::login_fail(Connection &c) { - std::cout << "Connection id " << c.getid() << ": Bad authentification.\n"; - c.sendln("Bad authentification."); - return 0; + return real_client; } /******************************************************************************* -** Public Classes +** Public methods *******************************************************************************/ Client::Client(Connection &c) : c_ (c) {} Client::~Client() {} +/******************************************************************************* +** Local functions +*******************************************************************************/ - -void Client::exec() { - assert(0); +static Client *login_fail(Connection &c) { + std::cout << "CId " << c.getid() << ": Bad authentification.\n"; + c.sendln("Bad authentification."); + return 0; } diff --git a/sls/trunk/src/client.hh b/sls/trunk/src/client.hh index 9db042a612937b70809f291b32f9f2020fcbf847..61248462fb94c52687ac4154593d4e1e6901276e 100644 --- a/sls/trunk/src/client.hh +++ b/sls/trunk/src/client.hh @@ -21,42 +21,24 @@ # include "connection.hh" -/*! -** Client Class +/** + * Client */ class Client { public: - Client(Connection &c); virtual ~Client(); - virtual void exec(); + virtual void exec() = 0; static Client *login(Connection &c); protected: - Connection c_; - -private: - static Client *login_fail(Connection &c); -}; - -/*! -** Client Daemon Class - */ -class Daemon: public Client { -public: - Daemon(Connection &c); - void exec(); -}; + Client(Connection &c); -/*! -** Client Console Class - */ -class Console : public Client { -public: - Console(Connection &c); - void exec(); + virtual bool trust(const char *login, const char *pass) = 0; +protected: + Connection c_; + string login_; }; - #endif diff --git a/sls/trunk/src/client_console.cc b/sls/trunk/src/client_console.cc index b7e2da8dbf1b0cd2e1b2b6dfe1abed707243d600..423c23ed543143f434e5c07eb9815e3dcc7946c6 100644 --- a/sls/trunk/src/client_console.cc +++ b/sls/trunk/src/client_console.cc @@ -17,10 +17,81 @@ */ #include "sls.hh" -#include "client.hh" +#include "error.hh" +#include "option.hh" +#include "client_console.hh" -Console::Console(Connection &c) : Client(c) {} +/******************************************************************************* +** Public methods +*******************************************************************************/ +/** + * Entry point for a console backend + */ void Console::exec() { - c_.sendln("You are a console !!"); + while (1) { + // receive line + string cmd = c_.recvln(); + + // Print info + if (O.verbose) std::cout << "Cid " << c_.getid() << ": Receive: " << cmd << ".\n"; + else std::cout << "Cid " << c_.getid() << ": Receive request.\n"; + + // call parser + try { parse(cmd); } + catch (const Error &e) { + if (e.code() == ERR_PARSE) { + // Print info + if (O.verbose) std::cout << "Cid " << c_.getid() << ": Parse error: " << e << ".\n"; + else std::cout << "Cid " << c_.getid() << ": Invalid command.\n"; + } + else throw; + } + } +} + +/******************************************************************************* +** Protected methods +*******************************************************************************/ + +/** + * Constructor + * + * @param c Attached connection + */ +Console::Console(Connection &c) : Client(c) {} + +/** + * Check if login and pass are valid user + * and register login and pass are logged in DB + * + * @param login user login + * @param pass user pass + * + * @return if user is logged or not + */ +bool Console::trust(const char *login, const char *pass) { + assert(login); + assert(pass); + + // check login and password in DB + c_.sendln("User always trusted !!"); + + // store username + login_ = login; + + // register as logged in DB + + return true; +} + +/** + * Parse and execute + * + * @param cmd string to parse + */ +void Console::parse(const string &cmd) { + if (!cmd.empty()) + throw Error(ERR_PARSE, "Empty command"); + // FIXME } diff --git a/sls/trunk/src/client_console.hh b/sls/trunk/src/client_console.hh new file mode 100644 index 0000000000000000000000000000000000000000..ebdbdec6afb312c64729009c08cd4eff2bb8a7c2 --- /dev/null +++ b/sls/trunk/src/client_console.hh @@ -0,0 +1,40 @@ +/* + This file is part of SLS. + Copyright (C) 2008 Sebastien LUTTRINGER + + SLS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + SLS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SLS; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CLIENT_CONSOLE_HH +# define CLIENT_CONSOLE_HH + +# include "client.hh" + +/*! +** Client Console Class + */ +class Console : public Client { +public: + friend class Client; + virtual void exec(); +protected: + Console(Connection &c); + + virtual bool trust(const char *login, const char *pass); + + void parse(const string &cmd); + +}; + +#endif diff --git a/sls/trunk/src/client_daemon.cc b/sls/trunk/src/client_daemon.cc index 641360050ebe77bdfcff5933d92eb461c0a28e04..1257ed4d86740d6c83042fe4666d4f1a04222be4 100644 --- a/sls/trunk/src/client_daemon.cc +++ b/sls/trunk/src/client_daemon.cc @@ -17,9 +17,11 @@ */ #include "sls.hh" -#include "client.hh" +#include "client_daemon.hh" -Daemon::Daemon(Connection &c) : Client(c) {} +/******************************************************************************* +** Public methods +*******************************************************************************/ void Daemon::exec() { // send scripts @@ -28,3 +30,39 @@ void Daemon::exec() { c_.sendln("EXIT"); } + + +/******************************************************************************* +** Protected methods +*******************************************************************************/ + +/** + * Constructor + * + * @param c Attached connection + */ +Daemon::Daemon(Connection &c) : Client(c) {} + +/** + * Check if login and pass are valid daemon + * and register login and pass are logged in DB + * + * @param login user login + * @param pass user pass + * + * @return if daemon is logged or not + */ +bool Daemon::trust(const char *login, const char *pass) { + assert(login); + assert(pass); + + // check login and password in DB + c_.sendln("Daemon always untrusted !!"); + + // store username + login_ = login; + + // register as logged in DB + + return false; +} diff --git a/sls/trunk/src/client_daemon.hh b/sls/trunk/src/client_daemon.hh new file mode 100644 index 0000000000000000000000000000000000000000..9fd529c1151f0582f83697d5cfbae2b7fc76873e --- /dev/null +++ b/sls/trunk/src/client_daemon.hh @@ -0,0 +1,38 @@ +/* + This file is part of SLS. + Copyright (C) 2008 Sebastien LUTTRINGER + + SLS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + SLS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with SLS; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef CLIENT_DAEMON_HH +# define CLIENT_DAEMON_HH + +# include "client.hh" + +/*! +** Client Daemon Class + */ +class Daemon: public Client { +public: + friend class Client; + virtual void exec(); + +protected: + Daemon(Connection &c); + + virtual bool trust(const char *login, const char *pass); +}; + +#endif diff --git a/sls/trunk/src/connection.cc b/sls/trunk/src/connection.cc index 288afbeba3f0e53a91ce83ad7cf0ed7fd09612bf..aa25541436ba4d09eea44f71074ab1e97a540c09 100644 --- a/sls/trunk/src/connection.cc +++ b/sls/trunk/src/connection.cc @@ -179,7 +179,7 @@ void Connection::listen(int port, int max) { * Disconnect socket */ void Connection::disconnect() { - if (socket < 0) + if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to disconnect"); // lock all mutex @@ -218,7 +218,7 @@ bool Connection::connected() { * @return null on error, else a new connection */ Connection *Connection::accept() { - if (socket < 0) + if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to accept"); struct sockaddr_in r_addr; @@ -243,7 +243,7 @@ Connection *Connection::accept() { * Send data on @param buf of size @param len on socket */ void Connection::send(const char* buf, size_t len) { - if (socket < 0) + if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send data"); pthread_mutex_lock(&w_mutex_); @@ -260,7 +260,7 @@ void Connection::send(const char* buf, size_t len) { * Send data on @param buf of size @param len followed by '\n' on socket */ void Connection::sendln(const char* buf, size_t len) { - if (socket < 0) + if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to send line"); pthread_mutex_lock(&w_mutex_); @@ -284,7 +284,7 @@ void Connection::sendln(const char* buf, size_t len) { * Receive a line */ string Connection::recvln() { - if (socket < 0) + if (socket_fd_ < 0) throw Error(ERR_NET, "No connection established but trying to receive line"); pthread_mutex_lock(&r_mutex_); @@ -327,6 +327,9 @@ string Connection::recvln() { } string Connection::getlocalip() { + if (socket_fd_ < 0) + throw Error(ERR_NET, "No connection established but trying to get local ip"); + pthread_mutex_lock(&c_mutex_); if (local_ip_.empty()) setlocalip_(); @@ -336,6 +339,9 @@ string Connection::getlocalip() { } int Connection::getlocalport() { + if (socket_fd_ < 0) + throw Error(ERR_NET, "No connection established but trying to get local port"); + pthread_mutex_lock(&c_mutex_); if (local_port_ == -1) setlocalport_(); @@ -345,6 +351,9 @@ int Connection::getlocalport() { } string Connection::getremoteip() { + if (socket_fd_ < 0) + throw Error(ERR_NET, "No connection established but trying to get remote ip"); + pthread_mutex_lock(&c_mutex_); if (remote_ip_.empty()) setremoteip_(); @@ -354,6 +363,9 @@ string Connection::getremoteip() { } int Connection::getremoteport() { + if (socket_fd_ < 0) + throw Error(ERR_NET, "No connection established but trying to get remote port"); + pthread_mutex_lock(&c_mutex_); if (remote_port_ == -1) setremoteport_(); @@ -367,6 +379,9 @@ unsigned long int Connection::getid() { } int Connection::getsocket() { + if (socket_fd_ < 0) + throw Error(ERR_NET, "No connection established but trying to get socket fd"); + pthread_mutex_lock(&c_mutex_); int ret = socket_fd_; pthread_mutex_unlock(&c_mutex_); diff --git a/sls/trunk/src/server.cc b/sls/trunk/src/server.cc index 4886b3ab727388e2be3afe5ba21f127ab262c4e8..884dff96b7ae842472559103e2788e6575a3c265 100644 --- a/sls/trunk/src/server.cc +++ b/sls/trunk/src/server.cc @@ -73,7 +73,7 @@ void Server::start(int port, size_t max_conn, bool verbose) { // check max conn if (threads_.size() >= max_conn_) { - std::cout << "Connection id " << nc->getid() << ": Refused from ip " << nc->getremoteip() + std::cout << "CId " << nc->getid() << ": Refused from ip " << nc->getremoteip() << " on port " << nc->getremoteport() << ": Max connections reached.\n"; nc->disconnect(); @@ -81,7 +81,7 @@ void Server::start(int port, size_t max_conn, bool verbose) { } // Print connection - std::cout << "Connection id " << nc->getid() << ": New connection from ip " + std::cout << "CId " << nc->getid() << ": New connection from ip " << nc->getremoteip() << " on port " << nc->getremoteport(); if (verbose_) std::cout << " (socket " << nc->getsocket() << ")" ; @@ -177,14 +177,14 @@ void *Server::start_client(void *voidconn) { } } catch (const Error &e) { - std::cerr << "Connection id " << conn->getid() << ": " << e << ".\n"; + std::cerr << "CId " << conn->getid() << ": " << e << ".\n"; } // stop connexion conn->disconnect(); // Print closing connection - std::cout << "Connection id " << conn->getid() << ": Closed.\n"; + std::cout << "CId " << conn->getid() << ": Closed.\n"; // remove from thread set pthread_mutex_lock(&S.threads_mutex_); diff --git a/sls/trunk/src/sls.cc b/sls/trunk/src/sls.cc index 2312df32faa1756c649739d8fe5289b0b19b44cf..1665946c87f19a6c0a82a448c36142360f0dfd82 100644 --- a/sls/trunk/src/sls.cc +++ b/sls/trunk/src/sls.cc @@ -30,11 +30,18 @@ #include #include + +// ----------------------------------------------------------------------------- +// Globals +// ----------------------------------------------------------------------------- Option O; Database D; Server S; Cron C; +// ----------------------------------------------------------------------------- +// Functions +// ----------------------------------------------------------------------------- int main(int argc, char *argv[]) { try { diff --git a/sls/trunk/src/sls.hh b/sls/trunk/src/sls.hh index 6624b61fea2005659ff78857bf1757b7dc9a6357..51a060c1d9dddfff11bab37d7650f880a540912e 100644 --- a/sls/trunk/src/sls.hh +++ b/sls/trunk/src/sls.hh @@ -44,6 +44,7 @@ enum { ERR_DB = 7, ERR_SRV = 8, ERR_THREAD = 9, + ERR_PARSE = 10, ERR_NOMEM = 41, ERR_UNKNOWN = 42 }; @@ -56,4 +57,19 @@ static const string VERSION = (string) "testing.\nBuild: " + __DATE__ + " " + __ //static const string VERSION = "1.0"; static const int MAX_LINE_SIZE = 512; +// ----------------------------------------------------------------------------- +// global variables +// ----------------------------------------------------------------------------- +class Option; +extern Option O; + +class Database; +extern Database D; + +class Server; +extern Server S; + +class Cron; +extern Cron C; + #endif