Documentation

Generated on Thu Aug 31 00:02:31 2006

 

babyftpd.h File Reference

#include "generic.h"
#include "Utilities.h"
#include "Configuration.h"
#include "Log.h"
#include "Connection.h"
#include "User.h"
#include "Data.h"
#include "Handler.h"
#include "Commands.h"
#include "tls.cpp"

Include dependency graph for babyftpd.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.


Classes

struct  cache

Functions

static void * user_wrapper (void *) __attribute__((noreturn))
static void * log_wrapper (void *) __attribute__((noreturn))
bool listener (void)
void sig_handler (int)
void exit_baby (int, enum exits)
void lifebeat (void)
int tls_db_store (void *, gnutls_datum, gnutls_datum)
gnutls_datum tls_db_fetch (void *, gnutls_datum)
int tls_db_delete (void *, gnutls_datum)

Variables

pthread_key_t my_user = 0
pthread_key_t my_data = 0
pthread_rwlock_t user_list_lock
sem_t cleanup_list_lock
pthread_t main_thread
pthread_t logging_thread
vector< User * > user_list
vector< pthread_t > cleanup_list
const int LISTEN_LIMIT = 5
gnutls_certificate_credentials x509_cred
static gnutls_dh_params dh_params
time_t dh_time
vector< cache * > cache_db
pthread_rwlock_t cache_lock

Function Documentation

void exit_baby ( int  ,
enum  exits 
)

Definition at line 298 of file babyftpd.cpp.

References cache_db, cache_lock, cleanup_list, cleanup_list_lock, comm, config, dh_params, EXIT_FULL, Configuration::general, handler, Utilities::itos(), Log::log_this(), logging, logging_thread, my_data, my_user, Commands::pam_lock, general_stru::pid_file, TYPE_DEBUG, user_list_lock, util, and x509_cred.

Referenced by listener(), Configuration::parse_command_line(), and sig_handler().

00299 {
00300   if(how == EXIT_FULL)
00301   {
00302     if(!config->general.pid_file.empty())
00303       unlink(config->general.pid_file.c_str());
00304 
00305     while(!cleanup_list.empty())
00306     {
00307       logging->log_this(4, TYPE_DEBUG, "joining thread #" +
00308           util.itos(cleanup_list.back()));
00309       pthread_join(cleanup_list.back(), NULL);
00310       cleanup_list.pop_back();
00311     }
00312 
00313     delete handler;
00314     pthread_key_delete(my_user);
00315     pthread_key_delete(my_data);
00316 
00317 #ifdef USE_TLS
00318     // emptying and freeing session cache.
00319     for(vector<cache*>::iterator cache_it = cache_db.begin();
00320         cache_it != cache_db.end(); cache_it++)
00321     {
00322       gnutls_free((*cache_it)->key.data);
00323       gnutls_free((*cache_it)->data.data);
00324       delete(*cache_it);
00325       cache_db.erase(cache_it);
00326     }
00327 
00328     gnutls_dh_params_deinit(dh_params);
00329     gnutls_certificate_free_credentials(x509_cred);
00330     gnutls_global_deinit();
00331     pthread_rwlock_destroy(&cache_lock);
00332 #endif // USE_TLS 
00333     sem_destroy(&comm.pam_lock);
00334     sem_destroy(&cleanup_list_lock);
00335     pthread_rwlock_destroy(&user_list_lock);
00336     pthread_cancel(logging_thread);
00337     pthread_join(logging_thread, NULL);
00338   }
00339   delete logging;
00340 
00341   delete config;
00342   exit(num);
00343 }

Here is the call graph for this function:

void lifebeat ( void   ) 

Definition at line 206 of file babyftpd.cpp.

References cleanup_list, cleanup_list_lock, config, dh_params, general_stru::dh_regenerate, dh_time, Configuration::general, Utilities::itos(), Log::log_this(), logging, TYPE_DEBUG, util, and x509_cred.

Referenced by listener().

00207 {
00208   logging->log_this(4, TYPE_DEBUG, "lifebeat reached.");
00209 
00210   sem_wait(&cleanup_list_lock);
00211   while(!cleanup_list.empty())
00212   {
00213     logging->log_this(4, TYPE_DEBUG, "joining thread #" +
00214         util.itos(cleanup_list.back()));
00215     pthread_join(cleanup_list.back(), NULL);
00216     cleanup_list.pop_back();
00217   }
00218   sem_post(&cleanup_list_lock);
00219 
00220 #ifdef USE_TLS
00221   if((time(NULL) - dh_time) > config->general.dh_regenerate)
00222   {
00223     gnutls_dh_params temp_dh_params;
00224     gnutls_dh_params_init(&temp_dh_params);
00225     gnutls_dh_params_generate2(temp_dh_params, 1024);
00226     gnutls_dh_params_cpy(dh_params, temp_dh_params);
00227     gnutls_dh_params_deinit(temp_dh_params);
00228     gnutls_certificate_set_dh_params(x509_cred, dh_params);
00229     dh_time = time(NULL);
00230   }
00231 #endif // USE_TLS
00232 }

