DocumentationGenerated on Thu Aug 31 00:02:36 2006 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Commands Class Reference#include <Commands.h>
Detailed Description
Definition at line 26 of file Commands.h. Member Function Documentation
Definition at line 102 of file Commands2.cpp. Referenced by Handler::Handler(). 00103 { 00104 string message = "226 "; 00105 if(user->data_vec.empty()) 00106 message += "No Data Connections to cancel"; 00107 else 00108 { 00109 for(vector<class Data*>::iterator data_it = user->data_vec.begin(); 00110 data_it != user->data_vec.end(); data_it++) 00111 if(*data_it) 00112 pthread_cancel((*data_it)->thread_id()); 00113 message += "All Data Connections Successfully closed."; 00114 } 00115 *user << message << ".\r\n"; 00116 return(true); 00117 }
Definition at line 1212 of file Commands2.cpp. References B_SET, config, DENY, FAILURE, Configuration::get_user(), and TLS_PROT_D. Referenced by Handler::Handler(). 01213 { 01214 transform(argument.begin(), argument.end(), argument.begin(), 01215 (int(*)(int))toupper); 01216 01217 if(argument == "TLS" || argument == "TLS-C" || argument == "SSL") 01218 { 01219 if(config->get_user(user->user_name()).encryption == DENY) 01220 { 01221 *user << 01222 "421 Sorry, you are not allowed to use encryption, disconnecting.\r\n"; 01223 user->settings(FAILURE, B_SET); 01224 return false; 01225 } 01226 *user << "234 Now starting encryption using TLS.\r\n"; 01227 if(!user->engage_tls()) 01228 { // failure =( 01229 user->settings(FAILURE, B_SET); 01230 *user << "421 Handshake failed. Disconnecting.\r\n"; 01231 } 01232 else 01233 { // wee! 01234 if(argument == "SSL") 01235 user->settings(TLS_PROT_D, B_SET); 01236 } 01237 } 01238 else 01239 *user << "504 Sorry, I don't understand the mechanism '" 01240 << argument << "'.\r\n"; 01241 01242 return true; 01243 }
Here is the call graph for this function: ![]()
Definition at line 255 of file Commands2.cpp. References COM_CDUP, Utilities::is_set(), and util. Referenced by Handler::Handler(). 00256 { 00257 struct stat stt; 00258 string message, new_dir; 00259 DIR *tmp_dir; 00260 00261 if(util.is_set(flag, COM_CDUP)) 00262 argument = ".."; 00263 00264 if((user->root_dir().size() > 1 && (user->current_dir().size() == 00265 user->root_dir().size())) && (argument == ".." || argument == ".")) 00266 new_dir = user->root_dir(); 00267 else 00268 new_dir = this->parsedir(user, argument); 00269 00270 00271 lstat(new_dir.c_str(), &stt); 00272 00273 if(S_ISLNK(stt.st_mode)) 00274 { 00275 char real_name[65] = { 0 }; 00276 int len; 00277 00278 len = readlink(new_dir.c_str(), real_name, 60); 00279 real_name[len] = '\0'; 00280 00281 new_dir = this->parsedir(user, real_name); 00282 } 00283 00284 if(!(tmp_dir = opendir(new_dir.c_str()))) 00285 { 00286 if(errno == EACCES) 00287 message = "550 '" + new_dir + "' permission denied."; 00288 else 00289 message = "550 '" + new_dir + "' no such file or directory."; 00290 } 00291 else 00292 { 00293 if(util.is_set(flag, COM_CDUP)) 00294 message = "200 'CDUP' command successful."; 00295 else // COM_CWD 00296 message = "250 'CWD' command successful."; 00297 00298 user->current_dir(new_dir); 00299 } 00300 closedir(tmp_dir); 00301 *user << message << "\r\n"; 00302 return(true); 00303 }
Here is the call graph for this function: ![]()
Definition at line 744 of file Commands2.cpp. Referenced by Handler::Handler(). 00745 { 00746 string message, new_file = parsedir(user, argument); 00747 00748 if(unlink(new_file.c_str())) 00749 { 00750 message = "550 "; 00751 if(errno == EPERM || errno == EACCES) 00752 message += "File access denied, not deleted."; 00753 else if(errno == EPERM) 00754 message += "File \"" + new_file + "\" is a directory."; 00755 else if(errno == ENOENT || errno == EISDIR) 00756 message += "File not found."; 00757 else 00758 message = "450 File not available."; 00759 } 00760 else 00761 message = "250 'DELE' command successful."; 00762 00763 *user << message << "\r\n"; 00764 return(true); 00765 }
Definition at line 212 of file Commands2.cpp. References general_stru::admin_email, Handler::cmd_info, config, Configuration::general, and handler. Referenced by Handler::Handler(). 00213 { 00214 string message; 00215 if(!argument.size()) 00216 { 00217 int cmd = 0; 00218 message = "214-The following commands are understood:\r\n "; 00219 for(hash_map<const char*, struct command_info, hash<const char*>, 00220 Utilities::eqstr>::iterator cmd_it = handler->cmd_info.begin(); 00221 cmd_it != handler->cmd_info.end(); cmd_it++) 00222 { 00223 if(!(*(cmd_it)).second.hlp_info.empty()) 00224 { 00225 if(cmd != 0 && cmd % 8 == 0) 00226 message += "\r\n "; 00227 message += (*(cmd_it)).first; 00228 message += '\t'; 00229 cmd++; 00230 } 00231 } 00232 message += 00233 "\r\n214 if you have any trouble please contact the administrator at " 00234 + config->general.admin_email + "."; 00235 } 00236 else 00237 { 00238 // other help stuff here... 00239 message = "214 Syntax: "; 00240 transform(argument.begin(), argument.end(), argument.begin(), 00241 (int(*)(int))toupper); 00242 hash_map<const char*, struct command_info, hash<const char*>, Utilities:: 00243 eqstr>::iterator cmd_it = handler->cmd_info.find(argument.c_str()); 00244 00245 if(cmd_it != handler->cmd_info.end() && 00246 !(*(cmd_it)).second.hlp_info.empty()) 00247 message += ((*(cmd_it)).first + (*(cmd_it)).second.hlp_info); 00248 else 00249 message = "500 No help available for '" + argument + "'"; 00250 } 00251 *user << message << "\r\n"; 00252 return(true); 00253 }
Definition at line 418 of file Commands2.cpp. References COM_LONG, COM_MLSD, COM_SHORT, Data::Data(), DATA_OPEN, Connection::engage_tls(), FAILURE, Utilities::is_set(), Connection::settings(), TLS_PROT_D, Data::user, and util. Referenced by Handler::Handler(). 00419 { 00420 struct stat stt; 00421 string failure; 00422 00423 if(argument.size() == 0) 00424 argument = user->current_dir(); 00425 00426 string file = parsedir(user, argument); 00427 00428 if((lstat(file.c_str(), &stt)) == -1 && ((util.is_set(flag, COM_LONG) || 00429 util.is_set(flag, COM_MLSD)) && argument[0] == '-')) 00430 { 00431 class StringTokenizer *token = new StringTokenizer(argument, " ", false); 00432 token->nextToken(); 00433 argument = token->restTokens(); 00434 delete token; 00435 file = parsedir(user, argument); 00436 lstat(file.c_str(), &stt); 00437 } 00438 00439 if(!S_ISDIR(stt.st_mode) && util.is_set(flag, COM_MLSD)) 00440 { 00441 *user << "501 Argument to MLSD has to be a directory.\r\n"; 00442 return false; 00443 } 00444 00445 class Data *data = new Data(user); 00446 00447 if(!data->settings(DATA_OPEN)) 00448 failure = "425 Can't open data connection."; 00449 else 00450 { 00451 *user << "150 Opening "; 00452 #ifdef USE_TLS 00453 if(data->settings(TLS_PROT_D)) 00454 { 00455 *user << "PROTECTED ASCII mode data connection for file list.\r\n"; 00456 if(!data->engage_tls()) 00457 failure = 00458 "451 Failed to negotiate TLS as was asked. Closing data connection."; 00459 } 00460 else 00461 #endif // USE_TLS 00462 *user << " ASCII mode data connection for file list.\r\n"; 00463 if(S_ISDIR(stt.st_mode)) 00464 { 00465 struct dirent dirstr, *dirptr; 00466 vector<string> dirlist; 00467 00468 DIR *dirp = opendir(file.c_str()); 00469 while((readdir_r(dirp, &dirstr, &dirptr) == 0) && dirptr != NULL) 00470 { 00471 #ifdef _DIRENT_HAVE_D_TYPE 00472 if((dirstr.d_type == DT_DIR) && util.is_set(flag, COM_SHORT)) 00473 continue; 00474 #endif // _DIRENT_HAVE_D_TYPE 00475 dirlist.push_back(dirstr.d_name); 00476 } 00477 00478 closedir(dirp); 00479 00480 // sorting the directory so we output first things first 00481 sort(dirlist.begin(), dirlist.end()); 00482 for(vector<string>::iterator dir_it = dirlist.begin(); 00483 dir_it != dirlist.end(); dir_it++) 00484 { 00485 if(util.is_set(flag, COM_LONG)) 00486 *data << list_file(file + "/" + *dir_it); 00487 else if(util.is_set(flag, COM_MLSD)) 00488 *data << mlsx(user, file + "/" + *dir_it); 00489 else 00490 *data << *dir_it; // short list. 00491 00492 *data << "\r\n"; 00493 if(data->settings(FAILURE)) 00494 break; 00495 } 00496 } 00497 else 00498 { 00499 if(util.is_set(flag, COM_LONG)) 00500 *data << list_file(file); 00501 else // NLST 00502 *data << argument; 00503 *data << "\r\n"; 00504 } 00505 if(data->settings(FAILURE)) 00506 failure = "426 LIST transfer failed."; 00507 } 00508 if(failure.size() > 0) 00509 *user << failure << "\r\n"; 00510 else 00511 *user << "226 Transfer complete.\r\n"; 00512 00513 delete data; 00514 return(true); 00515 }
Here is the call graph for this function: ![]()
Definition at line 517 of file Commands2.cpp. References Utilities::itos(), Utilities::parse_perms_ls(), PWBUF_SIZE, Utilities::time_string(), and util. 00518 { 00519 char size[20], nlink[6], pwdbuf[PWBUF_SIZE], grpbuf[PWBUF_SIZE]; 00520 string user_name, group_name, time_string; 00521 struct stat file_stat; 00522 struct passwd pwd, *pwd_ptr; 00523 struct group grp, *grp_ptr; 00524 00525 lstat(file_name.c_str(), &file_stat); 00526 00527 // number of hard links 00528 snprintf(nlink, 5, "%3d ", static_cast<int>(file_stat.st_nlink)); 00529 00530 if((getpwuid_r(file_stat.st_uid, &pwd, pwdbuf, sizeof(pwdbuf), 00531 &pwd_ptr)) == 0) 00532 user_name = pwd.pw_name; 00533 else 00534 user_name = util.itos(file_stat.st_uid); 00535 00536 if((getgrgid_r(file_stat.st_gid, &grp, grpbuf, sizeof(grpbuf), 00537 &grp_ptr)) == 0) 00538 group_name = grp.gr_name; 00539 else 00540 group_name = util.itos(file_stat.st_gid); 00541 00542 snprintf(size, 19, "%9d ", static_cast<int>(file_stat.st_size)); // filesize 00543 00544 // modification time, either in new ls format, or old.. 00545 #ifdef USE_NEWLS 00546 string time_format = "%Y-%m-%d %H:%M "; 00547 #else 00548 string time_format; 00549 // is the file over a year old? 00550 if((time(NULL) - file_stat.st_mtime) > (60 * 60 * 24 * 365)) 00551 time_format = "%b %e %Y "; 00552 else // if it's not, we display the time it was created as well. 00553 time_format = "%b %e %H:%M "; 00554 #endif // USE_NEWLS 00555 00556 util.time_string(time_string, time_format, 25, file_stat.st_mtime); 00557 00558 string message = (util.parse_perms_ls(file_stat.st_mode) + ' ') 00559 + nlink + user_name + '\t' + group_name + '\t' + size + time_string 00560 + basename(file_name.c_str()); // parsing everything on one line is neater. 00561 00562 // if it's a link... 00563 if(S_ISLNK(file_stat.st_mode)) 00564 { 00565 char real_name[55]; 00566 int len = readlink(file_name.c_str(), real_name, 50); 00567 real_name[len] = '\0'; 00568 message += " -> "; 00569 message += real_name; 00570 } 00571 return(message); 00572 }
Here is the call graph for this function: ![]()
Definition at line 700 of file Commands2.cpp. Referenced by Handler::Handler(). 00701 { 00702 string message, new_dir = parsedir(user, argument); 00703 00704 if(mkdir(new_dir.c_str(), 0755)) 00705 { 00706 message = "550 "; 00707 if(errno == EEXIST) 00708 message += "File exists."; 00709 else if(errno == EACCES) 00710 message += "Write access denied."; 00711 else if(errno == (ENOTDIR || ENOENT)) 00712 message += "Faulty pathname, directory not created."; 00713 else 00714 message += "Directory not created."; 00715 } 00716 else 00717 message = "257 \"" + argument + "\" created."; 00718 00719 *user << message << "\r\n"; 00720 return(true); 00721 }
Definition at line 1003 of file Commands2.cpp. References FACT_MODIFY, FACT_PERM, FACT_SIZE, FACT_TYPE, FACT_U_GID, FACT_U_LINK, FACT_U_MODE, FACT_U_UID, FACT_UNIQUE, and user(). 01004 { 01005 string message; 01006 01007 message += ("Type"); message += 01008 (user->settings(FACT_TYPE) ? "*;" : ";"); 01009 message += ("Size"); message += 01010 (user->settings(FACT_SIZE) ? "*;" : ";"); 01011 message += ("Modify"); message += 01012 (user->settings(FACT_MODIFY) ? "*;" : ";"); 01013 message += ("Unique"); message += 01014 (user->settings(FACT_UNIQUE) ? "*;" : ";"); 01015 message += ("Perm"); message += 01016 (user->settings(FACT_PERM) ? "*;" : ";"); 01017 message += ("Unix.mode"); message += 01018 (user->settings(FACT_U_MODE) ? "*;" : ";"); 01019 message += ("Unix.uid"); message += 01020 (user->settings(FACT_U_UID) ? "*;" : ";"); 01021 message += ("Unix.gid"); message += 01022 (user->settings(FACT_U_GID) ? "*;" : ";"); 01023 message += ("Unix.link"); message += 01024 (user->settings(FACT_U_LINK) ? "*;" : ";"); 01025 return(message); 01026 }
Here is the call graph for this function: ![]()
Definition at line 574 of file Commands2.cpp. References FACT_MODIFY, FACT_PERM, FACT_SIZE, FACT_TYPE, FACT_U_GID, FACT_U_LINK, FACT_U_MODE, FACT_U_UID, FACT_UNIQUE, Utilities::is_set(), Utilities::itos(), Utilities::parse_perms_num(), parsedir(), PWBUF_SIZE, Utilities::time_string(), user(), and util. 00575 { 00576 char pwdbuf[PWBUF_SIZE], grpbuf[PWBUF_SIZE]; 00577 struct passwd pwd, *pwd_ptr; 00578 struct group grp, *grp_ptr; 00579 00580 struct stat stt; 00581 string message; 00582 00583 lstat(file_name.c_str(), &stt); 00584 00585 // type. 00586 if(user->settings(FACT_TYPE)) 00587 { 00588 string type; 00589 if(S_ISREG(stt.st_mode)) 00590 type = "file"; 00591 else if(S_ISDIR(stt.st_mode)) 00592 { 00593 if(file_name == user->current_dir()) 00594 { 00595 type = "cdir"; 00596 file_name += "/."; 00597 } 00598 else if(file_name == parsedir(user, user->current_dir() + "/..")) 00599 type = "pdir"; 00600 else 00601 type = "dir"; 00602 } 00603 else if(S_ISLNK(stt.st_mode)) 00604 type = "OS.unix=slink"; 00605 else if(S_ISCHR(stt.st_mode)) 00606 type = "OS.unix=chr"; 00607 else if(S_ISBLK(stt.st_mode)) 00608 type = "OS.unix=blk"; 00609 else if(S_ISFIFO(stt.st_mode)) 00610 type = "OS.unix=fifo"; // or? 00611 else if(S_ISSOCK(stt.st_mode)) 00612 type = "OS.unix=sock"; // or? 00613 00614 message = "Type=" + type + ";"; 00615 } 00616 00617 if(user->settings(FACT_SIZE)) 00618 message += "Size=" + util.itos(stt.st_size) + ";"; 00619 if(user->settings(FACT_MODIFY)) 00620 { 00621 string tmp_time; 00622 util.time_string(tmp_time, "Modify=%Y%m%d%H%M%S;", 23, stt.st_mtime); 00623 message += tmp_time; 00624 } 00625 if(user->settings(FACT_UNIQUE)) 00626 message += "Unique=" + util.itos(stt.st_dev) + "g" + 00627 util.itos(stt.st_ino) + ";"; 00628 if(user->settings(FACT_PERM)) 00629 { 00630 bool owner = false, group = false; 00631 00632 if(getpwnam_r(user->user_name().c_str(), &pwd, pwdbuf, sizeof(pwdbuf), 00633 &pwd_ptr)) 00634 { 00635 if(pwd.pw_uid == stt.st_uid) 00636 owner = true; 00637 else if(pwd.pw_gid == stt.st_gid) 00638 group = true; 00639 } 00640 00641 if(!group && !owner) 00642 { 00643 if(getgrgid_r(stt.st_gid, &grp, grpbuf, sizeof(grpbuf), &grp_ptr)) 00644 for(int i = 0; grp.gr_mem[i] != NULL; i++) 00645 if(user->user_name() == grp.gr_mem[i]) 00646 group = true; 00647 } 00648 00649 message += "Perm="; 00650 if(owner) 00651 { 00652 if(S_ISDIR(stt.st_mode)) 00653 { 00654 if(util.is_set(stt.st_mode, S_IRUSR)) message += "l"; 00655 if(util.is_set(stt.st_mode, S_IWUSR)) message += "cmp"; 00656 if(util.is_set(stt.st_mode, S_IXUSR)) message += "e"; 00657 } 00658 if(util.is_set(stt.st_mode, S_IRUSR)) message += "r"; 00659 if(util.is_set(stt.st_mode, S_IWUSR)) message += "adfw"; 00660 } 00661 else if(group) 00662 { 00663 if(S_ISDIR(stt.st_mode)) 00664 { 00665 if(util.is_set(stt.st_mode, S_IRGRP)) message += "l"; 00666 if(util.is_set(stt.st_mode, S_IWGRP)) message += "cmp"; 00667 if(util.is_set(stt.st_mode, S_IXGRP)) message += "e"; 00668 } 00669 if(util.is_set(stt.st_mode, S_IRGRP)) message += "r"; 00670 if(util.is_set(stt.st_mode, S_IWGRP)) message += "adfw"; 00671 } 00672 else 00673 { 00674 if(S_ISDIR(stt.st_mode)) 00675 { 00676 if(util.is_set(stt.st_mode, S_IROTH)) message += "l"; 00677 if(util.is_set(stt.st_mode, S_IWOTH)) message += "cmp"; 00678 if(util.is_set(stt.st_mode, S_IXOTH)) message += "e"; 00679 } 00680 if(util.is_set(stt.st_mode, S_IROTH)) message += "r"; 00681 if(util.is_set(stt.st_mode, S_IWOTH)) message += "adfw"; 00682 } 00683 message += ";"; 00684 } 00685 if(user->settings(FACT_U_MODE)) 00686 message += "Unix.mode=" + util.parse_perms_num(stt.st_mode) + ";"; 00687 if(user->settings(FACT_U_UID)) 00688 message += "Unix.uid=" + util.itos(stt.st_uid) + ";"; 00689 if(user->settings(FACT_U_GID)) 00690 message += "Unix.gid=" + util.itos(stt.st_gid) + ";"; 00691 if(user->settings(FACT_U_LINK)) 00692 message += "Unix.link=" + util.itos(stt.st_nlink) + ";"; 00693 if(user->root_dir().size() > 1) 00694 file_name.erase(0, user->root_dir().size()); 00695 message += " " + file_name; 00696 00697 return(message); 00698 }
Here is the call graph for this function: ![]()
Definition at line 952 of file Commands2.cpp. References B_FLIP, FACT_MODIFY, FACT_PERM, FACT_SIZE, FACT_TYPE, FACT_U_GID, FACT_U_LINK, FACT_U_MODE, FACT_U_UID, FACT_UNIQUE, and StringTokenizer::StringTokenizer(). Referenced by Handler::Handler(). 00953 { 00954 string command, message; 00955 class StringTokenizer *st; 00956 00957 if(argument == "") 00958 { 00959 message += "500-Recognized OPTS arguments: \r\n"; 00960 message += " MLST\r\n"; 00961 message += "500 End."; 00962 } 00963 else 00964 { 00965 transform(argument.begin(), argument.end(), argument.begin(), 00966 (int(*)(int))toupper); 00967 st = new StringTokenizer(argument, " ", false); 00968 command = st->nextToken(); 00969 argument = st->restTokens(); 00970 delete st; 00971 00972 if(command == "MLST") 00973 { 00974 string fact; 00975 st = new StringTokenizer(argument, ";", false); 00976 00977 while(st->hasMoreTokens()) 00978 { 00979 fact = st->nextToken(); 00980 if(fact == "TYPE") user->settings(FACT_TYPE, B_FLIP); 00981 else if(fact == "SIZE") user->settings(FACT_SIZE, B_FLIP); 00982 else if(fact == "MODIFY") user->settings(FACT_MODIFY, B_FLIP); 00983 else if(fact == "UNIQUE") user->settings(FACT_UNIQUE, B_FLIP); 00984 else if(fact == "PERM") user->settings(FACT_PERM, B_FLIP); 00985 else if(fact == "UNIX.MODE") user->settings(FACT_U_MODE, B_FLIP); 00986 else if(fact == "UNIX.UID") user->settings(FACT_U_UID, B_FLIP); 00987 else if(fact == "UNIX.GID") user->settings(FACT_U_GID, B_FLIP); 00988 else if(fact == "UNIX.LINK") user->settings(FACT_U_LINK, B_FLIP); 00989 }; 00990 00991 message = "200 MLST string now showing: " + mlst_string(user); 00992 delete st; 00993 } 00994 else 00995 message = "501 " + command + " not known as argument to OPTS."; 00996 } 00997 00998 *user << message << "\r\n"; 00999 01000 return(true); 01001 }
Here is the call graph for this function: ![]()
Definition at line 127 of file Commands.cpp. References StringTokenizer::countTokens(), StringTokenizer::hasMoreTokens(), StringTokenizer::nextToken(), StringTokenizer::StringTokenizer(), and user(). Referenced by mlsx(). 00128 { 00129 string new_string; 00130 00131 if(orig_string[0] != '/') 00132 orig_string = user->current_dir() + '/' + orig_string; 00133 00134 class StringTokenizer *token = new StringTokenizer(orig_string, "/", false); 00135 vector<string> dir_array; 00136 dir_array.reserve(token->countTokens()); 00137 00138 while(token->hasMoreTokens()) 00139 { 00140 dir_array.push_back(token->nextToken()); 00141 00142 if(dir_array.back().size() < 3) 00143 { // to save us from expensive string comparisons 00144 if(dir_array.back() == "..") 00145 { 00146 dir_array.pop_back(); 00147 if(!dir_array.empty()) 00148 dir_array.pop_back(); 00149 } 00150 else if(dir_array.back() == ".") 00151 dir_array.pop_back(); 00152 } 00153 } 00154 delete token; 00155 00156 if(dir_array.empty()) 00157 new_string = '/'; 00158 else 00159 for(vector<string>::iterator dir_it = dir_array.begin(); 00160 dir_it != dir_array.end(); dir_it++) 00161 new_string += '/' + *dir_it; 00162 00163 if(user->root_dir().size() > 1) 00164 if(new_string.find(user->root_dir()) != 0) 00165 new_string = user->root_dir() + new_string; 00166 00167 00168 return(new_string); 00169 }
Here is the call graph for this function: ![]()
Definition at line 119 of file Commands2.cpp. References A_ENABLE, ANONYMOUS, general_stru::anonymous, B_SET, comm, config, Configuration::general, Log::log_this(), LOGGED_IN, logging, NOT_LOGGED_IN, pam_conversate(), PAM_DONE, pam_lock, PWBUF_SIZE, TYPE_INFO, general_stru::user, pam_data::user_name, and USER_SUPPLIED. Referenced by Handler::Handler(). 00120 { 00121 // before everything else, lets check if it is really time for pass... 00122 if(user->logged_in() != USER_SUPPLIED) 00123 { 00124 string message; 00125 if(user->logged_in() == NOT_LOGGED_IN) 00126 message = "503 Login with 'USER' first."; 00127 else if(user->logged_in() == LOGGED_IN) 00128 message = "503 You are already logged in!"; 00129 00130 *user << message << "\r\n"; 00131 return(false); 00132 } 00133 00134 // is anonymous login enabled? 00135 if(config->general.anonymous >= A_ENABLE && 00136 user->user_name() == "anonymous") 00137 { 00138 char pwdbuf[PWBUF_SIZE]; 00139 struct passwd pwd, *pwd_ptr; 00140 getpwuid_r(config->general.user, &pwd, pwdbuf, sizeof(pwdbuf), &pwd_ptr); 00141 user->user_name(pwd.pw_name); 00142 00143 // maybe we should do some rudimentary checking of the adress? no? 00144 logging->log_this(3, TYPE_INFO, "anonymous login from " + user->host_name() 00145 + " with email " + argument + "."); 00146 *user << "230 Anonymous login successful.\r\n"; 00147 user->login(); 00148 user->settings(ANONYMOUS, B_SET); 00149 user->anonymous_id(argument); 00150 return(true); 00151 } 00152 00153 seteuid(0); // we need to become root to check the user 00154 // pam stuff 00155 struct pam_data *auth_data = new struct pam_data; 00156 struct pam_conv pamconv = { &pam_conversate, auth_data }; 00157 int pam_error = 0; 00158 pam_handle_t *tmp_pamh = user->pamh(); 00159 00160 auth_data->user_name = user->user_name(); 00161 auth_data->password = argument; 00162 argument.clear(); 00163 00164 sem_wait(&comm.pam_lock); 00165 pam_error = pam_start("babyftpd", user->user_name().c_str(), 00166 &pamconv, &tmp_pamh); 00167 user->pamh(tmp_pamh); 00168 00169 if(pam_error == 0) 00170 { 00171 pam_error = pam_authenticate(user->pamh(), 0); 00172 if(pam_error == 0) 00173 { 00174 pam_error = pam_acct_mgmt(user->pamh(), 0); 00175 if(pam_error == 0) 00176 pam_error = pam_setcred(user->pamh(), PAM_ESTABLISH_CRED); 00177 } 00178 } 00179 if(pam_error != 0) 00180 { 00181 pam_end(user->pamh(), pam_error); 00182 sem_post(&pam_lock); 00183 seteuid(config->general.user); // and back to some other user.. 00184 } 00185 00186 delete auth_data; 00187 00188 if(pam_error == 0) 00189 { 00190 pam_open_session(user->pamh(), PAM_SILENT); 00191 user->settings(PAM_DONE, B_SET); 00192 00193 const char *pam_username; 00194 pam_get_item(user->pamh(), PAM_USER, 00195 (reinterpret_cast<const void**>(&pam_username))); 00196 sem_post(&pam_lock); 00197 if(user->user_name() != pam_username) 00198 { 00199 logging->log_this(3, TYPE_INFO, "PAM changed username of " + 00200 user->user_name() + " to " + pam_username); 00201 user->user_name(pam_username); 00202 } 00203 00204 *user << "230 Password accepted, proceeding.\r\n"; 00205 user->login(); 00206 return(true); 00207 } 00208 *user << "530 Login denied.\r\n"; 00209 return(false); 00210 }
Here is the call graph for this function: ![]()
Definition at line 845 of file Commands2.cpp. References B_SET, COM_EPSV, COM_PASV, EPSV_ONLY, Utilities::is_set(), Utilities::itos(), StringTokenizer::nextToken(), PASSIVE, PROT_IPV4, StringTokenizer::StringTokenizer(), and util. Referenced by Handler::Handler(). 00846 { 00847 string message; 00848 00849 if(util.is_set(flag, COM_EPSV) && argument.size() > 0) 00850 { 00851 transform(argument.begin(), argument.end(), argument.begin(), 00852 (int(*)(int))toupper); 00853 if(argument == "ALL" && util.is_set(flag, COM_EPSV)) 00854 { 00855 user->settings(EPSV_ONLY, B_SET); 00856 message = "200 Now only accepting 'EPSV'"; 00857 } 00858 else 00859 message = "501 '" + argument + "' is not a valid argument to 'EPSV'."; 00860 } 00861 else 00862 { 00863 struct sockaddr_in tmp_addr = {0}, tmp_addr1 = {0}, tmp_addr2 = {0}; 00864 socklen_t len = sizeof(tmp_addr); 00865 00866 if(user->data_id()) 00867 close(user->data_id()); 00868 00869 user->data_id(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)); 00870 tmp_addr.sin_family = AF_INET; 00871 tmp_addr.sin_addr.s_addr = INADDR_ANY; 00872 bind(user->data_id(), reinterpret_cast<struct sockaddr*> 00873 (&tmp_addr), sizeof(tmp_addr)); 00874 user->data_addr(tmp_addr); 00875 listen(user->data_id(), 1); 00876 getsockname(user->data_id(), reinterpret_cast<struct sockaddr*> 00877 (&tmp_addr1), &len); 00878 getsockname(user->socket_id(), reinterpret_cast<struct sockaddr*> 00879 (&tmp_addr2), &len); 00880 user->settings(PASSIVE, B_SET); 00881 00882 unsigned int p = ntohs(tmp_addr1.sin_port); 00883 00884 if(util.is_set(flag, COM_PASV)) 00885 { 00886 if(user->settings(EPSV_ONLY)) 00887 message = 00888 "501 Only 'EPSV' may be used after the issuing of 'EPSV ALL'"; 00889 00890 else 00891 { 00892 class StringTokenizer *token = 00893 new StringTokenizer(inet_ntoa(tmp_addr2.sin_addr), ".", false); 00894 00895 message = "227 Entering Passive Mode ("; 00896 message += token->nextToken() + ","; 00897 message += token->nextToken() + ","; 00898 message += token->nextToken() + ","; 00899 message += token->nextToken() + ","; 00900 message += util.itos(p / 256) + "," 00901 + util.itos(p % 256) + ")."; 00902 00903 delete token; 00904 } 00905 } 00906 else if(util.is_set(flag, COM_EPSV)) 00907 { 00908 if(argument.size() > 0) 00909 if(argument != util.itos(PROT_IPV4)) 00910 message = "522 Network protocol not supported, use (1)"; 00911 00912 if(message.size() == 0) 00913 message = "229 Entering Extended Passive Mode (|||" + 00914 util.itos(p) + "|)"; 00915 } 00916 } 00917 *user << message << "\r\n"; 00918 return(true); 00919 }
Here is the call graph for this function: ![]()
Definition at line 767 of file Commands2.cpp. References B_RESET, COM_EPRT, COM_PORT, config, EPSV_ONLY, Configuration::get_user(), Utilities::is_set(), Utilities::itos(), PASSIVE, PROT_IPV4, and util. Referenced by Handler::Handler(). 00768 { 00769 string tmp_adress, message; 00770 int port = -1; 00771 00772 if(user->settings(EPSV_ONLY)) 00773 message = "501 Only 'EPSV' may be used after the issuing of 'EPSV ALL'"; 00774 00775 else if((config->get_user(user->user_name()).only_passive)) 00776 message = 00777 "501 Sorry, active data transfers are disabled for your account."; 00778 00779 else if(util.is_set(flag, COM_PORT)) 00780 { 00781 class StringTokenizer *token = new StringTokenizer(argument, ",", false); 00782 00783 if(token->countTokens() != 6) 00784 message = "501 Illegal 'PORT' command."; 00785 00786 else 00787 { 00788 tmp_adress = token->nextToken() + "."; // if we do this on one line 00789 tmp_adress += token->nextToken() + "."; // it builds the string from 00790 tmp_adress += token->nextToken() + "."; // the wrong direction, it's 00791 tmp_adress += token->nextToken(); // weird. 00792 00793 port = atoi((token->nextToken()).c_str()) * 256 + 00794 atoi((token->nextToken()).c_str()); 00795 } 00796 delete token; 00797 } 00798 else if(util.is_set(flag, COM_EPRT)) 00799 { 00800 class StringTokenizer *token = 00801 new StringTokenizer(argument, argument.substr(0, 1), false); 00802 00803 if(token->countTokens() != 3 || 00804 argument[argument.size() - 1] != argument[0]) 00805 message = "501 Illegal 'EPRT' command."; 00806 00807 else 00808 { 00809 if(token->nextToken() == util.itos(PROT_IPV4)) 00810 { 00811 tmp_adress = token->nextToken(); 00812 port = atoi(token->nextToken().c_str()); 00813 } 00814 else 00815 message = "522 Network protocol not supported, use (1)"; 00816 } 00817 delete token; 00818 } 00819 00820 if(message.empty()) 00821 { 00822 struct sockaddr_in temp_addr; 00823 if((inet_aton(tmp_adress.c_str(), &temp_addr.sin_addr)) == 0) 00824 { 00825 message = "501 Illegal '"; 00826 message += (util.is_set(flag, COM_PORT) ? "PORT" : "EPRT"); 00827 message += "' command."; 00828 } 00829 else 00830 { 00831 temp_addr.sin_port = htons(port); 00832 temp_addr.sin_family = AF_INET; 00833 user->settings(PASSIVE, B_RESET); 00834 message += "200 '"; 00835 message += (util.is_set(flag, COM_PORT) ? "PORT" : "EPRT"); 00836 message += "' command successful."; 00837 } 00838 user->data_addr(temp_addr); 00839 } 00840 00841 *user << message << "\r\n"; 00842 return(true); 00843 }
Here is the call graph for this function: ![]()
Definition at line 15 of file Commands2.cpp. References B_SET, and FAILURE. Referenced by Handler::Handler(). 00016 { 00017 *user << "221 Goodbye. You transfered a total of " 00018 << user->transfered() << " bytes." << "\r\n"; 00019 00020 user->settings(FAILURE, B_SET); 00021 return(true); 00022 }
Definition at line 400 of file Commands2.cpp. References Data::user. Referenced by Handler::Handler(). 00401 { 00402 char *endptr; 00403 string message; 00404 00405 off_t fpos = strtoul(argument.c_str(), &endptr, 0); 00406 if(!*endptr) 00407 { 00408 user->rest_pos(fpos); 00409 message = "350 Restarting at " + argument + ". Send STOR or RETR."; 00410 } 00411 else 00412 message = "501 Restart point not in numeric format."; 00413 00414 *user << message << "\r\n"; 00415 return(true); 00416 }
Definition at line 305 of file Commands2.cpp. References BINARY, Data::Data(), DATA_OPEN, User::data_vec, User::data_vec_full(), data_wrapper(), Utilities::itos(), Connection::lock, Connection::settings(), Data::user, and util. Referenced by Handler::Handler(). 00306 { 00307 struct stat stt; 00308 00309 string file_name = parsedir(user, argument); 00310 stat(file_name.c_str(), &stt); 00311 if(!S_ISREG(stt.st_mode)) 00312 { 00313 *user << "550 \"" << argument << "\" is not a regular file.\r\n"; 00314 return(false); 00315 } 00316 00317 int file_id = open(file_name.c_str(), O_RDONLY); 00318 if(user->rest_pos() > 0) 00319 { 00320 lseek(file_id, user->rest_pos(), SEEK_SET); 00321 user->rest_pos(0); 00322 } 00323 00324 *user << "150 Opening " << (user->settings(BINARY)?"BINARY":"ASCII") 00325 << " mode data connection for \"" << argument << "\" (" 00326 << util.itos(stt.st_size) << " bytes).\r\n"; 00327 00328 class Data *data = new Data(user, file_id, file_name, 1); 00329 if(!data->settings(DATA_OPEN) || user->data_vec_full()) 00330 { 00331 *user << "425 Can't open data connection.\r\n"; 00332 delete data; 00333 return(false); 00334 } 00335 00336 BABY_WRLOCK(user->lock); 00337 user->data_vec.push_back(data); 00338 BABY_UNLOCK(user->lock); 00339 pthread_t temp_id; 00340 pthread_create(&temp_id, NULL, data_wrapper, 00341 static_cast<void*>(data)); 00342 return(true); 00343 }
Here is the call graph for this function: ![]()
Definition at line 723 of file Commands2.cpp. Referenced by Handler::Handler(). 00724 { 00725 string message, new_dir = parsedir(user, argument); 00726 00727 if(rmdir(new_dir.c_str())) 00728 { 00729 message = "550 "; 00730 if(errno == EACCES) 00731 message += "Write access denied."; 00732 else if(errno == (ENOTDIR || ENOENT)) 00733 message += "Faulty pathname, directory not removed."; 00734 else 00735 message += "Directory not removed."; 00736 } 00737 else 00738 message = "250 \"" + argument + "\" removed."; 00739 00740 *user << message << "\r\n"; 00741 return(true); 00742 }
Definition at line 922 of file Commands2.cpp. References COM_FROM, COM_TO, Utilities::is_set(), and util. Referenced by Handler::Handler(). 00923 { 00924 string file_name, message; 00925 00926 file_name = parsedir(user, argument); 00927 00928 if(util.is_set(flag, COM_FROM)) 00929 { 00930 user->temp_buf(file_name); 00931 message = "350 Command OK, waiting for RNTO."; 00932 } 00933 else if(util.is_set(flag, COM_TO)) 00934 { 00935 if(user->temp_buf().size() == 0) 00936 message = "503 RNTO must come after RNFR."; 00937 else 00938 { 00939 if(!(rename(user->temp_buf().c_str(), file_name.c_str()))) 00940 message = "250 " + user->temp_buf() + " renamed to " + file_name + "."; 00941 else if(errno == EACCES) 00942 message = "550 Access denied."; 00943 else 00944 message = "553 Rename failed."; 00945 user->temp_buf(""); 00946 } 00947 } 00948 *user << message << "\r\n"; 00949 return(true); 00950 }
Here is the call graph for this function: ![]()
Definition at line 1029 of file Commands2.cpp. References B_RESET, B_SET, BINARY, COM_CCC, COM_CONF, COM_ENC, COM_FEAT, COM_MIC, COM_MODE, COM_NOOP, COM_PBSZ, COM_PROT, COM_PWD, COM_STRU, COM_SYST, COM_TYPE, config, Configuration::general, Utilities::is_set(), general_stru::os, TLS_ENABLED, TLS_PBSZ, TLS_PROT_D, and util. Referenced by Handler::Handler(). 01030 { 01031 string message; 01032 01033 transform(argument.begin(), argument.end(), argument.begin(), 01034 (int(*)(int))toupper); 01035 01036 if(util.is_set(flag, COM_NOOP)) 01037 message = "200 'NOOP': Command successful."; 01038 01039 else if(util.is_set(flag, COM_PWD)) 01040 { 01041 string dir = user->current_dir(); 01042 if(user->root_dir().size() > 1) 01043 dir.erase(0, user->root_dir().size()); 01044 if(dir == "") 01045 dir = "/"; 01046 message = "257 \"" + dir + "\" is current directory."; 01047 } 01048 01049 else if(util.is_set(flag, COM_SYST)) 01050 message = "215 " + config->general.os + " Type: L8"; 01051 01052 else if(util.is_set(flag, COM_FEAT)) 01053 { 01054 message = "211-Extensions supported:\r\n"; 01055 message += " SIZE\r\n"; 01056 message += " MDTM\r\n"; 01057 message += " MLST " + mlst_string(user) + "\r\n"; 01058 message += " REST STREAM\r\n"; 01059 message += " EPRT\r\n"; 01060 message += " EPSV\r\n"; 01061 #ifdef USE_TLS 01062 message += " AUTH TLS\r\n"; 01063 message += " PBSZ\r\n"; 01064 message += " PROT\r\n"; 01065 message += " CCC\r\n"; 01066 #endif // USE_TLS 01067 message += "211 End."; 01068 } 01069 01070 else if(util.is_set(flag, COM_TYPE)) 01071 { 01072 if(argument == "A" || argument == "A N") 01073 { 01074 message = "200 Type set to " + argument + "."; 01075 user->settings(BINARY, B_RESET); 01076 } 01077 else if(argument == "I" || argument == "L 8") 01078 { 01079 message = "200 Type set to " + argument + "."; 01080 user->settings(BINARY, B_SET); 01081 } 01082 else 01083 message = "504 'TYPE " + argument + "' not understood."; 01084 } 01085 01086 else if(util.is_set(flag, COM_MODE)) 01087 { 01088 if(argument == "S") 01089 { 01090 message = "200 Stream MODE enabled."; 01091 } 01092 else 01093 message = "504 'MODE " + argument + "' not understood."; 01094 } 01095 01096 else if(util.is_set(flag, COM_STRU)) 01097 { 01098 if(argument == "F") 01099 message = "200 Structure set to F."; 01100 else 01101 message = "504 'STRU " + argument + "' not understood."; 01102 } 01103 #ifdef USE_TLS 01104 else if(util.is_set(flag, COM_PBSZ)) 01105 { 01106 if(user->settings(TLS_ENABLED)) 01107 { 01108 if(argument == "0") 01109 { 01110 message = "200 PBSZ set for stream transfer."; 01111 user->settings(TLS_PBSZ, B_SET); 01112 } 01113 else 01114 message = "501 PBSZ has to be set to 0 for use with TLS."; 01115 } 01116 else 01117 message = 01118 "503 AUTH must be issued and negotiated before PBSZ can be used."; 01119 } 01120 01121 else if(util.is_set(flag, COM_PROT)) 01122 { 01123 if(!user->settings(TLS_ENABLED) || !user->settings(TLS_PBSZ)) 01124 message = 01125 "503 AUTH and PBSZ has to be issued and negotiated before PROT."; 01126 else 01127 switch(argument[0]) 01128 { 01129 case 'C': 01130 message = "200 Data connection set to CLEAR level."; 01131 user->settings(TLS_PROT_D, B_RESET); 01132 break; 01133 case 'P': 01134 message = "200 Data connection set to PRIVATE level."; 01135 user->settings(TLS_PROT_D, B_SET); 01136 break; 01137 case 'S': 01138 case 'E': 01139 message = "536 Only CLEAR and PRIVATE level is available with TLS."; 01140 break; 01141 default: 01142 message = "504 Protection level '" + argument + "' not understood."; 01143 } 01144 } 01145 else if(util.is_set(flag, COM_CCC)) // Clear Command Channel 01146 { 01147 if(!user->settings(TLS_ENABLED)) 01148 message = 01149 "533 CCC can only be issued on a protected control connection."; 01150 else // code for disallowing CCC should be above, containing a 534 01151 { 01152 *user << "200 Disabling TLS, control connection is now CLEAR.\r\n"; 01153 user->disengage_tls(); 01154 } 01155 } 01156 else if(util.is_set(flag, COM_CONF | COM_MIC | COM_ENC)) 01157 { 01158 // note, if we implement som other security messure than TLS we might 01159 // need these commands, for now they reside here and only return 01160 // a 503 or 537. 01161 string command; 01162 if(util.is_set(flag, COM_CONF)) 01163 command = "CONF"; 01164 else if(util.is_set(flag, COM_MIC)) 01165 command += "MIC"; 01166 else 01167 command += "ENC"; 01168 01169 if(!user->settings(TLS_ENABLED)) 01170 message = "503 Command " + command 01171 + " can not be issued before a valid security exchange."; 01172 else 01173 message = "537 Command " + command + " not used in TLS mode."; 01174 } 01175 #endif // USE_TLS 01176 01177 if(message.size() > 0) 01178 *user << message << "\r\n"; 01179 return(true); 01180 }
Here is the call graph for this function: ![]()
Definition at line 1182 of file Commands2.cpp. References COM_MDTM, COM_MLST, COM_SIZE, Utilities::is_set(), Utilities::itos(), Utilities::time_string(), and util. Referenced by Handler::Handler(). 01183 { 01184 string file_name, message; 01185 struct stat stt; 01186 01187 file_name = parsedir(user, argument); 01188 if(!(stat(file_name.c_str(), &stt))) 01189 { 01190 if(util.is_set(flag, COM_SIZE)) 01191 message = "213 " + util.itos(stt.st_size); 01192 01193 else if(util.is_set(flag, COM_MDTM)) 01194 util.time_string(message, "213 %Y%m%d%H%M%S", 19, stt.st_mtime); 01195 01196 else if(util.is_set(flag, COM_MLST)) 01197 { 01198 message = "250-Listing " + argument + "\r\n"; 01199 message += mlsx(user, file_name) + "\r\n"; 01200 message += "250 End."; 01201 } 01202 } 01203 else 01204 message = "550 \"" + argument + "\": No such file or directory."; 01205 01206 *user << message << "\r\n"; 01207 return(true); 01208 }
Here is the call graph for this function: ![]()
Definition at line 345 of file Commands2.cpp. References BINARY, COM_STOR, Data::Data(), DATA_OPEN, User::data_vec, User::data_vec_full(), data_wrapper(), Utilities::is_set(), Connection::lock, Connection::settings(), Data::user, and util. Referenced by Handler::Handler(). 00346 { 00347 int file_id; 00348 00349 string file_name = parsedir(user, argument); 00350 00351 if(util.is_set(flag, COM_STOR)) 00352 file_id = open(file_name.c_str(), O_WRONLY|O_CREAT|O_TRUNC, 00353 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); 00354 else // com_type == COM_APPE 00355 file_id = open(file_name.c_str(), O_WRONLY|O_APPEND|O_TRUNC, 00356 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); 00357 00358 if(file_id == -1) 00359 { 00360 string message; 00361 if(errno == EEXIST) 00362 message = "550 File " + file_name + " already exists."; 00363 else if(errno == EISDIR) 00364 message = "550 " + file_name + " is a directory."; 00365 else if(errno == EACCES) 00366 message = "550 Access to " + file_name + " denied."; 00367 else 00368 message = "550 File operation failed."; 00369 *user << message << "\r\n"; 00370 return false; 00371 } 00372 00373 // shouldn't try to restart an appending :p 00374 if(user->rest_pos() > 0 && util.is_set(flag, COM_STOR)) 00375 { 00376 lseek(file_id, user->rest_pos(), SEEK_SET); 00377 user->rest_pos(0); 00378 } 00379 00380 *user << "150 Opening " << (user->settings(BINARY)?"BINARY":"ASCII") 00381 << " mode data connection for \"" << argument << "\".\r\n"; 00382 00383 class Data *data = new Data(user, file_id, file_name, 0); 00384 if(!data->settings(DATA_OPEN) || user->data_vec_full()) 00385 { 00386 *user << "425 Can't open data connection.\r\n"; 00387 delete data; 00388 return(false); 00389 } 00390 00391 BABY_WRLOCK(user->lock); 00392 user->data_vec.push_back(data); 00393 BABY_UNLOCK(user->lock); 00394 pthread_t temp_id; 00395 pthread_create(&temp_id, NULL, data_wrapper, 00396 static_cast<void*>(data)); 00397 return(true); 00398 }
Here is the call graph for this function: ![]()
Definition at line 24 of file Commands2.cpp. References A_ENABLE, A_ONLY, general_stru::anonymous, B_SET, config, DENY, users_stru::encryption, FAILURE, FORCE, FORCE_CERT, Configuration::general, Configuration::get_user(), LOGGED_IN, users_stru::noftp, TLS_ENABLED, users_stru::user_limit, user_list, user_list_lock, and USER_SUPPLIED. Referenced by Handler::Handler(), mlst_string(), mlsx(), and parsedir(). 00025 { 00026 string message; 00027 bool ret = true, bad = false; 00028 if(user->logged_in() == LOGGED_IN) 00029 { 00030 message = "503 You are already logged in!"; 00031 ret = false; 00032 } 00033 else 00034 { 00035 int current_connections = 0; 00036 pthread_rwlock_rdlock(&user_list_lock); 00037 for(vector<User*>::iterator user_it = user_list.begin(); 00038 user_it != user_list.end(); user_it++) 00039 if((*user_it)->user_name() == argument) 00040 current_connections++; 00041 pthread_rwlock_unlock(&user_list_lock); 00042 00043 user->user_name(argument); 00044 user->logged_in(USER_SUPPLIED); 00045 00046 if(config->get_user(argument).noftp == true) 00047 { 00048 message = "421 Sorry, you are not allowed to use ftp. disconnecting."; 00049 bad = true; 00050 } 00051 else if(current_connections >= config->get_user(argument).user_limit){ 00052 message = 00053 "421 You have reached your maximum number of control connections."; 00054 bad = true; 00055 } 00056 #ifdef USE_TLS 00057 else if(config->get_user(argument).encryption == DENY && 00058 user->settings(TLS_ENABLED)) 00059 { 00060 message = "421 Sorry, you are not allowed to connect with" 00061 "encryption enabled, disconnecting."; 00062 bad = true; 00063 } 00064 else if(user->settings(TLS_ENABLED) && user->verify_cert()) 00065 { 00066 message = "230 Logged in as " + argument + "."; 00067 user->login(); 00068 } 00069 else if(config->get_user(argument).encryption == FORCE_CERT) 00070 { 00071 message = "421 You must supply a valid certificate to login."; 00072 bad = true; 00073 } 00074 else if(config->get_user(argument).encryption == FORCE && 00075 !user->settings(TLS_ENABLED)) 00076 { 00077 message = 00078 "421 You must enable encryption before logging in, disconnecting."; 00079 bad = true; 00080 } 00081 #endif // USE_TLS 00082 else if(config->general.anonymous >= A_ENABLE && 00083 user->user_name() == "anonymous") 00084 message = "331 Anonymous login. Please, provide your email as password."; 00085 else if(config->general.anonymous == A_ONLY) 00086 { 00087 message = "421 All logins except anonymous disabled, disconnecting."; 00088 bad = true; 00089 } 00090 else 00091 message = "331 Password required for " + argument + "."; 00092 } 00093 *user << message << "\r\n"; 00094 if(bad) 00095 { 00096 user->settings(FAILURE, B_SET); 00097 ret = false; 00098 } 00099 return(ret); 00100 }
Here is the call graph for this function: ![]()
Member Data Documentation
Definition at line 54 of file Commands.h. Referenced by exit_baby(), main(), pass(), and User::~User().
The documentation for this class was generated from the following files: |
- Copyright © 2005, BabyFTPd
- Powered by: