home *** CD-ROM | disk | FTP | other *** search
/ The Hacker's Encyclopedia 1998 / hackers_encyclopedia.iso / hacking / internet / telbounc.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-06-11  |  8.8 KB  |  277 lines

  1. /* Subject: general purpose telnet server.
  2. This is a telnet bouncer that some people have expressed interest in.
  3. It's uses are utility and privacy related. It should compile easily on
  4. most OS's striaght out of it's wrapper as such.
  5.  
  6. Mark
  7. mark@cairo.anu.edu.au
  8. */
  9. /* Name: ts2.c */
  10. /* Author: Hal-9000, Xanadude, Richard Stevens, Avalon, Mark */
  11. /* Distribution: Public */
  12. /* Copyright: Held by the respective contributors */
  13. /* Posted to USENET September '93 by Mark mark@cairo.anu.edu.au */
  14.  
  15. /* This file was telserv.c, part of the Telnet Server package v. 1.0,
  16.      written by "Hal-9000". Much of that package was developed by Richard
  17.      Stephens and his thanks go to "Xanadude" for providing him with that
  18.      section. Performance fix by Darren Reed. */
  19.  
  20. /* Reworked to add concurrency, password checking and destination selection
  21.    on the fly. - Mark 31st Aug 93
  22.  
  23.    Compiled and tested on:
  24.        HPUX 9.01 9000/700 series        NeXTStep 3.1 NeXT 68040
  25.        OSx Pyramid 90x BSD universe     SunOS 5.2 sun4c
  26.        Ultrix 4.3 DEC RISC              Linux 0.99.10 80486
  27.  
  28.    To compile, type "cc -O -s ts2.c -o ts2".
  29.  
  30.    MY_PASSWORD and SERV_TCP_PORT are all that is required to be altered. */
  31.  
  32. #define    MY_PASSWORD    "bollox"
  33. #define    SERV_TCP_PORT  9090    /* port I'll listen for connections on */
  34.  
  35. #include <stdio.h>
  36. #include <sys/types.h>
  37. #include <sys/socket.h>
  38. #include <sys/time.h>
  39. #include <sys/resource.h>
  40. #include <sys/wait.h>
  41. #include <fcntl.h>
  42. #include <errno.h>
  43. #include <netinet/in.h>
  44. #include <netdb.h>
  45. #include <arpa/inet.h>
  46. #include <sys/ioctl.h>
  47.  
  48. #define    QLEN           5
  49.  
  50. char sbuf[2048], cbuf[2048];
  51. extern int errno;
  52. extern char *sys_errlist[];
  53. void reaper();
  54. int main();
  55. void telcli();
  56.  
  57. int main(argc, argv)
  58. int argc;
  59. char *argv[];
  60. {
  61.     int srv_fd, rem_fd, rem_len, opt = 1;
  62.     struct sockaddr_in rem_addr, srv_addr;
  63. #if !defined(SVR4) && !defined(POSIX) && !defined(linux) && !defined(__386BSD__) && !defined(hpux)
  64.     union wait status;
  65. #else
  66.     int    status;
  67. #endif /* !defined(SVR4) */
  68.  
  69.     bzero((char *) &rem_addr, sizeof(rem_addr));
  70.     bzero((char *) &srv_addr, sizeof(srv_addr));
  71.     srv_addr.sin_family = AF_INET;
  72.     srv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  73.     srv_addr.sin_port = htons(SERV_TCP_PORT);
  74.     srv_fd = socket(PF_INET, SOCK_STREAM, 0);
  75.     if (bind(srv_fd, (struct sockaddr *) &srv_addr, sizeof(srv_addr)) == -1) {
  76.         perror("bind");
  77.         exit(-1);
  78.     }
  79.     listen(srv_fd, QLEN);
  80.     close(0); close(1); close(2);
  81. #ifdef TIOCNOTTY
  82.     if ((rem_fd = open("/dev/tty", O_RDWR)) >= 0) {
  83.         ioctl(rem_fd, TIOCNOTTY, (char *)0);
  84.         close(rem_fd);
  85.     }
  86. #endif
  87.     if (fork()) exit(0);
  88.     while (1) {
  89.     rem_len = sizeof(rem_addr);
  90.         rem_fd=accept(srv_fd, (struct sockaddr *) &rem_addr, &rem_len);
  91.         if (rem_fd < 0) {
  92.             if (errno == EINTR) continue;
  93.             exit(-1);
  94.         }
  95.         switch(fork()) {
  96.         case 0:                             /* child process */
  97.             close(srv_fd);                  /* close original socket */
  98.             telcli(rem_fd);                 /* process the request */
  99.             close(rem_fd);
  100.             exit(0);
  101.             break;
  102.         default: 
  103.             close(rem_fd);                  /* parent process */
  104.             if (fork()) exit(0);            /* let init worry about children */
  105.             break;
  106.         case -1:
  107.             fprintf(stderr, "\n\rfork: %s\n\r", sys_errlist[errno]);
  108.             break;
  109.         }
  110.     }
  111. }
  112.  
  113. void telcli(source)
  114. int source;
  115. {
  116.     int dest;
  117.     int found;
  118.     struct sockaddr_in sa;
  119.     struct hostent *hp;
  120.     struct servent *sp;
  121.     char gethost[100];
  122.     char getport[100];
  123.     char string[100];
  124.  
  125.     bzero(gethost, 100);
  126.     sprintf(string, "Password: ");
  127.     write(source, string, strlen(string));
  128.     read(source, gethost, 100);
  129.     gethost[(strlen(gethost)-2)] = '\0'; /* kludge alert - kill the \r\n */
  130.     if (strcmp(gethost, MY_PASSWORD) != 0) {
  131.         sprintf(string, "Wrong password, got %s.\n", gethost);
  132.         write(source, string, strlen(string));
  133.         close(source);
  134.         exit(0);
  135.     }
  136.     do {
  137.         found = 0;
  138.         bzero(gethost,100);
  139.         sprintf(string, "Host: ");
  140.         write(source, string, strlen(string));
  141.         read(source, gethost, 100);
  142.         gethost[(strlen(gethost)-2)] = '\0';
  143.         hp = gethostbyname(gethost);
  144.         if (hp) {
  145.             found++;
  146. #if !defined(h_addr)        /* In 4.3, this is a #define */
  147. #if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
  148.             memcpy((caddr_t)&sa.sin_addr, hp->h_addr_list[0], hp->h_length);
  149. #else
  150.             bcopy(hp->h_addr_list[0], &sa.sin_addr, hp->h_length);
  151. #endif
  152. #else /* defined(h_addr) */
  153. #if defined(hpux) || defined(NeXT) || defined(ultrix) || defined(POSIX)
  154.             memcpy((caddr_t)&sa.sin_addr, hp->h_addr, hp->h_length);
  155. #else
  156.             bcopy(hp->h_addr, &sa.sin_addr, hp->h_length);
  157. #endif
  158. #endif /* defined(h_addr) */
  159.             sprintf(string, "Found address for %s\n", hp->h_name);
  160.             write(source, string, strlen(string));
  161.         } else {
  162.             if (inet_addr(gethost) == -1) {
  163.                 found = 0;
  164.                 sprintf(string, "Didnt find address for %s\n", gethost);
  165.                 write(source, string, strlen(string));
  166.             } else {
  167.                 found++;
  168.                 sa.sin_addr.s_addr = inet_addr(gethost);
  169.             }
  170.         }
  171.     } while (!found);
  172.     sa.sin_family = AF_INET;
  173.     sprintf(string, "Port: ");
  174.     write(source, string, strlen(string));
  175.     read(source, getport, 100);
  176.     gethost[(strlen(getport)-2)] = '\0';
  177.     sa.sin_port = htons((unsigned) atoi(getport));
  178.     if (sa.sin_port == 0) {
  179.         sp = getservbyname(getport, "tcp");
  180.         if (sp)
  181.             sa.sin_port = sp->s_port;
  182.         else {
  183.             sprintf(string, "%s: bad port number\n", getport);
  184.             write(source, string, strlen(string));
  185.             return;
  186.         }
  187.     }
  188.     sprintf(string, "Trying %s...\n", (char *) inet_ntoa(sa.sin_addr));
  189.     write(source, string, strlen(string));
  190.     if ((dest = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  191.         perror("telcli: socket");
  192.         exit(1);
  193.     }
  194.     connect(dest, (struct sockaddr *) &sa, sizeof(sa));
  195.     sprintf(string, "Connected to %s port %d...\n", inet_ntoa(sa.sin_addr),
  196.                                                           ntohs(sa.sin_port));
  197.     write(source, string, strlen(string));
  198. #ifdef FNDELAY
  199.     fcntl(source,F_SETFL,fcntl(source,F_GETFL,0)|FNDELAY);
  200.     fcntl(dest,F_SETFL,fcntl(dest,F_GETFL,0)|FNDELAY);
  201. #else
  202.     fcntl(source,F_SETFL,O_NDELAY);
  203.     fcntl(dest,F_SETFL,O_NDELAY);
  204. #endif
  205.     communicate(dest,source);
  206.     close(dest);
  207.     exit(0);
  208. }
  209.  
  210. communicate(sfd,cfd)    {
  211.     char *chead, *ctail, *shead, *stail;
  212.     int num, nfd, spos, cpos;
  213.     extern int errno;
  214.     fd_set rd, wr;
  215.  
  216.     chead = ctail = cbuf;
  217.     cpos = 0;
  218.     shead = stail = sbuf;
  219.     spos = 0;
  220.     while (1) {
  221.         FD_ZERO(&rd);
  222.         FD_ZERO(&wr);
  223.         if (spos < sizeof(sbuf)-1) FD_SET(sfd, &rd);
  224.         if (ctail > chead) FD_SET(sfd, &wr);
  225.         if (cpos < sizeof(cbuf)-1) FD_SET(cfd, &rd);
  226.         if (stail > shead) FD_SET(cfd, &wr);
  227.         nfd = select(256, &rd, &wr, 0, 0);
  228.         if (nfd <= 0) continue;
  229.         if (FD_ISSET(sfd, &rd)) {
  230.             num=read(sfd,stail,sizeof(sbuf)-spos);
  231.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  232.             if (num==0) return;
  233.             if (num>0) {
  234.                 spos += num;
  235.                 stail += num;
  236.                 if (!--nfd) continue;
  237.             }
  238.         }
  239.         if (FD_ISSET(cfd, &rd)) {
  240.             num=read(cfd,ctail,sizeof(cbuf)-cpos);
  241.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  242.             if (num==0) return;
  243.             if (num>0) {
  244.                 cpos += num;
  245.                 ctail += num;
  246.                 if (!--nfd) continue;
  247.             }
  248.         }
  249.         if (FD_ISSET(sfd, &wr)) {
  250.             num=write(sfd,chead,ctail-chead);
  251.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  252.             if (num>0) {
  253.                 chead += num;
  254.                 if (chead == ctail) {
  255.                     chead = ctail = cbuf;
  256.                     cpos = 0;
  257.                 }
  258.                 if (!--nfd) continue;
  259.             }
  260.         }
  261.         if (FD_ISSET(cfd, &wr)) {
  262.             num=write(cfd,shead,stail-shead);
  263.             if ((num==-1) && (errno != EWOULDBLOCK)) return;
  264.             if (num>0) {
  265.                 shead += num;
  266.                 if (shead == stail) {
  267.                     shead = stail = sbuf;
  268.                     spos = 0;
  269.                 }
  270.                 if (!--nfd) continue;
  271.             }
  272.         }
  273.     }
  274. }
  275.  
  276.  
  277.