Here is the call graph for this function:

bool listener ( void   ) 

Definition at line 149 of file babyftpd.cpp.

References config, exit_baby(), EXIT_FULL, Configuration::general, general_stru::group, Utilities::itos(), lifebeat(), general_stru::lifebeat_tick, LISTEN_LIMIT, Log::log_this(), logging, general_stru::port, TYPE_INFO, general_stru::user, user_wrapper(), and util.

Referenced by main().

00150 {
00151   struct sockaddr_in address;
00152   struct timeval tv = {config->general.lifebeat_tick,0};
00153 
00154   int first_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
00155   address.sin_family = AF_INET;
00156   address.sin_addr.s_addr = INADDR_ANY;
00157   address.sin_port = htons(config->general.port);
00158   if(bind(first_socket, reinterpret_cast<struct sockaddr*>(&address),
00159         sizeof(address)) < 0)
00160   {
00161     logging->log_this(2, TYPE_INFO, "Port " +
00162         util.itos(config->general.port) + " already in use.");
00163     exit_baby(1, EXIT_FULL);
00164   }
00165   seteuid(config->general.user);
00166   setgid(config->general.group);
00167   listen(first_socket, LISTEN_LIMIT);
00168   while(true)
00169   {
00170     pthread_t thread_tmp;
00171     socklen_t socketlen = sizeof(struct sockaddr_in);
00172     fd_set sock_set;
00173     time_t before = time(NULL) - (config->general.lifebeat_tick - tv.tv_sec);
00174 
00175     FD_ZERO(&sock_set);
00176     FD_SET(first_socket, &sock_set);
00177     if(!select(first_socket + 1, &sock_set, NULL, NULL, &tv))
00178     {
00179       lifebeat();
00180       tv.tv_sec = config->general.lifebeat_tick; // important to reset lifebeat
00181       continue;
00182     }
00183 
00184     int *final_socket = new int;
00185     *final_socket = accept(first_socket,
00186         reinterpret_cast<struct sockaddr*>(&address), &socketlen);
00187     if(*final_socket != -1)
00188       pthread_create(&thread_tmp, NULL, user_wrapper, (final_socket));
00189     else
00190     {
00191       logging->log_this(3, TYPE_INFO, "Failed to accept new caller.");
00192       // if the socket is accepted and the thread created the pointer will
00193       // get deleted there after it is stored.
00194       delete final_socket;
00195     }
00196 
00197     tv.tv_sec = config->general.lifebeat_tick - (time(NULL) - before);
00198     if(tv.tv_sec < 0 || tv.tv_sec > config->general.lifebeat_tick)
00199       tv.tv_sec = 0;
00200   }
00201   close(first_socket);
00202 
00203   return(true);
00204 }

Here is the call graph for this function:

static void* log_wrapper ( void *   )  [static]

void sig_handler ( int   ) 

Definition at line 258 of file babyftpd.cpp.

References config, exit_baby(), EXIT_FULL, Utilities::itos(), Log::log_this(), logging, logging_thread, main_thread, Configuration::parse_config_file(), TYPE_DEBUG, TYPE_INFO, user_list, and util.

Referenced by main().

00259 {
00260   switch(signal)
00261   {
00262     case SIGTERM:
00263     case SIGINT:
00264       logging->log_this(3, TYPE_INFO, "SIGTERM received.");
00265 
00266       logging->log_this(4, TYPE_DEBUG, "main thread. users: " +
00267           util.itos(user_list.size()));
00268 
00269       for(vector<User*>::iterator user_it = user_list.begin();
00270           user_it != user_list.end(); user_it++)
00271         pthread_cancel((*user_it)->thread_id());
00272 
00273       struct timeval times;
00274       times.tv_sec = 1;
00275       times.tv_usec = 0;
00276       select(0, NULL, NULL, NULL, &times);
00277 
00278       logging->log_this(3, TYPE_INFO, "main thread exiting.");
00279       exit_baby(1, EXIT_FULL);
00280       break;
00281 
00282     case SIGHUP:
00283       logging->log_this(3, TYPE_INFO,
00284           "SIGHUP received, reloading configuration");
00285       config->parse_config_file();
00286       break;
00287 
00288     case SIGPIPE:
00289       logging->log_this(3, TYPE_INFO,
00290           "SIGPIPE received in thread: " + util.itos(pthread_self()));
00291       if(!pthread_equal(pthread_self(), main_thread) ||
00292           pthread_equal(pthread_self(), logging_thread))
00293         pthread_exit(NULL); // if this is a user or data thread, bail.
00294       break;
00295   }
00296 }

