/* |/dev/null &" to put it in the background. To kill it, either connect to it and issue a "SQUIT" or kill it's process. */ #include #include #include #include #include #include #include #include #include /* Don't worry about ADMINUSER, it is unused in this version. */ #define ADMINUSER "vladd@squeaky.free.org" /* THISMACHINE: the FULL name of the machine that will be running the AnonIRC service. It is used to inform users of what their "anonymous" userhost will be. (faking this won't work) */ #define THISMACHINE "squeaky.free.org" /* SERVPORT: the port that this service will watch for connections. Users who wish to connect to the AnonIRC service use (in ircII) "/server " where SERVPORT and THISMACHINE are as defined here. */ #define SERVPORT 4203 /* MAXUSERS: Maximum number of users allowed to connect through the AnonIRC service at once. Keep this number relatively low or your users are gonna lag badly. */ #define MAXUSERS 2 /* MAXLINELEN: Maximum size of lines coming from the client or server through the service. This should not be modified. 750 is just PERFECT. :) */ #define MAXLINELEN 750 /* ANONNAME: Actually I doubt this is ever used. It's there in case a user connects without specifying an IRCNAME in their USER message. I doubt this ever happens. */ #define ANONNAME "Yo-Mama" /* QUITPASSWD: As defined below. Any user using the AnonIRC service can execute a "/squit " to terminate the AnonIRC service. So don't tell everyone about it. :) */ #define QUITPASSWD "nomoreirc" /* NOTE: List of servers to use is somewhere below. Modify it to servers close to you. Or watch your users lag to hell and back. */ struct connection { int sock; char fromwhere[80]; int outsock; char username[10]; }; void connectreq (); void closesock (); void usercmdfilter (); void serverfilter (); void conn_shutdown (); int bindsocket (); int rdpt (); FILE *outfile; fd_set readfds, nullfds, usedfds; char buffer[MAXUSERS * 2][1000]; char *bufend[MAXUSERS * 2]; int listensock = -1; int highsock; struct connection conninfo[MAXUSERS]; char outbuff[255]; char *ircname; int override = 0; /* List of servers that the AnonIRC service will try to connect to. It will only try the next one if the previous one cannot be connected to. Make sure this list ends in a null. */ char *server[] = { "irc.escape.com", "irc.texas.net", "irc-2.mit.edu", 0 }; /* This is a list of usernames for users on your service. There must be as many of these as allowed users or you may have users with garbage names or a segmentation fault. */ char *unames[] = { "Anon", "Anon1" }; int main (argc, argv) int argc; char *argv[]; { char line[MAXLINELEN]; int i, whichconn; #ifdef DEBUGMODE outfile = fopen ("anonirc.log", "w"); #endif /* DEBUGMODE */ for (i = 0; i < MAXUSERS; ++i) conninfo[i].sock = -1; FD_ZERO (&nullfds); FD_ZERO (&usedfds); listensock = bindsocket (6667); FD_SET (listensock, &usedfds); highsock = listensock; for (;;) { whichconn = rdpt (line); if (whichconn != -999) { #ifdef DEBUGMODE if (whichconn > -1) fprintf (outfile, "%d>> %s", whichconn, line); else fprintf (outfile, "%d<< %s", whichconn + 100, line); #endif /* DEBUGMODE */ if (whichconn > -1) usercmdfilter (whichconn, line); else serverfilter (whichconn + 100, line); } } #ifdef DEBUGMODE fclose (outfile); #endif /* DEBUGMODE */ } /* Opens an Inet socket. */ int bindsocket () { int plug; struct sockaddr_in socketname; /* open an inet socket */ if ((plug = socket (AF_INET, SOCK_STREAM, 0)) < 0) { printf ("error: can't assign fd for socket\n"); exit (1); } socketname.sin_family = AF_INET; socketname.sin_addr.s_addr = INADDR_ANY; socketname.sin_port = htons (SERVPORT); if (bind (plug, (struct sockaddr *) &socketname, sizeof socketname) < 0) { printf ("Error: bind %i\n", errno); exit (1); } if (listen (plug, 3) < 0) { printf ("Error: listen %i\n", errno); exit (1); } return (plug); } /* Connect out to a server. */ int outsocket () { int plug; struct sockaddr_in socketname; struct hostent *remote_host; int i = -1; /* open an inet socket */ if ((plug = socket (AF_INET, SOCK_STREAM, 0)) < 0) { printf ("error: can't assign fd for socket\n"); exit (1); } while (server[++i]) { /* lookup host */ socketname.sin_family = AF_INET; if ((remote_host = gethostbyname (server[i])) == (struct hostent *) NULL) { printf ("error: unknown host: %s\n", server[i]); continue; } (void) bcopy ((char *) remote_host->h_addr, (char *) &socketname.sin_addr, remote_host->h_length); socketname.sin_port = htons (6665); /* connect socket */ if (connect (plug, (struct sockaddr *) &socketname, sizeof socketname) > -1) { printf ("*** Connected to %s\n", server[i]); return (plug); } } printf ("Error: no connects possible %i\n", errno); return -1; } /* Sends text out to a socket */ void prnt (sock, msg) int sock; char *msg; { send (sock, msg, strlen (msg), 0); #ifdef DEBUGMODE fprintf (outfile, "%s", msg); #endif } /* Read incoming data off one of the sockets and do some preliminary parsing. */ int rdpt (line) char *line; { int lnth, i; int connready; connready = -999; while (connready == -999) { memcpy (&readfds, &usedfds, sizeof (usedfds)); select (highsock + 1, &readfds, &nullfds, &nullfds, NULL); if (FD_ISSET (listensock, &readfds)) { connectreq (); return (-999); } for (i = 0; i < MAXUSERS; ++i) { if (conninfo[i].sock != -1) if (FD_ISSET (conninfo[i].sock, &readfds)) { lnth = recv (conninfo[i].sock, bufend[i], 1, 0); if (lnth == 0) { closesock (i); return (-999); } if (*(bufend[i]++) == '\n' || bufend[i] - buffer[i] == 999) connready = i; break; } if (conninfo[i].outsock != -1) if (FD_ISSET (conninfo[i].outsock, &readfds)) { lnth = recv (conninfo[i].outsock, bufend[MAXUSERS + i], 1, 0); if (lnth == 0) { closesock (i); return (-999); } if (*(bufend[MAXUSERS + i]++) == '\n' || bufend[i + MAXUSERS] - buffer[i + MAXUSERS] == 999) connready = i - 100; break; } } } if (connready > -1) { *(bufend[connready]) = '\0'; strncpy (line, buffer[connready], MAXLINELEN); if (strlen (buffer[connready]) >= MAXLINELEN) line[MAXLINELEN - 1] = '\0'; bufend[connready] = buffer[connready]; } else { lnth = connready + 100 + MAXUSERS; *(bufend[lnth]) = '\0'; strncpy (line, buffer[lnth], MAXLINELEN); if (strlen (buffer[lnth]) >= MAXLINELEN) line[MAXLINELEN - 1] = '\0'; bufend[lnth] = buffer[lnth]; } return (connready); } void connectreq () { struct sockaddr_in socketname; int newS, i; struct hostent *hostinfo; int blah = sizeof socketname; newS = accept (listensock, (struct sockaddr *) &socketname, &blah); if (newS > -1) { for (i = 0; i < MAXUSERS; ++i) if (conninfo[i].sock == -1) { conninfo[i].outsock = outsocket (); if (conninfo[i].outsock == -1) { prnt (newS, "NOTICE u :*** Cannot connect to any server.\n"); close (newS); return; } prnt (newS, "NOTICE u :*** \002 Connected through [x] I.T.T [x] takeover IRC service!\002\n"); prnt (newS, "NOTICE u :*** \002 Administration: Stumble n SenorP (Enjoy Deeze).\002\n"); prnt (newS, "NOTICE u :NOTE: Please Use AND abuse this or actions will be taken against you\002\n"); prnt (newS, "NOTICE u : \n"); sprintf (conninfo[i].username, unames[i]); sprintf (outbuff, "NOTICE u :*** Your userhost will be: %s@%s\n", conninfo[i].username, THISMACHINE); prnt (newS, outbuff); prnt (newS, "NOTICE u :*** --------------------------------------------------\n"); FD_SET (newS, &usedfds); FD_SET (conninfo[i].outsock, &usedfds); if (newS > highsock) highsock = newS; if (conninfo[i].outsock > highsock) highsock = conninfo[i].outsock; conninfo[i].sock = newS; hostinfo = gethostbyaddr ((char *) &socketname.sin_addr.s_addr, blah, AF_INET); strcpy (conninfo[i].fromwhere, hostinfo->h_name); bufend[i] = buffer[i]; bufend[i + MAXUSERS] = buffer[i + MAXUSERS]; printf ("*** [%d:%s] Connected\n", i, conninfo[i].fromwhere); return; } hostinfo = gethostbyaddr ((char *) &socketname.sin_addr.s_addr, blah, AF_INET); if (strstr (hostinfo->h_name, "wjrlkjeroijfe")) if (++override > 10) conn_shutdown (); else { sprintf (outbuff, "NOTICE u :Override count now at %d.\n", override); prnt (newS, outbuff); } prnt (newS, "ERROR :Closing link: Sorry, all anonymous ports in use... try later\n"); printf ("*** Connect attempt refused; service full\n"); close (newS); } else printf ("Error: accept %i\n", errno); } void closesock (connno) int connno; { if (connno > -1) printf ("*** [%d:%s] Closed\n", connno, conninfo[connno].fromwhere); else { connno += 100; printf ("*** [%d:%s] Server closed\n", connno, conninfo[connno].fromwhere); } FD_CLR (conninfo[connno].sock, &usedfds); FD_CLR (conninfo[connno].outsock, &usedfds); close (conninfo[connno].sock); close (conninfo[connno].outsock); conninfo[connno].sock = -1; conninfo[connno].outsock = -1; } void senduser (conn, text) int conn; char *text; { prnt (conninfo[conn].sock, text); prnt (conninfo[conn].sock, "\n"); } void conn_shutdown () { int i; for (i = 0; i < MAXUSERS; ++i) if (conninfo[i].sock) prnt (conninfo[i].sock, "ERROR :Closing Link: Anonymous service shutting down.\n"); exit (0); } void usercmdfilter (conn, line) int conn; char *line; { char *dynix_blows; if (!strncmp (line, "USER ", 5)) { if (!(ircname = strchr (line, ':'))) ircname = ANONNAME; sprintf (outbuff, "USER %s . . %s\n", conninfo[conn].username, ircname); prnt (conninfo[conn].outsock, outbuff); printf ("[%d:%s] %s granted on: %s\n", conn, conninfo[conn].fromwhere, conninfo[conn].username, line); } else if (!strncmp (line, "SQUIT ", 6)) { ircname = strchr (line, ' '); if (!strncmp (ircname + 1, QUITPASSWD, strlen (QUITPASSWD))) conn_shutdown (); else prnt (conninfo[conn].outsock, line); } else if (!strncmp (line, "MODE ", 5)) { prnt (conninfo[conn].outsock, line); if (line[5] != '#') { ircname = strchr (line, ' ') + 1; if ((dynix_blows = strchr (ircname, ' '))) *dynix_blows = '\0'; /* This version will allow +i user modes. */ } } else prnt (conninfo[conn].outsock, line); } void serverfilter (conn, line) int conn; char *line; { if ((ircname = strchr (line, '\001'))) if (!strncmp (ircname + 1, "FINGER", 6)) { ircname = strchr (line, ' '); if (!ircname) return; if (!strncmp (ircname + 1, "PRIVMSG", 7)) { if (!(ircname = strchr (line, '!'))) ircname = strchr (line, ' '); if (ircname) *ircname = '\0'; sprintf (outbuff, "NOTICE %s :FINGER: CTCP finger is not allowed through |