⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socdemon.c

📁 一个可以执行Client端传来的Shell命令的服务器程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Socket Demon. *   - A little program that waits on a internet port and *     handles interactive commands. *     Most of the routines are taken out of "Unix Network Programming" *     by W. Richard Stevens, Prentice Hall, 1990. * * History: *  1994: *   Jan. 14 - Initial program completed. *   Jan. 17 - Added in nil command (if you just press enter) *           - Added in "?" to be the same as help *           - Added in the "bye", "ls", "pwd", and "cd" commands. *           - Added in lotsa comments *           - Added the 'ver' command. *           - Added in support for the -port, -log and -command *             command line options. *           - Added in the 'die' command. *           - Added logging of connects, disconnects, die's, and *             bad passwords. *   Apr. 07 - Changed the password to be encrypted so it cannot be *             discovered with a strings(1) command. *           - Added the 'id' command. *           - Call setuid if uid != euid (so that if program is setuid root *           - we can take advantage of the priviledge). *           - Took out the annoying uid listing at login *   Apr. 11 - Added a debug mode, and moved most of the verbose FTP style *             comments to that mode, leaving normal mode more unix-ish. *           - Added in a uname command *           - Changed the output format of several commands to look more  *             unix-ish *   Apr. 13 - Split the program up in to a bunch of different files and *             made a make file for it. - Speeds up development and *             makes if easier to change.. *   Apr. 14 - Added new commands, cp, mv, rm *           - Redirected stdin, stdout and stderr to the client socket. *           - Added a shell! *   Apr. 15 - Added new commands, who, w, ps, chmod, chgrp, chown, cat, *             create*/#include "socdemon.h"#include "socketio.h"#include "soclog.h"/* * print_usage() *   - prints the program name, version, and date, and also *     the program parameters. See socdemon.h for all their *     definitions.*/void print_usage() { int i;   fprintf(stdout,"%s ver %s, %s.\n",SOCDEMON_NAME,SOCDEMON_VER,SOCDEMON_DATE);   fprintf(stdout,"usage: %s [option] [option]...\n",program_name);   fprintf(stdout,"where [option] is one of:\n");   for (i=0;i<parm_nil;i+=2) {      fprintf(stdout,"     %8.8s - %s\n",parm_table[i],parm_table[i+1]);   }}/* * socket_demon_shutdown() *   - shuts down the internet socket (the one created by  *     the original parent, not the descriptors created by the *     accept() call). This is called before the program terminates, *     (under an error condition, or when a SIGTERM signal is caught).*/void socket_demon_shutdown() {   soc_fprintf(stdout,"%s: Shutting down internet socket...",SOCDEMON_NAME);   if (shutdown(socket_descriptor, 2) != 0) {      soc_fprintf(stdout,"\n");      soc_fprintf(stderr,"ERROR(%d): Unable to shutdown socket [%d].\n",                  CANT_SHUTDOWN_SOCKET, errno);      /* dont exit, try and close it */   }   soc_fprintf(stdout,"done.\n");   soc_fprintf(stdout,"%s: Closing internet socket...",SOCDEMON_NAME);   if (close(socket_descriptor) != 0) {      soc_fprintf(stdout,"\n");      soc_fprintf(stderr,"ERROR(%d): Unable to close socket [%d].\n",                  CANT_CLOSE_SOCKET, errno);      exit(CANT_CLOSE_SOCKET);   }   soc_fprintf(stdout,"done.\n");}/* * socket_demon_death_action() *   - this is the signal handler for the signals SIGTERM and SIGKILL, *     however, I don't think it catches the SIGKILL's, so always kill *     with a plain kill, and never a -9 parm.*/void socket_demon_death_action() {   soc_fprintf(stdout,"%s: Received shutdown notice.\n",SOCDEMON_NAME);   socket_demon_shutdown();   soc_fprintf(stdout,"%s: Exiting..\n",SOCDEMON_NAME);   exit(0);}/* * soc_demon_main_proc() *   - This is sorta the main process that the forked process  *     handling the incoming user sits in.  It waits for input *     and then calls the handler proc for that action. *   - The daemon forks, the parent executing this routine, and *     the child returning to wait on the port.  The benefits of *     doing it this way, instead of having the parent go back *     to wait on the port is that  *       i) You don't get defunct processes in you process tables *      ii) The process id of the main daemon changes after every *          use.*/void soc_demon_main_proc() { char in_msg[MAX_INPUT_LEN]; char in_parm[MAX_INPUT_LEN]; char *cmd_ptr; char out_msg[MAX_OUTPUT_LEN]; int  msg_len = 0; int  i;   for (;;) {      tell_user(client_descriptor, SOCDEMON_PROMPT);      msg_len = soc_read(client_descriptor, in_msg, MAX_INPUT_LEN);      if (msg_len < 0) {         soc_fprintf(stderr,"ERROR(%d): Error reading socket input [%d:%d].\n",                     SOCKET_INPUT_ERROR, msg_len, errno);         return;      }      if (in_msg[strlen(in_msg)-1] == '\n') {         in_msg[strlen(in_msg)-2] = 0;         strcpy(in_parm,in_msg);         cmd_ptr = (char *) strtok(in_msg," ");         i = strlen(in_msg);         cmd_ptr = &in_parm[i];         strcpy(in_parm,cmd_ptr);         if (in_parm[0] != 0) {            cmd_ptr = &in_parm[1];            strcpy(in_parm,cmd_ptr);         }         for (i=0;i<strlen(in_msg);i++) {            in_msg[i] = toupper(in_msg[i]);         }#ifdef LOG_TO_DEATH         log_command(in_msg);#endif         if ((!strcmp(in_msg,command_table[cmd_help]))            || (!strcmp(in_msg,command_table[cmd_qstn]))) {            tell_user(client_descriptor, "%3.3d - %s", valid_commands,                      out_table[valid_commands]);            for (i=0;i<=cmd_nil;i+=2) {               tell_user(client_descriptor, "  %-6.6s - %s\n",                         command_table[i],command_table[i+1]);            }         } else if ((!strcmp(in_msg,command_table[cmd_quit]))                   || (!strcmp(in_msg,command_table[cmd_bye]))) {            tell_user(client_descriptor, "%3.3d - %s", goodbye_str,                      out_table[goodbye_str]);            break;         } else if (!strcmp(in_msg,command_table[cmd_ver])) {            report_version();         } else if (!strcmp(in_msg,command_table[cmd_pwd])) {            get_pwd();         } else if (!strcmp(in_msg,command_table[cmd_whoami])) {            who_am_i();         } else if (!strcmp(in_msg,command_table[cmd_id])) {            get_id();         } else if (!strcmp(in_msg,command_table[cmd_cp])) {            do_cp(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_rm])) {            do_rm(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_ps])) {            do_ps(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_w])) {            do_unix_command("w");         } else if (!strcmp(in_msg,command_table[cmd_who])) {            do_unix_command("who");         } else if (!strcmp(in_msg,command_table[cmd_create])) {            do_create(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_chmod])) {            do_chmod(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_chown])) {            do_chown(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_chgrp])) {            do_chgrp(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_mv])) {            do_mv(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_cat])) {            do_cat(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_shell])) {            do_shell();         } else if (!strcmp(in_msg,command_table[cmd_uname])) {            strcpy(out_msg,"uname");            if (in_parm[0] != 0) {               strcat(out_msg," ");               strcat(out_msg,in_parm);            }            do_unix_command(out_msg);         } else if (!strcmp(in_msg,command_table[cmd_cd])) {            ch_dir(in_parm);         } else if (!strcmp(in_msg,command_table[cmd_die])) {            /* ok, to kill both the client and the server, we */            /* first kill our parent, then ourselves... when  */            /* our parent get's the TERM signal, we might be  */            /* knocked off to, but just incase, send ourselves*/            /* the TERM signal too, so that everything is nice*/             /* and tidy                                       */#ifdef LOG_TO_DEATH            log_stuff(killed_by_command);#endif            kill(getppid(),SIGTERM); /* bam, our parent is dead */            kill(getpid(), SIGTERM); /* bam, we're dead.        */         } else if (!strcmp(in_msg,command_table[cmd_ls])) {            strcpy(out_msg,"ls");            if (in_parm[0] != 0) {               strcat(out_msg," ");               strcat(out_msg,in_parm);            }            do_unix_command(out_msg);         } else if (!strcmp(in_msg,command_table[cmd_cmd])) {            do_unix_command(in_parm);         } else if ((!strcmp(in_msg,command_table[cmd_nil]))                 || (in_msg[0] == 0)) {            ;         } else {            tell_user(client_descriptor, "%3.3d - %s: %s", unknown_command,                      in_msg, out_table[unknown_command]);         }      } else {         tell_user(client_descriptor, "%3.3d - %s", input_too_long,                   out_table[input_too_long]);      }   }}#ifdef SOCDEMON_PASSWORDint check_pw(entered_pw, access_pw) char *entered_pw;char *access_pw;{ char salt[3]; char key[8]; char *encr_pw;   strncpy(key,entered_pw,8);   strncpy(salt,access_pw,2);   encr_pw = (char *) crypt(key,salt);   return strcmp(access_pw,encr_pw);}#endif /* SOCDEMON_PASSWORD *//* * soc_demon_welcome() *   - This routine prints up a bunch of greetings and identity info, *     all defined in socdemon.h, aswell as its real user id, effective user id *     real group id, effective group id, process id, and process group id. *     this is so you know what's going on on the server side of things. *     See socdemon.h for definitions of all the welcome strings. *   - Also, if the define 'SOCDEMON_PASSWORD' is not a nil string, *     then the user on the port will be prompted for a password, *     and allowed access only if the password is correct. *     The password is a compile time constant, and may not be changed other *     than by recompiling. The printing of the process id's etc. is *     held off until the user has successfully entered the password. *     see socdemon.h for the #define of SOCDEMON_PASSWORD.*/boolean soc_demon_welcome() { char hello_msg[HELLO_MSG_LEN]; int  hello_msg_len; char pword_str[MAX_INPUT_LEN]; int  pword_len;   report_version();#ifdef SOCDEMON_PASSWORD   if (strlen(SOCDEMON_PASSWORD) > 0) {      tell_user(client_descriptor, "Password? ");      pword_len = soc_read(client_descriptor, pword_str, MAX_INPUT_LEN);      if (pword_str[strlen(pword_str)-1] == '\n') {         pword_str[strlen(pword_str)-2] = 0;      }      if (check_pw(pword_str, SOCDEMON_PASSWORD)) {#ifdef LOG_TO_DEATH         strcpy(log_string,pword_str);         log_stuff(bad_password);#endif         tell_user(client_descriptor, "Access Denied.\n");         return false;      }   }#endif   return true;}/* * main() *   - This is the main procedure..

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -