Documentation

Generated on Thu Aug 31 00:02:40 2006

 

User Class Reference

#include <User.h>

Inheritance diagram for User:

Inheritance graph
[legend]
Collaboration diagram for User:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 User (int socket_id, struct sockaddr_in &addr)
vector< Data * >::iterator get_data_it (pthread_t)
Useroperator>> (string &message)
bool data_vec_full ()
bool login ()
 ~User ()
 MEMBER (logged_in, int)
 MEMBER (data_id, int)
 MEMBER (data_addr, struct sockaddr_in)
 MEMBER (current_dir, string)
 MEMBER (root_dir, string)
 MEMBER (temp_buf, string)
 MEMBER (failed_logins, int)
 MEMBER (pamh, pam_handle_t *)
 MEMBER (rest_pos, off_t)
 MEMBER (anonymous_id, string)
ssize_t send (const char *, size_t)
ssize_t receive (char *, size_t)
Connectionoperator<< (long long int num)
Connectionoperator<< (string message)
bool engage_tls ()
bool disengage_tls ()
bool verify_cert ()
bitset< TOTAL_U_BITsettings () const
bool settings (int bit)
void settings (int bit, int way)
pthread_t thread_id (void)
void thread_id (pthread_t var)
string host_name (void)
void host_name (string var)
int socket_id (void)
void socket_id (int var)
sockaddr_in addr (void)
void addr (struct sockaddr_in var)
size_t packet_size (void)
void packet_size (size_t var)
timeval timeout (void)
void timeout (struct timeval var)
string user_name (void)
void user_name (string var)
unsigned long long transfered (void)
void transfered (unsigned long long var)

Public Attributes

vector< Data * > data_vec
pthread_rwlock_t lock

Protected Attributes

bitset< TOTAL_U_BIT_settings

Detailed Description

Definition at line 25 of file User.h.


Constructor & Destructor Documentation

User::User ( int  socket_id,
struct sockaddr_in &  addr 
)

Definition at line 15 of file User.cpp.

References Connection::addr(), B_SET, config, Configuration::general_user, Connection::host_name(), users_stru::idle, LAST_FACT, NOT_LOGGED_IN, Connection::socket_id(), Connection::thread_id(), and Connection::timeout().

Referenced by Handler::initializer().

00015                                                   : Connection()
00016 {
00017   this->_root_dir = "/";
00018   this->_failed_logins = 0;
00019   this->_logged_in = NOT_LOGGED_IN;
00020   this->_data_id = 0;
00021   this->_rest_pos = 0;
00022   this->addr(addr);
00023   this->socket_id(socket_id);
00024   this->thread_id(pthread_self());
00025   this->host_name(inet_ntoa(this->addr().sin_addr));
00026   struct timeval tmp = {config->general_user.idle, 0};
00027   this->timeout(tmp);
00028 
00029   // setting the bitflags on mlst_facts... not to clean..
00030   for(int i = 0; i <= LAST_FACT; i++)
00031     this->settings(i, B_SET);
00032 }

Here is the call graph for this function:

User::~User (  ) 

Definition at line 34 of file User.cpp.

References comm, data_vec, get_user_it(), Utilities::itos(), Log::log_this(), logging, PAM_DONE, Commands::pam_lock, TYPE_INFO, user_list, user_list_lock, and util.

00035 {
00036   if(this->_data_id)
00037     close(this->_data_id);
00038 
00039   if(this->settings(PAM_DONE))
00040   {
00041     sem_wait(&comm.pam_lock);
00042     pam_close_session(this->_pamh, PAM_SILENT);
00043     pam_end(this->_pamh, PAM_SUCCESS);
00044     sem_post(&comm.pam_lock);
00045   }
00046 
00047   // killing off any ongoing data threads
00048   for(vector<Data*>::iterator data_it = data_vec.begin();
00049       data_it != data_vec.end(); data_it++)
00050     if(*data_it)
00051       pthread_cancel((*data_it)->thread_id());
00052 
00053   while(data_vec.size())
00054   {  }
00055 
00056   pthread_rwlock_wrlock(&user_list_lock);
00057   user_list.erase(get_user_it(this->thread_id()));
00058   logging->log_this(4, TYPE_INFO, "user thread " +
00059       util.itos(this->thread_id()) + " exiting, connected users:" +
00060       util.itos(user_list.size()));
00061   pthread_rwlock_unlock(&user_list_lock);
00062 }

