DocumentationGenerated on Thu Aug 31 00:02:31 2006 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
babyftpd.cpp File Reference#include "babyftpd.h" Include dependency graph for babyftpd.cpp: ![]() Go to the source code of this file.
Define Documentation
Definition at line 14 of file babyftpd.cpp.
Definition at line 13 of file babyftpd.cpp.
Definition at line 11 of file babyftpd.cpp.
Definition at line 12 of file babyftpd.cpp.
Function Documentation
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: ![]()
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: ![]()
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: ![]()
Definition at line 249 of file babyftpd.cpp. References Log::log_main(), and logging. Referenced by main(). 00250 { 00251 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 00252 logging->log_main(); 00253 00254 pthread_exit(NULL); 00255 }
Here is the call graph for this function: ![]()
Definition at line 17 of file babyftpd.cpp. References cache_lock, cleanup_list_lock, comm, Configuration::conf_file, config, dh_params, dh_time, gcry_threads_pthread, Configuration::general, handler, kill_data(), kill_user(), listener(), Log::log_this(), log_wrapper(), logging, logging_thread, main_thread, my_data, my_user, general_stru::no_daemon, Commands::pam_lock, Configuration::parse_command_line(), Configuration::parse_config_file(), general_stru::pid_file, sig_handler(), general_stru::tls_ca, general_stru::tls_cert, general_stru::tls_crl, general_stru::tls_key, TYPE_INFO, user_list_lock, general_stru::welcome_msg, and x509_cred. 00018 { 00019 pid_t pid; 00020 00021 logging = new class Log; 00022 config = new class Configuration; 00023 config->parse_command_line(argc, argv); 00024 // we send the start message for logging here so that starts our log. 00025 logging->log_this(3, TYPE_INFO, config->general.welcome_msg + " started."); 00026 // the config file variable exists in the Configuration class :p 00027 if(config->parse_config_file() == false) 00028 cout << "Failed to open the config file (" << config->conf_file << 00029 "), check if it exists + permissions." << endl; 00030 // if the conffile changes variables from commandline we reset them. 00031 config->parse_command_line(argc, argv); 00032 00033 if(config->general.no_daemon == false) 00034 pid = fork(); 00035 else 00036 pid = 0; 00037 00038 switch(pid) 00039 { 00040 case -1: 00041 // error 00042 exit(1); 00043 break; 00044 00045 case 0: 00046 // child 00047 int new_pid; 00048 setsid(); 00049 if(config->general.no_daemon == false) 00050 new_pid = fork(); 00051 else 00052 new_pid = 0; 00053 00054 switch(new_pid) 00055 { 00056 case -1: 00057 exit(0); 00058 break; 00059 00060 case 0: 00061 break; 00062 00063 default: 00064 _exit(0); 00065 } 00066 00067 chdir("/"); 00068 umask(0); 00069 00070 close(STDIN_FILENO); 00071 close(STDOUT_FILENO); 00072 close(STDERR_FILENO); 00073 00074 if(!config->general.pid_file.empty()) 00075 { 00076 ofstream pidstream; 00077 pidstream.open(config->general.pid_file.c_str(), ofstream::out); 00078 if(!pidstream) 00079 logging->log_this(2, TYPE_INFO, "Failed to open pid_file " + 00080 config->general.pid_file + " for writing. continuing."); 00081 else 00082 { 00083 pidstream << getpid(); 00084 pidstream.close(); 00085 } 00086 } 00087 00088 // we can't spawn the logging thread until after we are daemonized 00089 pthread_create(&logging_thread, NULL, log_wrapper, NULL); 00090 00091 pthread_key_create(&my_user, kill_user); 00092 pthread_key_create(&my_data, kill_data); 00093 00094 pthread_rwlock_init(&user_list_lock, NULL); 00095 sem_init(&cleanup_list_lock, 0, 1); 00096 sem_init(&comm.pam_lock, 0, 1); 00097 00098 signal(SIGTERM, sig_handler); 00099 signal(SIGINT, sig_handler); 00100 signal(SIGHUP, sig_handler); 00101 signal(SIGPIPE, sig_handler); 00102 00103 main_thread = pthread_self(); 00104 00105 #ifdef USE_TLS 00106 #ifndef OLD_GCRYPT 00107 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); 00108 #endif // OLD_GCRYPT 00109 int ret; 00110 pthread_rwlock_init(&cache_lock, NULL); 00111 gnutls_global_init(); 00112 00113 gnutls_certificate_allocate_credentials(&x509_cred); 00114 ret = gnutls_certificate_set_x509_trust_file(x509_cred, 00115 config->general.tls_ca.c_str(), GNUTLS_X509_FMT_PEM); 00116 if(ret < 0) 00117 logging->log_this(2, TYPE_INFO, gnutls_strerror(ret)); 00118 00119 ret = gnutls_certificate_set_x509_crl_file(x509_cred, 00120 config->general.tls_crl.c_str(), GNUTLS_X509_FMT_PEM); 00121 if(ret < 0) 00122 logging->log_this(2, TYPE_INFO, gnutls_strerror(ret)); 00123 00124 ret = gnutls_certificate_set_x509_key_file(x509_cred, 00125 config->general.tls_cert.c_str(), config->general.tls_key.c_str(), 00126 GNUTLS_X509_FMT_PEM); 00127 if(ret < 0) 00128 logging->log_this(2, TYPE_INFO, gnutls_strerror(ret)); 00129 00130 gnutls_dh_params_init(&dh_params); 00131 00132 gnutls_dh_params_generate2(dh_params, 1024); 00133 00134 gnutls_certificate_set_dh_params(x509_cred, dh_params); 00135 dh_time = time(NULL); 00136 00137 #endif // USE_TLS 00138 handler = new Handler; 00139 listener(); 00140 break; 00141 00142 default: 00143 // parent 00144 _exit(0); 00145 break; 00146 } 00147 }
Here is the call graph for this function: ![]()
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, ×); 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: ![]()
Definition at line 385 of file babyftpd.cpp. References cache_db, and cache_lock. Referenced by Connection::engage_tls(). 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 }
Definition at line 366 of file babyftpd.cpp. References cache_db, cache_lock, and cache::data. Referenced by Connection::engage_tls(). 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 }
Definition at line 347 of file babyftpd.cpp. References cache_db, cache_lock, cache::data, and cache::key. Referenced by Connection::engage_tls(). 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 }
Definition at line 234 of file babyftpd.cpp. References handler, Handler::init(), Handler::initializer(), Log::log_this(), logging, my_user, and TYPE_DEBUG. Referenced by listener(). 00235 { 00236 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); 00237 00238 class User *user = handler->initializer((*(static_cast<int*>(socket_id)))); 00239 delete (static_cast<int*>(socket_id)); 00240 pthread_setspecific(my_user, static_cast<void*>(user)); 00241 00242 handler->init(user); 00243 00244 logging->log_this(3, TYPE_DEBUG, "closed connection from: " + 00245 user->host_name()); 00246 pthread_exit(NULL); // the thread exits..., and takes the user with it.. 00247 }
Here is the call graph for this function: ![]()
|
- Copyright © 2005, BabyFTPd
- Powered by: