From 023042a315261b3fbe9c7807dbe08fe8cc0517ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Luttringer?= Date: Mon, 14 Jan 2008 03:43:11 +0000 Subject: [PATCH] - fix bugs sur test de connection existante dans la classe connection - ajout de test de connection sur toutes les fonctions de la class connection - changement du mode de dispatch par la classe console, il faut desormais passer par login pour obtenir une class fils - separation des headers des classes clients filles et maman - ajout type d'erreur ERR_PARSE - Archi du backend console --- sls/trunk/Makefile.am | 2 + sls/trunk/src/client.cc | 58 +++++++++++++++---------- sls/trunk/src/client.hh | 34 ++++----------- sls/trunk/src/client_console.cc | 77 +++++++++++++++++++++++++++++++-- sls/trunk/src/client_console.hh | 40 +++++++++++++++++ sls/trunk/src/client_daemon.cc | 42 +++++++++++++++++- sls/trunk/src/client_daemon.hh | 38 ++++++++++++++++ sls/trunk/src/connection.cc | 25 ++++++++--- sls/trunk/src/server.cc | 8 ++-- sls/trunk/src/sls.cc | 7 +++ sls/trunk/src/sls.hh | 16 +++++++ 11 files changed, 284 insertions(+), 63 deletions(-) create mode 100644 sls/trunk/src/client_console.hh create mode 100644 sls/trunk/src/client_daemon.hh diff --git a/sls/trunk/Makefile.am b/sls/trunk/Makefile.am index 31cfe38..666f69b 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 4888018..2299a06 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 9db042a..6124846 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 b7e2da8..423c23e 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 0000000..ebdbdec --- /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 6413600..1257ed4 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 0000000..9fd529c --- /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 288afbe..aa25541 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 4886b3a..884dff9 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 2312df3..1665946 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 6624b61..51a060c 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 -- GitLab