diff -crN ../ircu2.10.06-DBH7/CAMBIOS ../ircu2.10.06-DBH7-noproxy/CAMBIOS *** ../ircu2.10.06-DBH7/CAMBIOS Wed Jul 21 11:36:39 1999 --- ../ircu2.10.06-DBH7-noproxy/CAMBIOS Wed Jul 28 16:05:25 1999 *************** *** 1,3 **** --- 1,34 ---- + * 1999/07/28 savage@apostols.org (patch.noproxy) + ----------------------------------------------------------------------- + Implemento un checker de Socks4-Proxies (wingates incluido). + La implementación esta en s_socks.c y s_socks.h, pero ha sido necesario + tocar ligeramente s_bsd.c, ircd.c y s_res.c. En la estructura Client de + struct.h he añadido el campo socksfd en la parte extendida de clientes + locales. En s_bsd.h he creado las macros y usado un par de bits del + campo client->hmodes. + + Implementacion: + + - Llega conexion nueva + - Se lanzan en paralelo los checkers de DNS, ident y proxy + - Se atiende al user cuando los tres han finalizado + + Cuando lanzamos el cheker de proxy, este se intenta conectar al puerto + de socks4 del usuario (1080), si lo consigue, mediante protocolo socks4 + le solicita al proxy que habra una conexion a la direccion/puerto del + ircd que el usuario ha conectado. Se analiza la respuesta de socks4 y + si nos confirma la conexión, es un proxy abiero y lo desconectamos del + irc informandole de la causa. + + Mientras se hace el proceso de checking de Proxy, el server envia unos + NOTICE al usuario para que vea lo que le está haciendo. He tenido que + usar writes directos al cptr->fd, pk al no estar registrado el usuario + en el momento del cheking, no podia usar las colas de salida. + + Esta opcion se puede activar/desactivar (PROXY_PROTECTION) en el make + config, siempre que hayamos seleccionado DB_HISPANO. Queda reflejado + en el /VERSION como PX+ o PX- + * 1999/07/21 savage@apostols.org (patch.DBH6) ----------------------------------------------------------------------- Cambia la forma de trabajo del flag +r, impidiendo que el user diff -crN ../ircu2.10.06-DBH7/config/config-sh.in ../ircu2.10.06-DBH7-noproxy/config/config-sh.in *** ../ircu2.10.06-DBH7/config/config-sh.in Wed Jul 21 11:36:36 1999 --- ../ircu2.10.06-DBH7-noproxy/config/config-sh.in Wed Jul 28 04:00:02 1999 *************** *** 366,371 **** --- 366,372 ---- bool 'HISPANO: OPER_DB features only on registered (CHAN_DB) channels' DBH_OPER_HACK_ONLYREG y bool 'HISPANO: OPER_DB members can be Chanserv (+k)' DBH_OPER_HACK_KMODE y fi + bool 'Proteccion contra Wingates y Socks4 proxies' PROXY_PROTECTION y fi bool 'XMODE Networking - ESNET' XMODE_ESNET y bool 'ESNET Distributed DataBase Support - ESNET' DB_ESNET y diff -crN ../ircu2.10.06-DBH7/doc/Configure.help ../ircu2.10.06-DBH7-noproxy/doc/Configure.help *** ../ircu2.10.06-DBH7/doc/Configure.help Wed Jul 21 11:36:35 1999 --- ../ircu2.10.06-DBH7-noproxy/doc/Configure.help Wed Jul 28 15:32:21 1999 *************** *** 1150,1152 **** --- 1150,1164 ---- para evitar ser KICK, DEOP y las flood si hemos aplicado el parche de CS_NO_FLOOD_ESNET + Proteccion contra Wingates y Socks4 proxies + PROXY_PROTECTION + Si activamos esta opción, el servidor de irc se asegurará de que + ningun usuario con Wingate o Socks4 abiertos pueda entrar. + El servidor iniciará una conexión contra el puerto 1080 del usuario + pidiendo que le abra una conexion contra nosotros mismo, si lo consigue + expulsa al usuario, si no es así, lo deja entrar. Esto no suele retrasar + el tiempo de conexión del usuario, pues se hace en paralelo a la busqueda + de DNS y conexion al ident (113). + En cuanto el usuario conecta se le presenta un texto informando de lo + que se intenta hacer, y si es aceptable o no. + diff -crN ../ircu2.10.06-DBH7/include/s_bsd.h ../ircu2.10.06-DBH7-noproxy/include/s_bsd.h *** ../ircu2.10.06-DBH7/include/s_bsd.h Wed Jul 21 11:36:36 1999 --- ../ircu2.10.06-DBH7-noproxy/include/s_bsd.h Wed Jul 28 04:46:56 1999 *************** *** 186,191 **** --- 186,193 ---- /* Bits de los modos hispano */ #define HMODE_NICKREGISTERED 0x00000001 /* Nick is registered (HISPANO/ESNET) */ + #define HMODE_SOCKS 0x00000004 /* se esta chekeando socks */ + #define HMODE_WRSOCKS 0x00000008 /* se tiene ke escribir en socks */ /* Modos hispano a propagar */ #define SEND_HMODES \ *************** *** 197,208 **** --- 199,216 ---- /* Macros comprobacion modos hispano */ #define IsNickRegistered(x) ((x)->hmodes & HMODE_NICKREGISTERED) + #define DoingSocks(x) ((x)->hmodes & HMODE_SOCKS) + #define DoingWrSocks(x) ((x)->hmodes & HMODE_WRSOCKS) /* Macros para poner modos hispano */ #define SetNickRegistered(x) ((x)->hmodes |= HMODE_NICKREGISTERED) + #define SetSocks(x) ((x)->hmodes |= HMODE_SOCKS) + #define SetWrSocks(x) ((x)->hmodes |= HMODE_WRSOCKS) /* Macros para borrar modos hispano */ #define ClearNickRegistered(x) ((x)->hmodes &= ~HMODE_NICKREGISTERED) + #define ClearSocks(x) ((x)->hmodes &= ~HMODE_SOCKS) + #define ClearWrSocks(x) ((x)->hmodes &= ~HMODE_WRSOCKS) #endif /* DB_HISPANO || DB_ESNET */ diff -crN ../ircu2.10.06-DBH7/include/s_socks.h ../ircu2.10.06-DBH7-noproxy/include/s_socks.h *** ../ircu2.10.06-DBH7/include/s_socks.h Thu Jan 1 01:00:00 1970 --- ../ircu2.10.06-DBH7-noproxy/include/s_socks.h Wed Jul 28 04:00:02 1999 *************** *** 0 **** --- 1,23 ---- + #ifndef S_SOCKS_H + #define S_SOCKS_H + + /*============================================================================= + * SOCKS4 / SOCKS4A pks + */ + struct socks4 { + unsigned char vn; + unsigned char cd; + unsigned short dstport; + unsigned int dstip; + }; + + + /*============================================================================= + * Proto types + */ + + extern void start_socks(aClient *cptr); + extern void send_socksports(aClient *cptr); + extern void read_socksports(aClient *cptr); + + #endif /* S_SOCKS_H */ diff -crN ../ircu2.10.06-DBH7/include/struct.h ../ircu2.10.06-DBH7-noproxy/include/struct.h *** ../ircu2.10.06-DBH7/include/struct.h Wed Jul 21 11:36:38 1999 --- ../ircu2.10.06-DBH7-noproxy/include/struct.h Wed Jul 28 04:00:02 1999 *************** *** 112,117 **** --- 112,120 ---- struct Client *acpt; /* listening client which we accepted from */ struct SLink *confs; /* Configuration record associated */ int authfd; /* fd for rfc931 authentication */ + #ifdef PROXY_PROTECTION + int socksfd; /* fd for socks4/wingate detection */ + #endif unsigned short int port; /* and the remote port# too :-) */ struct hostent *hostp; struct ListingArgs *listing; diff -crN ../ircu2.10.06-DBH7/ircd/Makefile.in ../ircu2.10.06-DBH7-noproxy/ircd/Makefile.in *** ../ircu2.10.06-DBH7/ircd/Makefile.in Wed Jul 21 11:36:29 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/Makefile.in Wed Jul 28 04:00:02 1999 *************** *** 62,68 **** list.o map.o match.o numnicks.o opercmds.o packet.o parse.o querycmds.o \ random.o res.o runmalloc.o s_auth.o s_bsd.o s_conf.o s_debug.o s_err.o \ s_misc.o s_numeric.o s_ping.o s_serv.o s_user.o send.o sprintf_irc.o \ ! support.o userload.o whocmds.o whowas.o hash.o SRC=${OBJS:%.o=%.c} --- 62,68 ---- list.o map.o match.o numnicks.o opercmds.o packet.o parse.o querycmds.o \ random.o res.o runmalloc.o s_auth.o s_bsd.o s_conf.o s_debug.o s_err.o \ s_misc.o s_numeric.o s_ping.o s_serv.o s_user.o send.o sprintf_irc.o \ ! support.o userload.o whocmds.o whowas.o hash.o s_socks.o SRC=${OBJS:%.o=%.c} *************** *** 472,474 **** --- 472,481 ---- ../include/numeric.h ../include/send.h ../include/s_misc.h \ ../include/s_err.h ../include/ircd.h ../include/list.h \ ../include/s_user.h ../include/support.h + s_socks.o: s_socks.c ../include/sys.h ../include/../config/config.h \ + ../include/../config/setup.h ../include/runmalloc.h ../include/h.h \ + ../include/s_debug.h ../include/res.h ../include/list.h \ + ../include/struct.h ../include/dbuf.h ../include/whowas.h \ + ../include/common.h ../include/send.h ../include/s_bsd.h \ + ../include/s_conf.h ../include/s_misc.h ../include/support.h \ + ../include/ircd.h ../include/s_socks.h ../include/sprintf_irc.h diff -crN ../ircu2.10.06-DBH7/ircd/ircd.c ../ircu2.10.06-DBH7-noproxy/ircd/ircd.c *** ../ircu2.10.06-DBH7/ircd/ircd.c Wed Jul 21 11:36:32 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/ircd.c Wed Jul 28 05:46:22 1999 *************** *** 345,354 **** --- 345,362 ---- (!IsRegistered(cptr) && !IsHandshake(cptr) && (now - cptr->firsttime) >= ping)) { + #ifdef PROXY_PROTECTION + if (!IsRegistered(cptr) && (DoingDNS(cptr) || DoingAuth(cptr) || DoingSocks(cptr))) + { + Debug((DEBUG_NOTICE, "%s/%s/%s timeout %s", DoingDNS(cptr) ? "DNS" : "", + DoingAuth(cptr) ? "AUTH" : "", DoingSOCKS(cptr) ? "SOCKS" : "", + get_client_name(cptr, TRUE))); + #else if (!IsRegistered(cptr) && (DoingDNS(cptr) || DoingAuth(cptr))) { Debug((DEBUG_NOTICE, "%s/%s timeout %s", DoingDNS(cptr) ? "DNS" : "", DoingAuth(cptr) ? "AUTH" : "", get_client_name(cptr, TRUE))); + #endif if (cptr->authfd >= 0) { close(cptr->authfd); *************** *** 359,365 **** del_queries((char *)cptr); ClearAuth(cptr); ClearDNS(cptr); ! SetAccess(cptr); cptr->firsttime = now; cptr->lasttime = now; continue; --- 367,382 ---- del_queries((char *)cptr); ClearAuth(cptr); ClearDNS(cptr); ! #ifdef PROXY_PROTECTION ! if (cptr->socksfd >= 0) ! { ! close(cptr->socksfd); ! cptr->socksfd = -1; ! } ! ClearSocks(cptr); ! ClearWrSocks(cptr); ! #endif ! SetAccess(cptr); cptr->firsttime = now; cptr->lasttime = now; continue; *************** *** 895,900 **** --- 912,920 ---- now = time(NULL); me.hopcount = 0; me.authfd = -1; + #ifdef PROXY_PROTECTION + me.socksfd = -1; + #endif me.confs = NULL; me.next = NULL; me.user = NULL; diff -crN ../ircu2.10.06-DBH7/ircd/list.c ../ircu2.10.06-DBH7-noproxy/ircd/list.c *** ../ircu2.10.06-DBH7/ircd/list.c Wed Jul 21 11:36:32 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/list.c Wed Jul 28 05:47:13 1999 *************** *** 111,116 **** --- 111,119 ---- cptr->nextnick = now - NICK_DELAY; cptr->nexttarget = now - (TARGET_DELAY * (STARTTARGETS - 1)); cptr->authfd = -1; + #ifdef PROXY_PROTECTION + cptr->socksfd = -1; + #endif } return (cptr); } diff -crN ../ircu2.10.06-DBH7/ircd/res.c ../ircu2.10.06-DBH7-noproxy/ircd/res.c *** ../ircu2.10.06-DBH7/ircd/res.c Wed Jul 21 11:36:33 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/res.c Wed Jul 28 04:00:02 1999 *************** *** 358,365 **** { case ASYNC_CLIENT: ClearDNS(cptr); ! if (!DoingAuth(cptr)) ! SetAccess(cptr); break; case ASYNC_PING: sendto_ops("Host %s unknown", rptr->name); --- 358,369 ---- { case ASYNC_CLIENT: ClearDNS(cptr); ! #ifdef PROXY_PROTECTION ! if (!DoingAuth(cptr) && !DoingSocks(cptr)) ! #else ! if (!DoingAuth(cptr)) ! #endif ! SetAccess(cptr); break; case ASYNC_PING: sendto_ops("Host %s unknown", rptr->name); diff -crN ../ircu2.10.06-DBH7/ircd/s_auth.c ../ircu2.10.06-DBH7-noproxy/ircd/s_auth.c *** ../ircu2.10.06-DBH7/ircd/s_auth.c Thu Jan 21 03:47:25 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/s_auth.c Wed Jul 28 04:00:02 1999 *************** *** 87,94 **** #endif Debug((DEBUG_ERROR, "Unable to create auth socket for %s:%s", get_client_name(cptr, TRUE), strerror(get_sockerr(cptr)))); if (!DoingDNS(cptr)) ! SetAccess(cptr); ircstp->is_abad++; return; } --- 87,98 ---- #endif Debug((DEBUG_ERROR, "Unable to create auth socket for %s:%s", get_client_name(cptr, TRUE), strerror(get_sockerr(cptr)))); + #ifdef PROXY_PROTECTION + if (!DoingDNS(cptr) && !DoingSocks(cptr)) + #else if (!DoingDNS(cptr)) ! #endif /* PROXY_PROTECTION */ ! SetAccess(cptr); ircstp->is_abad++; return; } *************** *** 125,132 **** alarm((unsigned)0); close(cptr->authfd); cptr->authfd = -1; if (!DoingDNS(cptr)) ! SetAccess(cptr); return; } alarm((unsigned)0); --- 129,140 ---- alarm((unsigned)0); close(cptr->authfd); cptr->authfd = -1; + #ifdef PROXY_PROTECTION + if (!DoingDNS(cptr) && !DoingSocks(cptr)) + #else if (!DoingDNS(cptr)) ! #endif /* PROXY_PROTECTION */ ! SetAccess(cptr); return; } alarm((unsigned)0); *************** *** 179,186 **** highest_fd--; cptr->authfd = -1; cptr->flags &= ~FLAGS_AUTH; if (!DoingDNS(cptr)) ! SetAccess(cptr); } cptr->flags &= ~FLAGS_WRAUTH; return; --- 187,198 ---- highest_fd--; cptr->authfd = -1; cptr->flags &= ~FLAGS_AUTH; + #ifdef PROXY_PROTECTION + if (!DoingDNS(cptr) && !DoingSocks(cptr)) + #else if (!DoingDNS(cptr)) ! #endif /* PROXY_PROTECTION */ ! SetAccess(cptr); } cptr->flags &= ~FLAGS_WRAUTH; return; *************** *** 250,257 **** cptr->count = 0; cptr->authfd = -1; ClearAuth(cptr); if (!DoingDNS(cptr)) ! SetAccess(cptr); if (len > 0) Debug((DEBUG_INFO, "ident reply: [%s]", cptr->buffer)); --- 262,273 ---- cptr->count = 0; cptr->authfd = -1; ClearAuth(cptr); + #ifdef PROXY_PROTECTION + if (!DoingDNS(cptr) && !DoingSocks(cptr)) + #else if (!DoingDNS(cptr)) ! #endif /* PROXY_PROTECTION */ ! SetAccess(cptr); if (len > 0) Debug((DEBUG_INFO, "ident reply: [%s]", cptr->buffer)); diff -crN ../ircu2.10.06-DBH7/ircd/s_bsd.c ../ircu2.10.06-DBH7-noproxy/ircd/s_bsd.c *** ../ircu2.10.06-DBH7/ircd/s_bsd.c Wed Jul 21 11:36:33 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/s_bsd.c Wed Jul 28 05:50:14 1999 *************** *** 90,95 **** --- 90,98 ---- #include "sprintf_irc.h" #include "querycmds.h" #include "IPcheck.h" + #ifdef PROXY_PROTECTION + #include "s_socks.h" + #endif #ifdef DB_HISPANO #include "msg.h" *************** *** 1021,1029 **** } } #endif /* DB_HISPANO */ ! if (!IsDead(cptr)) start_auth(cptr); return (IsDead(cptr)) ? -1 : 0; } --- 1024,1039 ---- } } #endif /* DB_HISPANO */ ! ! #ifdef PROXY_PROTECTION ! if (!IsDead(cptr)) { ! start_auth(cptr); ! start_socks(cptr); ! } ! #else if (!IsDead(cptr)) start_auth(cptr); + #endif return (IsDead(cptr)) ? -1 : 0; } *************** *** 1109,1114 **** --- 1119,1129 ---- if (cptr->authfd >= 0) close(cptr->authfd); + #ifdef PROXY_PROTECTION + if (cptr->socksfd >= 0) + close(cptr->socksfd); + #endif + if (cptr->fd >= 0) { flush_connections(cptr->fd); *************** *** 1395,1400 **** --- 1410,1418 ---- } start_auth(acptr); + #ifdef PROXY_PROTECTION + start_socks(acptr); + #endif return acptr; } *************** *** 1677,1682 **** --- 1695,1703 ---- unsigned long timeout; int added; #endif /* USE_POLL */ + #ifdef PROXY_PROTECTION + int socks = 0; + #endif /* PROXY_PROTECTION */ #ifdef pyr gettimeofday(&nowt, NULL); *************** *** 1706,1711 **** --- 1727,1742 ---- if (cptr->flags & FLAGS_WRAUTH) RWFD_SET(cptr->authfd, &write_set, currfd_index); } + #ifdef PROXY_PROTECTION + if (DoingSocks(cptr)) + { + socks++; + Debug((DEBUG_NOTICE, "socks on %p %d", cptr, i)); + RFD_SET(cptr->socksfd, &read_set, currfd_index, cptr); + if (DoingWrSocks(cptr)) + RWFD_SET(cptr->socksfd, &write_set, currfd_index); + } + #endif /* PROXY_PROTECTION */ if (IsPing(cptr)) { ping++; *************** *** 1728,1734 **** --- 1759,1769 ---- #endif /* USE_POLL */ continue; } + #ifdef PROXY_PROTECTION + if (DoingDNS(cptr) || DoingAuth(cptr) || DoingSocks(cptr)) + #else if (DoingDNS(cptr) || DoingAuth(cptr)) + #endif /* PROXY_PROTECTION */ { #ifdef USE_POLL if (added) *************** *** 1874,1879 **** --- 1909,1939 ---- read_authports(cptr); } } + #ifdef PROXY_PROTECTION + /* + * Check fd sets for the socks fd's (if set and valid!) first + * because these can not be processed using the normal loops below. + * -savage + */ + for (i = HIGHEST_INDEX; (socks > 0) && (i >= 0); i--) + { + if (!(cptr = LOC_CLIENTS(i))) + continue; + if (cptr->socksfd < 0) + continue; + auth--; + if ((nfds > 0) && WFD_ISSET(cptr->socksfd, &write_set, i)) + { + nfds--; + send_socksports(cptr); + } + else if ((nfds > 0) && RFD_ISSET(cptr->socksfd, &read_set, i)) + { + nfds--; + read_socksports(cptr); + } + } + #endif /* PROXY_PROTECTION */ for (i = HIGHEST_INDEX; i >= 0; i--) if ((cptr = LOC_CLIENTS(i)) && RFD_ISSET(i, &read_set, i) && IsListening(cptr)) diff -crN ../ircu2.10.06-DBH7/ircd/s_debug.c ../ircu2.10.06-DBH7-noproxy/ircd/s_debug.c *** ../ircu2.10.06-DBH7/ircd/s_debug.c Wed Jul 28 04:08:56 1999 --- ../ircu2.10.06-DBH7-noproxy/ircd/s_debug.c Wed Jul 28 16:03:51 1999 *************** *** 218,223 **** --- 218,230 ---- #else '-', #endif + 'P','X', + #ifdef PROXY_PROTECTION + '+', + #else + '-', + #endif + #endif /* DB_HISPANO */ '\0' }; diff -crN ../ircu2.10.06-DBH7/ircd/s_socks.c ../ircu2.10.06-DBH7-noproxy/ircd/s_socks.c *** ../ircu2.10.06-DBH7/ircd/s_socks.c Thu Jan 1 01:00:00 1970 --- ../ircu2.10.06-DBH7-noproxy/ircd/s_socks.c Wed Jul 28 15:18:21 1999 *************** *** 0 **** --- 1,257 ---- + /* + * IRC - Internet Relay Chat, ircd/s_auth.c + * Copyright (C) 1992 Darren Reed + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + #include "sys.h" + #include + #if HAVE_SYS_FILE_H + #include + #endif + #if HAVE_SYS_IOCTL_H + #include + #endif + #ifdef UNIXPORT + #include + #endif + #if HAVE_UNISTD_H + #include + #endif + #ifdef HPUX + #include + #endif /* HPUX */ + #if HAVE_FCNTL_H + #include + #endif + #ifdef USE_SYSLOG + #include + #endif + #include + #include + + #include "h.h" + #include "res.h" + #include "struct.h" + #include "common.h" + #include "send.h" + #include "s_bsd.h" + #include "s_misc.h" + #include "support.h" + #include "ircd.h" + #include "s_socks.h" + #include "sprintf_irc.h" + + RCSTAG_CC("$Id: s_socks4.c,v 1.00 1999/07/27 02:47:25 savage Exp $"); + + /* + * start_socks + * + * Flag the client to show that an attempt to contact the socks server on + * the client's host. The connect and subsequently the socket are all put + * into 'non-blocking' mode. + */ + void start_socks(aClient *cptr) + { + struct sockaddr_in sock; + int err; + char text[1024]; + + Debug((DEBUG_NOTICE, "start_socks(%p) fd %d status %d", + cptr, cptr->fd, cptr->status)); + + alarm(2); + cptr->socksfd = socket(AF_INET, SOCK_STREAM, 0); + err = errno; + alarm(0); + if (cptr->socksfd < 0 && err == EAGAIN) + sendto_ops("Can't allocate fd for socks on %s : socket: No more sockets", + get_client_name(cptr, TRUE)); + + if (cptr->socksfd < 0) + { + #ifdef USE_SYSLOG + syslog(LOG_ERR, "Unable to create socks socket for %s:%m", + get_client_name(cptr, TRUE)); + #endif + Debug((DEBUG_ERROR, "Unable to create socks socket for %s:%s", + get_client_name(cptr, TRUE), strerror(get_sockerr(cptr)))); + if (!DoingDNS(cptr) && !DoingAuth(cptr)) + SetAccess(cptr); + ircstp->is_abad++; + return; + } + if (cptr->socksfd >= (MAXCONNECTIONS - 2)) + { + sendto_ops("Can't allocate fd for socks on %s", get_client_name(cptr, TRUE)); + close(cptr->socksfd); + return; + } + + set_non_blocking(cptr->socksfd, cptr); + + #ifdef VIRTUAL_HOST + if (bind(cptr->socksfd, (struct sockaddr *)&vserv, sizeof(vserv)) == -1) + { + report_error("binding socks stream socket %s: %s", cptr); + close(cptr->fd); + return; + } + #endif + memcpy(&sock.sin_addr, &cptr->ip, sizeof(struct in_addr)); + + sock.sin_port = htons(1080); + sock.sin_family = AF_INET; + sprintf_irc(text, ":%s NOTICE SOCKS4 :*** Checking SocksProxy & WinGates...\r\n", me.name ); + write(cptr->fd, text, strlen(text)); + alarm((unsigned)4); + if (connect(cptr->socksfd, (struct sockaddr *)&sock, + sizeof(sock)) == -1 && errno != EINPROGRESS) + { + ircstp->is_abad++; + /* + * No error report from this... + */ + alarm((unsigned)0); + close(cptr->socksfd); + cptr->socksfd = -1; + sprintf_irc(text, ":%s NOTICE SOCKS4 :*** Proxy test passed.\r\n", me.name ); + write(cptr->fd, text, strlen(text)); + if (!DoingDNS(cptr) && !DoingAuth(cptr)) + SetAccess(cptr); + return; + } + alarm((unsigned)0); + SetSocks(cptr); + SetWrSocks(cptr); + if (cptr->socksfd > highest_fd) + highest_fd = cptr->socksfd; + return; + } + + /* + * send_socksports + * + */ + void send_socksports(aClient *cptr) + { + struct sockaddr_in us, them; + char socksbuf[255], *uname; + size_t ulen, tlen; + struct passwd *pw; + struct socks4 *sk; + char text[1024]; + + Debug((DEBUG_NOTICE, "write_socksports(%p) fd %d socksfd %d stat %d", + cptr, cptr->fd, cptr->socksfd, cptr->status)); + tlen = ulen = sizeof(us); + if (getsockname(cptr->fd, (struct sockaddr *)&us, &ulen) || + getpeername(cptr->fd, (struct sockaddr *)&them, &tlen)) + { + #ifdef USE_SYSLOG + syslog(LOG_ERR, "socks get{sock,peer}name error for %s:%m", + get_client_name(cptr, TRUE)); + #endif + goto sockssenderr; + } + + if( ! (pw=getpwuid(getuid())) ) { + #ifdef USE_SYSLOG + syslog(LOG_ERR, "socks getpwuid error"); + #endif + goto sockssenderr; + } + + sk=(struct socks4 *)socksbuf; + uname=socksbuf+sizeof(struct socks4); + + sk->vn=4; + sk->cd=1; + sk->dstport=us.sin_port; + sk->dstip=us.sin_addr.s_addr; + strcpy(uname, pw->pw_name); + + Debug((DEBUG_SEND, "sending connect request to socks port %s.1080", + inetntoa(them.sin_addr))); + if (write(cptr->socksfd, socksbuf, sizeof(struct socks4)+strlen(uname)+1) + != (int)(sizeof(struct socks4)+strlen(uname)+1) ) + { + sockssenderr: + sprintf_irc(text, ":%s NOTICE SOCKS4 :*** Proxy test passed.\r\n", me.name ); + write(cptr->fd, text, strlen(text)); + close(cptr->socksfd); + if (cptr->socksfd == highest_fd) + while (!loc_clients[highest_fd]) + highest_fd--; + cptr->socksfd = -1; + ClearSocks(cptr); + if (!DoingDNS(cptr) && !DoingAuth(cptr)) + SetAccess(cptr); + } + ClearWrSocks(cptr); + return; + } + /* + * read_socksports + * + * read the reply (if any) from the ident server we connected to. + * The actual read processijng here is pretty weak - no handling of the reply + * if it is fragmented by IP. + */ + void read_socksports(aClient *cptr) + { + int len; + struct socks4 *sk; + char socksbuf[255]; + char text[1024]; + + sk=(struct socks4 *)socksbuf; + + Debug((DEBUG_NOTICE, "read_socksports(%p) fd %d socksfd %d stat %d", + cptr, cptr->fd, cptr->socksfd, cptr->status)); + + if ( cptr->socksfd>0 && read(cptr->socksfd, socksbuf, sizeof(struct socks4)) == sizeof(struct socks4) ) + { + switch(sk->cd) + { + case 90: + sprintf_irc(text, ":%s NOTICE SOCKS4 :*** Proxy is UNSECURE.\r\n", me.name ); + write(cptr->fd, text, strlen(text)); + /* close connection */ + close(cptr->socksfd); + close(cptr->authfd); + exit_client(cptr, cptr, &me, "SocksProxy o WinGate inseguro"); + return; + default: + break; + } + } + + sprintf_irc(text, ":%s NOTICE SOCKS4 :*** Proxy test passed.\r\n", me.name ); + write(cptr->fd, text, strlen(text)); + + cptr->lasttime = now; + close(cptr->socksfd); + if (cptr->socksfd == highest_fd) + while (!loc_clients[highest_fd]) + highest_fd--; + cptr->socksfd = -1; + ClearSocks(cptr); + ClearWrSocks(cptr); + if (!DoingDNS(cptr) && !DoingAuth(cptr)) + SetAccess(cptr); + return; + }