Documentation

Generated on Thu Aug 31 00:02:38 2006

 

Data Class Reference

#include <Data.h>

Inheritance diagram for Data:

Inheritance graph
[legend]
Collaboration diagram for Data:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 Data (User *user, int file_id=-1, string file_name="", int trans_type=0)
 ~Data ()
 MEMBER (trans_type, int)
 MEMBER (file_id, int)
 MEMBER (file_name, 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

Useruser
pthread_rwlock_t lock

Protected Attributes

bitset< TOTAL_U_BIT_settings

Private Member Functions

void open_active ()
void open_passive ()

Detailed Description

Definition at line 23 of file Data.h.


Constructor & Destructor Documentation

Data::Data ( User user,
int  file_id = -1,
string  file_name = "",
int  trans_type = 0 
)

Definition at line 16 of file Data.cpp.

References Connection::_settings, Connection::addr(), B_RESET, B_SET, DATA_OPEN, open_active(), PASSIVE, RETR_TRANS, Connection::settings(), Connection::thread_id(), Connection::timeout(), TLS_ENABLED, TLS_INITED, USE_TLS, and user.

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

00017   : Connection()
00018 {
00019   this->thread_id(0); // data_wrapper sets this to it's own.
00020   this->_file_id = file_id;
00021   this->_file_name = file_name;
00022   this->user = user;
00023   this->_settings = user->settings();
00024   this->addr(user->data_addr());
00025   struct timeval tv = {1, 0};
00026   this->timeout(tv);
00027   if(trans_type == 1)
00028     this->settings(RETR_TRANS, B_SET);
00029 
00030   this->settings(DATA_OPEN, B_SET);
00031 #ifdef USE_TLS
00032   this->settings(TLS_INITED, B_RESET);
00033   this->settings(TLS_ENABLED, B_RESET);
00034 #endif // USE_TLS
00035 
00036   if(this->settings(PASSIVE))
00037     this->open_passive();
00038   else // ACTIVE
00039     this->open_active();
00040 
00041   // if the data connection comes from another host than the
00042   // ctrl connection we drop it.. unless the user is tls protected.
00043   if(this->addr().sin_addr.s_addr != user->addr().sin_addr.s_addr)
00044   {
00045 #ifdef USE_TLS
00046     if(!user->settings(TLS_ENABLED))
00047     {
00048 #endif // USE_TLS
00049       close(this->socket_id());
00050       this->settings(DATA_OPEN, B_RESET);
00051     }
00052 #ifdef USE_TLS
00053   }
00054 #endif //USE_TLS
00055 }

Here is the call graph for this function:

Data::~Data (  ) 

Definition at line 138 of file Data.cpp.

References User::data_vec, User::get_data_it(), Utilities::itos(), Connection::lock, Log::log_this(), logging, Connection::transfered(), TYPE_INFO, user, Connection::user_name(), and util.

00139 {
00140   if(this->_file_id != -1)
00141     close(this->_file_id);
00142 
00143   this->user->transfered(
00144       this->user->transfered() + this->transfered());
00145 
00146   if(this->thread_id())
00147   {
00148     BABY_WRLOCK(user->lock);
00149     user->data_vec.erase(user->get_data_it(this->thread_id()));
00150     BABY_UNLOCK(user->lock);
00151     logging->log_this(4, TYPE_INFO, "data thread " +
00152         util.itos(this->thread_id()) +
00153         " exiting. Remaining data connections for " + user->user_name() +
00154         " is: " + util.itos(user->data_vec.size()));
00155   }
00156 }

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_wrapper(), open_active(), open_passive(), and User::User().

00103 :
#ifdef USE_TLS

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:

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::User(), and Connection::verify_cert().

00103 :
#ifdef USE_TLS

Data::MEMBER ( file_name  ,
string   
)

Data::MEMBER ( file_id  ,
int   
)

Data::MEMBER ( trans_type  ,
int   
)

void Data::open_active (  )  [private]

Definition at line 80 of file Data.cpp.

References Connection::addr(), B_RESET, config, DATA_OPEN, general_stru::data_port, Configuration::general, Utilities::itos(), Log::log_this(), logging, Connection::settings(), Connection::socket_id(), Connection::timeout(), TYPE_INFO, and util.

Referenced by Data().

00081 {
00082   this->socket_id(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
00083 
00084   int on = 1;
00085   setsockopt(this->socket_id(), SOL_SOCKET, SO_REUSEADDR,
00086       (static_cast<void*>(&on)), sizeof(on));
00087   struct sockaddr_in my_addr;
00088   my_addr.sin_port = htons(config->general.data_port);
00089   my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
00090 
00091   uid_t old_uid = 0;
00092   // if dataport is below 1024 we need root.
00093   if(config->general.data_port <= 1024)
00094   {
00095     old_uid = geteuid();
00096     seteuid(0);
00097   }
00098   int ret = bind(this->socket_id(), reinterpret_cast<struct sockaddr*>
00099       (&my_addr), sizeof(my_addr));
00100   if(config->general.data_port <= 1024)
00101     seteuid(old_uid);
00102 
00103   if(ret != 0)
00104     logging->log_this(3, TYPE_INFO,
00105         "Failed to bind to data port " + util.itos(config->general.data_port)
00106         + ", falling back to arbitrary port.");
00107 
00108   struct sockaddr_in tmp_addr = this->addr();
00109 
00110   // go into nonblocking
00111   long sock_arg = fcntl(this->socket_id(), F_GETFL, NULL);
00112   sock_arg |= O_NONBLOCK;
00113   fcntl(this->socket_id(), F_SETFL, sock_arg);
00114 
00115   int sock_err = connect(this->socket_id(), reinterpret_cast<struct sockaddr*>
00116         (&tmp_addr), sizeof(tmp_addr));
00117   this->addr(tmp_addr);
00118 
00119   if(sock_err < 0)
00120     if(errno == EINPROGRESS)
00121     {
00122       struct timeval tv = this->timeout();
00123       fd_set con_set;
00124       FD_ZERO(&con_set);
00125       FD_SET(this->socket_id(), &con_set);
00126       if(select(this->socket_id() + 1, NULL, &con_set, NULL, &tv) < 0)
00127         this->settings(DATA_OPEN, B_RESET);
00128     }
00129     else
00130       this->settings(DATA_OPEN, B_RESET);
00131 
00132   // leave non blocking
00133   long sock_arg2 = fcntl(this->socket_id(), F_GETFL, NULL);
00134   sock_arg2 &= (~O_NONBLOCK);
00135   fcntl(this->socket_id(), F_SETFL, sock_arg2);
00136 }

Here is the call graph for this function:

void Data::open_passive (  )  [private]

Definition at line 57 of file Data.cpp.

References Connection::addr(), B_RESET, DATA_OPEN, Connection::settings(), Connection::socket_id(), Connection::timeout(), and user.

00058 {
00059   socklen_t len = sizeof(this->addr());
00060   struct sockaddr_in temp_addr = this->addr();
00061 
00062   fd_set acc_set;
00063   FD_ZERO(&acc_set);
00064   FD_SET(user->data_id(), &acc_set);
00065   struct timeval tv = this->timeout();
00066 
00067   if(select(user->data_id() + 1, &acc_set, NULL, NULL, &tv) > 0)
00068   {
00069     int ret = accept(user->data_id(),
00070         reinterpret_cast<struct sockaddr*>(&temp_addr), &len);
00071     this->socket_id(ret);
00072     this->addr(temp_addr);
00073   }
00074   else
00075     this->settings(DATA_OPEN, B_RESET);
00076 
00077   close(user->data_id());
00078 }

Here is the call graph for this function:

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:

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 open_active(), open_passive(), and User::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_wrapper(), and User::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(), User::login(), open_active(), open_passive(), User::operator>>(), and User::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().

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().

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(), and Connection::settings().

pthread_rwlock_t Connection::lock [inherited]

Definition at line 58 of file Connection.h.

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


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