Documentation

Generated on Thu Aug 31 00:02:32 2006

 

Commands.h File Reference

#include "generic.h"
#include "Utilities.h"
#include "Configuration.h"
#include "Log.h"
#include "Connection.h"
#include "Data.h"
#include "User.h"
#include "Handler.h"
#include "StringTokenizer.h"

Include dependency graph for Commands.h:

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

Go to the source code of this file.


Classes

class  Commands
struct  pam_data

Defines

#define BABY_COM(com)   bool com(User *user, string &argument, unsigned int flag)

Functions

void * data_wrapper (void *) __attribute__((noreturn))
int tls_db_store (void *, gnutls_datum, gnutls_datum)
gnutls_datum tls_db_fetch (void *, gnutls_datum)
int tls_db_delete (void *, gnutls_datum)
int pam_conversate (int, const struct pam_message **, struct pam_response **, void *)

Variables

Commands comm
const int COM_LONG = (1 << 0)
const int COM_SHORT = (1 << 1)
const int COM_MLSD = (1 << 2)
const int COM_FROM = (1 << 0)
const int COM_TO = (1 << 1)
const int COM_STOR = (1 << 0)
const int COM_APPE = (1 << 1)
const int COM_CDUP = (1 << 0)
const int COM_CWD = (1 << 1)
const int COM_NOOP = (1 << 0)
const int COM_PWD = (1 << 1)
const int COM_SYST = (1 << 2)
const int COM_FEAT = (1 << 3)
const int COM_TYPE = (1 << 4)
const int COM_MODE = (1 << 5)
const int COM_STRU = (1 << 6)
const int COM_PBSZ = (1 << 7)
const int COM_PROT = (1 << 8)
const int COM_CCC = (1 << 9)
const int COM_CONF = (1 << 10)
const int COM_MIC = (1 << 11)
const int COM_ENC = (1 << 12)
const int COM_SIZE = (1 << 0)
const int COM_MDTM = (1 << 1)
const int COM_MLST = (1 << 2)
const int COM_PORT = (1 << 0)
const int COM_EPRT = (1 << 1)
const int COM_PASV = (1 << 2)
const int COM_EPSV = (1 << 3)
const int BEFORE_USER = (1 << 31)
const int PROT_IPV4 = 1
const int PROT_IPV6 = 2
vector< User * > user_list
gnutls_certificate_credentials x509_cred

Define Documentation

#define BABY_COM ( com   )     bool com(User *user, string &argument, unsigned int flag)

Definition at line 24 of file Commands.h.


Function Documentation

void* data_wrapper ( void *   ) 

Definition at line 17 of file Commands.cpp.

References Connection::addr(), ANONYMOUS, BINARY, config, Connection::engage_tls(), Connection::host_name(), Utilities::itos(), Log::log_this(), Configuration::logger, logging, my_data, Connection::packet_size(), PWBUF_SIZE, Connection::receive(), RETR_TRANS, Connection::send(), Connection::settings(), Connection::thread_id(), Utilities::time_string(), TLS_PROT_D, TYPE_DEBUG, TYPE_XFER, Data::user, Connection::user_name(), util, and log_stru::xferlog.

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

00018 {
00019   class Data *data = static_cast<class Data*>(void_data);
00020   string message;
00021   time_t start_time = time(NULL);
00022   size_t trans_size = 0; // will hold the total number of sent bytes
00023 
00024   data->thread_id(pthread_self());
00025 
00026   pthread_setspecific(my_data, void_data);
00027   pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
00028 
00029   data->host_name(inet_ntoa(data->addr().sin_addr));
00030 
00031   // I don't like it, but we need to drop permissions again...
00032   //   not true for new threads, need to look deeper into this.
00033   struct passwd pwd, *pwd_ptr;
00034   char pwdata[PWBUF_SIZE];
00035   getpwnam_r(data->user->user_name().c_str(), &pwd, pwdata, sizeof(pwdata),
00036       &pwd_ptr);
00037   uid_t uid = pwd.pw_uid;
00038   gid_t gid = pwd.pw_gid;
00039   setuid(uid);
00040   setgid(gid);
00041 
00042 #ifdef USE_TLS // handshakes etc
00043   if(data->settings(TLS_PROT_D))
00044     if(!data->engage_tls()) // failed handshake
00045       message =
00046         "451 Failed to negotiate TLS as was asked. Closing data connection.";
00047 #endif // USE_TLS
00048   while(message.empty())
00049   {
00050     char *read_buf = new char[data->packet_size()];
00051     size_t size = 0, size2 = 0;
00052     if(data->settings(RETR_TRANS))
00053     {
00054       size2 = read(data->file_id(), read_buf, data->packet_size());
00055       if(size2 > 0)
00056         size = data->send(read_buf, size2);
00057     }
00058     else // STOR_STRANS
00059       size = data->receive(read_buf, data->packet_size() - 1);
00060 
00061     trans_size += size;
00062     if(!data->settings(RETR_TRANS))
00063     {
00064       if(size != 0 && (write(data->file_id(), read_buf, size) == -1))
00065       {
00066         logging->log_this(3, TYPE_DEBUG, "Write failed to file: " +
00067             data->file_name() + " from host: " + data->host_name() +
00068             " with error %m");
00069         message = "451 File transfer failed.";
00070       }
00071       else if(size == 0)
00072       {
00073         if(close(data->file_id()) != 0)
00074           message = "550 Failed saving file.";
00075         else
00076           message = "226 Transfer complete.";
00077       }
00078     }
00079     else // RETR_TRANS
00080     {
00081       if(size != size2)
00082         message = "550 Transfer failed.";
00083       else if(size2 != data->packet_size())
00084         message = "226 Transfer complete.";
00085     }
00086     delete[] read_buf;
00087   }
00088 
00089   *data->user << message << "\r\n";
00090   if(config->logger.xferlog)
00091   {
00092     string time_string;
00093     util.time_string(time_string, "%a %b %d %H:%M:%S %Y ");
00094 
00095     // as ' ' separates fields in the xferlog we convert them to '_' here
00096     string temp_name = data->file_name();
00097     for(string::iterator name_it = temp_name.begin();
00098         name_it != temp_name.end(); name_it++)
00099       if(isspace(*name_it))
00100         *name_it = '_';
00101 
00102     // let us build a string!
00103     string xferlog = time_string;
00104     xferlog += util.itos(time(NULL) - start_time);
00105     xferlog += " " + data->host_name();
00106     xferlog += " " + util.itos(trans_size);
00107     xferlog += " " + temp_name + " ";
00108     xferlog += (data->settings(BINARY)?"b":"a");
00109     xferlog += " _ "; // we don't support any special-action to flag here.
00110     xferlog += (data->settings(RETR_TRANS)?"o":"i");
00111     xferlog += (data->user->settings(ANONYMOUS)? // a for anonymous, r for real
00112         " a " + data->user->anonymous_id(): // if the user is anonymous we log
00113         " r " + data->user->user_name()); // the id string, else the user name.
00114     xferlog += " FTP"; // maybe ftps for encrypted? no. IANA.
00115     xferlog += " 0"; // there should be more auth methods available here?
00116     xferlog += " *"; // or should this be uid?
00117 
00118     logging->log_this(1, TYPE_XFER, xferlog);
00119   }
00120 
00121   pthread_exit(NULL);
00122 }

Here is the call graph for this function:

int pam_conversate ( int  ,
const struct pam_message **  ,
struct pam_response **  ,
void *   
)

Definition at line 171 of file Commands.cpp.

References pam_data::password, and pam_data::user_name.

Referenced by Commands::pass().

00173 {
00174   struct pam_response *reply = NULL;
00175   int count = 0;
00176   struct pam_data *auth_data = (static_cast<struct pam_data*>(appdata_ptr));
00177 
00178   for(int i = 0; i < num_msg; i++)
00179   {
00180     struct pam_response *reply_tmp;
00181     switch(msg[i]->msg_style)
00182     {
00183       case PAM_PROMPT_ECHO_ON:
00184       case PAM_PROMPT_ECHO_OFF:
00185         reply_tmp = (static_cast<struct pam_response*>
00186             (malloc(sizeof(struct pam_response) * (count + 1))));
00187         memcpy(reply_tmp, reply, count);
00188         if(reply)
00189           free(reply);
00190         reply = reply_tmp;
00191 
00192         // is this really how it should be done?
00193         if(msg[i]->msg_style == PAM_PROMPT_ECHO_ON)
00194           reply[i].resp = strndup(auth_data->user_name.c_str(),
00195               auth_data->user_name.size());
00196         else
00197           reply[i].resp = strndup(auth_data->password.c_str(),
00198               auth_data->password.size());
00199 
00200         reply[count++].resp_retcode = PAM_SUCCESS;
00201         break;
00202 
00203       case PAM_TEXT_INFO:
00204         break;
00205 
00206       case PAM_ERROR_MSG:
00207       default:
00208         if(reply)
00209           free(reply);
00210         return PAM_CONV_ERR;
00211     }
00212   }
00213   *resp = reply;
00214   return PAM_SUCCESS;
00215 }

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 }


Variable Documentation

const int BEFORE_USER = (1 << 31)

Definition at line 103 of file Commands.h.

Referenced by Handler::Handler(), and Handler::interpreter().

const int COM_APPE = (1 << 1)

Definition at line 72 of file Commands.h.

Referenced by Handler::Handler().

const int COM_CCC = (1 << 9)

Definition at line 87 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_CDUP = (1 << 0)

Definition at line 74 of file Commands.h.

Referenced by Commands::cwd(), and Handler::Handler().

const int COM_CONF = (1 << 10)

Definition at line 88 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_CWD = (1 << 1)

Definition at line 75 of file Commands.h.

Referenced by Handler::Handler().

const int COM_ENC = (1 << 12)

Definition at line 90 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_EPRT = (1 << 1)

Definition at line 98 of file Commands.h.

Referenced by Handler::Handler(), and Commands::port().

const int COM_EPSV = (1 << 3)

Definition at line 100 of file Commands.h.

Referenced by Handler::Handler(), and Commands::pasv().

const int COM_FEAT = (1 << 3)

Definition at line 80 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_FROM = (1 << 0)

Definition at line 68 of file Commands.h.

Referenced by Handler::Handler(), and Commands::rname().

const int COM_LONG = (1 << 0)

Definition at line 64 of file Commands.h.

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

const int COM_MDTM = (1 << 1)

Definition at line 94 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim2().

const int COM_MIC = (1 << 11)

Definition at line 89 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_MLSD = (1 << 2)

Definition at line 66 of file Commands.h.

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

const int COM_MLST = (1 << 2)

Definition at line 95 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim2().

const int COM_MODE = (1 << 5)

Definition at line 82 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_NOOP = (1 << 0)

Definition at line 77 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_PASV = (1 << 2)

Definition at line 99 of file Commands.h.

Referenced by Handler::Handler(), and Commands::pasv().

const int COM_PBSZ = (1 << 7)

Definition at line 85 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_PORT = (1 << 0)

Definition at line 97 of file Commands.h.

Referenced by Handler::Handler(), and Commands::port().

const int COM_PROT = (1 << 8)

Definition at line 86 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_PWD = (1 << 1)

Definition at line 78 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_SHORT = (1 << 1)

Definition at line 65 of file Commands.h.

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

const int COM_SIZE = (1 << 0)

Definition at line 93 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim2().

const int COM_STOR = (1 << 0)

Definition at line 71 of file Commands.h.

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

const int COM_STRU = (1 << 6)

Definition at line 83 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_SYST = (1 << 2)

Definition at line 79 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

const int COM_TO = (1 << 1)

Definition at line 69 of file Commands.h.

Referenced by Handler::Handler(), and Commands::rname().

const int COM_TYPE = (1 << 4)

Definition at line 81 of file Commands.h.

Referenced by Handler::Handler(), and Commands::sim1().

class Commands comm

Definition at line 15 of file Commands.cpp.

Referenced by exit_baby(), Handler::interpreter(), main(), Commands::pass(), and User::~User().

const int PROT_IPV4 = 1

Definition at line 105 of file Commands.h.

Referenced by Commands::pasv(), and Commands::port().

const int PROT_IPV6 = 2

Definition at line 106 of file Commands.h.

vector<User*> user_list

Definition at line 44 of file babyftpd.h.

gnutls_certificate_credentials x509_cred

Definition at line 50 of file babyftpd.h.