Here is the call graph for this function:

int tls_db_delete ( void *  ,
gnutls_datum   
)

Definition at line 385 of file babyftpd.cpp.

00386 {
00387   int ret = -1;
00388   pthread_rwlock_rdlock(&cache_lock);
00389   for(vector<cache*>::iterator cache_it = cache_db.begin();
00390       cache_it != cache_db.end(); cache_it++)
00391     if(memcmp(key.data, (*cache_it)->key.data, (*cache_it)->key.size) == 0)
00392     {
00393       pthread_rwlock_unlock(&cache_lock);
00394       pthread_rwlock_wrlock(&cache_lock);
00395       gnutls_free((*cache_it)->key.data);
00396       gnutls_free((*cache_it)->data.data);
00397       delete(*cache_it);
00398       cache_db.erase(cache_it);
00399       ret = 0;
00400       break;
00401     }
00402   pthread_rwlock_unlock(&cache_lock);
00403 
00404   return(ret);
00405 }

gnutls_datum tls_db_fetch ( void *  ,
gnutls_datum   
)

Definition at line 366 of file babyftpd.cpp.

00367 {
00368   gnutls_datum data = { NULL, 0 };
00369 
00370   pthread_rwlock_rdlock(&cache_lock);
00371   for(vector<cache*>::iterator cache_it = cache_db.begin();
00372       cache_it != cache_db.end(); cache_it++)
00373     if(memcmp(key.data, (*cache_it)->key.data, (*cache_it)->key.size) == 0)
00374     {
00375       data.size = (*cache_it)->data.size;
00376       data.data = static_cast<unsigned char*>(gnutls_malloc(data.size));
00377       memcpy(data.data, (*cache_it)->data.data, data.size);
00378       break;
00379     }
00380   pthread_rwlock_unlock(&cache_lock);
00381 
00382   return(data);
00383 }

int tls_db_store ( void *  ,
gnutls_datum  ,
gnutls_datum   
)

Definition at line 347 of file babyftpd.cpp.

00348 {
00349   struct cache *temp_cache = new cache;
00350 
00351   temp_cache->key.data = static_cast<unsigned char*>(gnutls_malloc(key.size));
00352   temp_cache->key.size = key.size;
00353   memcpy(temp_cache->key.data, key.data, key.size);
00354 
00355   temp_cache->data.data =
00356     static_cast<unsigned char*>(gnutls_malloc(data.size));
00357   temp_cache->data.size = data.size;
00358   memcpy(temp_cache->data.data, data.data, data.size);
00359 
00360   pthread_rwlock_wrlock(&cache_lock);
00361   cache_db.push_back(temp_cache);
00362   pthread_rwlock_unlock(&cache_lock);
00363   return(0);
00364 }

static void* user_wrapper ( void *   )  [static]


Variable Documentation

vector<cache*> cache_db

Definition at line 63 of file babyftpd.h.

Referenced by exit_baby(), tls_db_delete(), tls_db_fetch(), and tls_db_store().

pthread_rwlock_t cache_lock

Definition at line 64 of file babyftpd.h.

Referenced by exit_baby(), main(), tls_db_delete(), tls_db_fetch(), and tls_db_store().

vector<pthread_t> cleanup_list

Definition at line 45 of file babyftpd.h.

Referenced by exit_baby(), lifebeat(), and Connection::~Connection().

Definition at line 41 of file babyftpd.h.

Referenced by exit_baby(), lifebeat(), main(), and Connection::~Connection().

gnutls_dh_params dh_params [static]

Definition at line 51 of file babyftpd.h.

Referenced by exit_baby(), lifebeat(), and main().

time_t dh_time

Definition at line 52 of file babyftpd.h.

Referenced by lifebeat(), and main().

const int LISTEN_LIMIT = 5

Definition at line 47 of file babyftpd.h.

Referenced by listener().

pthread_t logging_thread

Definition at line 43 of file babyftpd.h.

Referenced by exit_baby(), main(), and sig_handler().

pthread_t main_thread

Definition at line 42 of file babyftpd.h.

Referenced by main(), and sig_handler().

pthread_key_t my_data = 0

Definition at line 38 of file babyftpd.h.

Referenced by data_wrapper(), exit_baby(), and main().

pthread_key_t my_user = 0

Definition at line 37 of file babyftpd.h.

Referenced by exit_baby(), main(), and user_wrapper().

vector<User*> user_list

pthread_rwlock_t user_list_lock

gnutls_certificate_credentials x509_cred

Definition at line 50 of file babyftpd.h.

Referenced by Connection::engage_tls(), exit_baby(), lifebeat(), and main().