Here is the call graph for this function:


Member Function Documentation

void Connection::addr ( struct sockaddr_in  var  )  [inline, inherited]

Definition at line 98 of file Connection.h.

00103 :
#ifdef USE_TLS

struct sockaddr_in Connection::addr ( void   )  [inline, inherited]

Definition at line 98 of file Connection.h.

Referenced by Data::Data(), data_wrapper(), Data::open_active(), Data::open_passive(), and User().

00103 :
#ifdef USE_TLS

bool User::data_vec_full (  ) 

Definition at line 92 of file User.cpp.

References config, data_vec, and Configuration::get_user().

Referenced by Commands::retr(), and Commands::stor().

00093 {
00094   if(data_vec.size() >=
00095       static_cast<size_t>(config->get_user(this->user_name()).sim_data))
00096     return(true);
00097   return(false);
00098 }

Here is the call graph for this function:

bool Connection::disengage_tls (  )  [inherited]

Definition at line 138 of file Connection.cpp.

References B_RESET, Connection::settings(), and TLS_ENABLED.

00139 {
00140   gnutls_bye(this->session, GNUTLS_SHUT_RDWR);
00141   this->settings(TLS_ENABLED, B_RESET);
00142   return true;
00143 }

Here is the call graph for this function:

bool Connection::engage_tls (  )  [inherited]

Definition at line 104 of file Connection.cpp.

References B_SET, Connection::packet_size(), Connection::session, Connection::settings(), tls_db_delete(), tls_db_fetch(), tls_db_store(), TLS_ENABLED, TLS_INITED, and x509_cred.

Referenced by data_wrapper(), and Commands::list().

00105 {
00106   bool ret = false;
00107   gnutls_init(&session, GNUTLS_SERVER);
00108 
00109   gnutls_set_default_priority(this->session);
00110 
00111   gnutls_credentials_set(this->session, GNUTLS_CRD_CERTIFICATE, x509_cred);
00112 
00113   gnutls_certificate_server_set_request(this->session, GNUTLS_CERT_REQUEST);
00114 
00115   gnutls_dh_set_prime_bits(this->session, 1024);
00116 
00117   // these are for the connection cache
00118   gnutls_db_set_retrieve_function(this->session, tls_db_fetch);
00119   gnutls_db_set_remove_function(this->session, tls_db_delete);
00120   gnutls_db_set_store_function(this->session, tls_db_store);
00121   gnutls_db_set_ptr(this->session, NULL);
00122 
00123   // associating the session with the socket.
00124   gnutls_transport_set_ptr(this->session,
00125       reinterpret_cast<gnutls_transport_ptr>(this->socket_id()));
00126   this->settings(TLS_INITED, B_SET);
00127 
00128   if(gnutls_handshake(this->session) >= 0)
00129   {
00130     this->settings(TLS_ENABLED, B_SET);
00131     this->packet_size(gnutls_record_get_max_size(this->session));
00132     ret = true;
00133   }
00134 
00135   return ret;
00136 }

Here is the call graph for this function:

vector< Data * >::iterator User::get_data_it ( pthread_t   ) 

Definition at line 78 of file User.cpp.

References data_vec.

Referenced by Data::~Data().

00079 {
00080   vector<Data*>::iterator data_it;
00081 
00082   BABY_RDLOCK(this->lock);
00083   for(data_it = this->data_vec.begin(); data_it != this->data_vec.end();
00084       data_it++)
00085     if(pthread_equal((*data_it)->thread_id(), thread_id))
00086       break;
00087   BABY_UNLOCK(this->lock);
00088 
00089   return(data_it);
00090 }

void Connection::host_name ( string  var  )  [inline, inherited]

Definition at line 96 of file Connection.h.

00103 :
#ifdef USE_TLS

string Connection::host_name ( void   )  [inline, inherited]

Definition at line 96 of file Connection.h.

Referenced by data_wrapper(), User(), and Connection::verify_cert().

00103 :
#ifdef USE_TLS

bool User::login (  ) 

Definition at line 100 of file User.cpp.

References config, Configuration::get_user(), LOGGED_IN, PWBUF_SIZE, and Connection::timeout().

00101 {
00102   char pwdata[PWBUF_SIZE];
00103   struct passwd pwd, *pwd_ptr;
00104   this->logged_in(LOGGED_IN);
00105   getpwnam_r(this->user_name().c_str(), &pwd, pwdata, sizeof(pwdata),
00106       &pwd_ptr);
00107   uid_t uid = pwd.pw_uid;
00108   gid_t gid = pwd.pw_gid;
00109   if(config->get_user(this->user_name()).only_home)
00110     this->root_dir(pwd.pw_dir);
00111   this->current_dir(pwd.pw_dir);
00112   seteuid(0);
00113   setgid(gid);
00114   seteuid(uid); // dropping permissions...
00115   struct timeval tmp = {config->get_user(this->user_name()).idle, 0};
00116   this->timeout(tmp);
00117   return true;
00118 }

Here is the call graph for this function:

User::MEMBER ( anonymous_id  ,
string   
)

User::MEMBER ( rest_pos  ,
off_t   
)

User::MEMBER ( pamh  ,
pam_handle_t *   
)

User::MEMBER ( failed_logins  ,
int   
)

User::MEMBER ( temp_buf  ,
string   
)

User::MEMBER ( root_dir  ,
string   
)

User::MEMBER ( current_dir  ,
string   
)

User::MEMBER ( data_addr  ,
struct  sockaddr_in 
)

User::MEMBER ( data_id  ,
int   
)

User::MEMBER ( logged_in  ,
int   
)

Connection & Connection::operator<< ( string  message  )  [inherited]

Definition at line 96 of file Connection.cpp.

References B_SET, FAILURE, and Connection::settings().

00097 {
00098   if(this->send(message.c_str(), message.size()) < 0)
00099   this->settings(FAILURE, B_SET);
00100   return *this;
00101 }

Here is the call graph for this function:

Connection & Connection::operator<< ( long long int  num  )  [inherited]

Definition at line 91 of file Connection.cpp.

References Utilities::itos(), and util.

00092 {
00093   return (*this << util.itos(num));
00094 }

Here is the call graph for this function:

User & User::operator>> ( string &  message  ) 

Definition at line 120 of file User.cpp.

References B_SET, config, FAILURE, Configuration::get_user(), Utilities::itos(), Log::log_this(), logging, Connection::settings(), Connection::timeout(), TYPE_AUTH, and util.

00121 {
00122   char tmp_buf[210] = { 0 };
00123   fd_set rfd;
00124   FD_ZERO(&rfd);
00125   FD_SET(this->socket_id(), &rfd);
00126   timeval tv = this->timeout();
00127 
00128   if(!select(this->socket_id() + 1, &rfd, NULL, NULL, &tv))
00129   {
00130     *this << "421 Connection timed out("
00131       << util.itos(config->get_user(this->user_name()).idle)
00132       << " seconds). Disconnected.";
00133     if(this->logged_in())
00134       logging->log_this(3, TYPE_AUTH, "User " + this->user_name() +
00135           ", disconnected due to timeout.");
00136 
00137     this->settings(FAILURE, B_SET);
00138   }
00139   else
00140   {
00141     if(this->receive(tmp_buf, 200) > 0)
00142       message = tmp_buf;
00143     else
00144       this->settings(FAILURE, B_SET);
00145   }
00146   return *this;
00147 }

Here is the call graph for this function:

void Connection::packet_size ( size_t  var  )  [inline, inherited]

Definition at line 99 of file Connection.h.

00103 :
#ifdef USE_TLS

size_t Connection::packet_size ( void   )  [inline, inherited]

Definition at line 99 of file Connection.h.

Referenced by data_wrapper(), and Connection::engage_tls().

00103 :
#ifdef USE_TLS

ssize_t Connection::receive ( char *  ,
size_t   
) [inherited]

Definition at line 74 of file Connection.cpp.

References Connection::_packet_size, TLS_ENABLED, and Connection::transfered().

Referenced by data_wrapper().

00075 {
00076   assert(len <= this->_packet_size && len > 0);
00077   ssize_t ret = -1;
00078 
00079 #ifdef USE_TLS
00080   if(this->settings(TLS_ENABLED))
00081     ret = gnutls_record_recv(this->session, message, len);
00082   else
00083 #endif
00084     ret = read(this->socket_id(), message, len);
00085 
00086   this->transfered(this->transfered() + ret);
00087 
00088   return ret;
00089 }

Here is the call graph for this function:

ssize_t Connection::send ( const char *  ,
size_t   
) [inherited]

Definition at line 47 of file Connection.cpp.

References Connection::_packet_size, Utilities::itos(), Log::log_this(), logging, TLS_ENABLED, Connection::transfered(), TYPE_INFO, and util.

Referenced by data_wrapper().

00048 {
00049   assert(len <= this->_packet_size && len > 0);
00050   ssize_t ret = -1;
00051 
00052   BABY_WRLOCK(this->lock);
00053 #ifdef USE_TLS
00054   if(this->settings(TLS_ENABLED))
00055   {
00056     ret = gnutls_record_send(this->session, message, len);
00057     if(ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
00058       ret = gnutls_record_send(this->session, message, len);
00059   }
00060   else
00061 #endif // USE_TLS
00062     ret = write(this->_socket_id, message, len);
00063 
00064   BABY_UNLOCK(this->lock);
00065   if(ret < 0)
00066     logging->log_this(3, TYPE_INFO, "write to socket " +
00067         util.itos(this->socket_id()) + " failed: %m");
00068   else
00069     this->transfered(this->transfered() + ret);
00070 
00071   return ret;
00072 }

Here is the call graph for this function:

void Connection::settings ( int  bit,
int  way 
) [inline, inherited]

Definition at line 80 of file Connection.h.

References Connection::_settings, B_FLIP, B_RESET, and B_SET.

00081     {
00082       BABY_WRLOCK(this->lock);
00083       if(way == B_SET)
00084         this->_settings.set(bit);
00085       else if(way == B_RESET)
00086         this->_settings.reset(bit);
00087       else if(way == B_FLIP)
00088         this->_settings.flip(bit);
00089       BABY_UNLOCK(this->lock);
00090     }

bool Connection::settings ( int  bit  )  [inline, inherited]

Definition at line 72 of file Connection.h.

References Connection::_settings, and TOTAL_U_BIT.

00073     {
00074       assert(bit < TOTAL_U_BIT);
00075       BABY_RDLOCK(this->lock);
00076       bool b = this->_settings.test(bit);
00077       BABY_UNLOCK(this->lock);
00078       return(b);
00079     }

void Connection::socket_id ( int  var  )  [inline, inherited]

Definition at line 97 of file Connection.h.

00103 :
#ifdef USE_TLS

int Connection::socket_id ( void   )  [inline, inherited]

Definition at line 97 of file Connection.h.

Referenced by Data::open_active(), Data::open_passive(), and User().

00103 :
#ifdef USE_TLS

void Connection::thread_id ( pthread_t  var  )  [inline, inherited]

Definition at line 95 of file Connection.h.

00103 :
#ifdef USE_TLS

pthread_t Connection::thread_id ( void   )  [inline, inherited]

Definition at line 95 of file Connection.h.

Referenced by Data::Data(), data_wrapper(), and User().

00103 :
#ifdef USE_TLS

void Connection::timeout ( struct timeval  var  )  [inline, inherited]

Definition at line 100 of file Connection.h.

00103 :
#ifdef USE_TLS

struct timeval Connection::timeout ( void   )  [inline, inherited]

Definition at line 100 of file Connection.h.

Referenced by Data::Data(), login(), Data::open_active(), Data::open_passive(), operator>>(), and User().

00103 :
#ifdef USE_TLS

void Connection::transfered ( unsigned long long  var  )  [inline, inherited]

Definition at line 102 of file Connection.h.

00103 :
#ifdef USE_TLS

unsigned long long Connection::transfered ( void   )  [inline, inherited]

Definition at line 102 of file Connection.h.

Referenced by Connection::receive(), Connection::send(), and Data::~Data().

00103 :
#ifdef USE_TLS

void Connection::user_name ( string  var  )  [inline, inherited]

Definition at line 101 of file Connection.h.

00103 :
#ifdef USE_TLS

string Connection::user_name ( void   )  [inline, inherited]

Definition at line 101 of file Connection.h.

Referenced by data_wrapper(), Connection::verify_cert(), and Data::~Data().

00103 :
#ifdef USE_TLS

bool Connection::verify_cert (  )  [inherited]

Definition at line 145 of file Connection.cpp.

References config, Configuration::general, Connection::host_name(), Utilities::is_set(), Log::log_this(), logging, TYPE_AUTH, TYPE_DEBUG, Connection::user_name(), util, and general_stru::verify_client.

00146 {
00147   bool ret = false;
00148   if (gnutls_certificate_type_get(this->session) == GNUTLS_CRT_X509)
00149   {
00150     int verified = gnutls_certificate_verify_peers(this->session);
00151     if(util.is_set(verified, GNUTLS_CERT_REVOKED))
00152       logging->log_this(2, TYPE_AUTH, this->user_name() +
00153           + " tried to login with a revoked certificate.");
00154     else if(!util.is_set(verified, GNUTLS_CERT_INVALID) &&
00155         !util.is_set(verified, GNUTLS_CERT_SIGNER_NOT_FOUND))
00156     {
00157       unsigned int cert_list_size = 0;
00158       // I really hope gnutls has their locking code in shape. get_peers just
00159       // gives us some memory.. *shudder*                     
00160       const gnutls_datum *cert_list = gnutls_certificate_get_peers(
00161           this->session, &cert_list_size);
00162       if(cert_list_size > 0)
00163       {
00164         gnutls_x509_crt peer_cert;
00165         gnutls_x509_crt_init(&peer_cert);
00166         gnutls_x509_crt_import(peer_cert, &cert_list[0], GNUTLS_X509_FMT_DER);
00167         char dn_buf[200] = {0}, ca_buf[200] = {0};
00168         size_t buf_size = 199, ca_size = 199;
00169         gnutls_x509_crt_get_dn(peer_cert, dn_buf, &buf_size);
00170         gnutls_x509_crt_get_issuer_dn(peer_cert, ca_buf, &ca_size);
00171         if(buf_size > 0 && ca_size > 0)
00172         {
00173           // here we call an external program to ask if this user may login
00174           // with this cert.
00175           //  format is "<user> <host/ip> <ca-dn> <cert-dn>"
00176           string call = config->general.verify_client + " " +
00177             this->user_name() + " " + this->host_name() +
00178             " \"" + ca_buf + "\" \"" + dn_buf + "\"";
00179           logging->log_this(5, TYPE_DEBUG, "running:" + call);
00180           int approved = system(call.c_str());
00181           if(WEXITSTATUS(approved) == 0)
00182             ret = true;
00183         }
00184         gnutls_x509_crt_deinit(peer_cert);
00185       }
00186     }
00187   }
00188   return ret;
00189 }

Here is the call graph for this function:


Member Data Documentation

bitset<TOTAL_U_BIT> Connection::_settings [protected, inherited]

Definition at line 94 of file Connection.h.

Referenced by Connection::Connection(), Data::Data(), and Connection::settings().

vector<Data*> User::data_vec

Definition at line 34 of file User.h.

Referenced by data_vec_full(), get_data_it(), Commands::retr(), Commands::stor(), Data::~Data(), and ~User().

pthread_rwlock_t Connection::lock [inherited]

Definition at line 58 of file Connection.h.

Referenced by Commands::retr(), Commands::stor(), and Data::~Data().


The documentation for this class was generated from the following files: