📄 sockd.c
字号:
#else /* SUPPORT_RCMD is not defined */ if ((out = socket(AF_INET, SOCK_STREAM, 0)) < 0) socks_fail("socket()", in, &ndst);#endif /* #if defined(SUPPORT_RCMD) */ sin.sin_family = AF_INET; sin.sin_port = dst->port; sin.sin_addr.s_addr = dst->host; ndst.version = Version; ndst.cmd = SOCKS_RESULT; if (connect(out, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) < 0) socks_fail("connect()", in, &ndst); syslog(LOG_LOW, "connected -- %s", log_msg);#if defined(SO_OOBINLINE) setsockopt(out, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));#endif socks_SendDst(in, &ndst); Pump(in, out); syslog(LOG_LOW, "terminated -- %s.", log_msg); syslog(LOG_LOW, "%lu bytes from %s, %lu bytes from %s", from_in, socks_src_name, from_out, socks_dst_name);}/*** Set up a socket to be connected to from the outside world.** diffrence between this an the Version1 protocal is that** the socket has to be bound from a specific host that** is passed.*/DoNewBind(in, dst)int in;Socks_t *dst;{ struct in_addr sockd_route(); int new, out, len = sizeof(struct sockaddr_in); struct sockaddr_in sin; Socks_t ndst; char dsthost[16]; char socks_dst_name[NAMELEN], socks_dst_serv[NAMELEN]; int outport = IPPORT_RESERVED - 1; int turnon = 1; bzero((char *)&sin, sizeof(sin));#if defined(SO_OOBINLINE) setsockopt(in, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));#endif sin.sin_family = AF_INET; ndst.version = Version; ndst.cmd = SOCKS_RESULT; sin.sin_port = htons(0);#ifdef MULTIHOMED_SERVER sin.sin_addr = sockd_route(dst->host);#else sin.sin_addr.s_addr = htonl(INADDR_ANY);#endif#if defined(SUPPORT_RCMD)#ifdef DEBUG syslog(LOG_LOW, "DoNewBind(): client port=%u", socks_client_port);#endif /* #ifdef DEBUG */ if ((socks_client_port < IPPORT_RESERVED) && (socks_client_port >= IPPORT_RESERVED/2)){ if((out = rresvport(&outport)) < 0) socks_fail("rresrvport()", in, &ndst);#ifdef DEBUG syslog(LOG_LOW, "DoNewBind(): outport=%d", outport);#endif /* #ifdef DEBUG */#if !defined(SCO) && !defined(ISC)#if defined(hpux) ioctl(out, FIOSSAIOOWN, getpid());#else /* hpux not defined */ fcntl(out, F_SETOWN, getpid());#endif /* #if defined(hpux) */#endif /* #if !defined(SCO) && !defined(ISC) */ sin.sin_port = htons((short)outport);#ifdef DEBUG syslog(LOG_LOW, "DoNewBind(): sin.sin_addr=%s, sin.sin_port=%u", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));#endif /* #ifdef DEBUG */ } else {#endif /* #if defined(SUPPORT_RCMD) */ if ((out = socket(AF_INET, SOCK_STREAM, 0)) < 0) socks_fail("socket()", in, &ndst); if (bind(out, (struct sockaddr *)&sin, sizeof(sin)) < 0) socks_fail("bind()", in, &ndst); if (getsockname(out, (struct sockaddr *)&sin, &len) < 0) socks_fail("getsockname()", in, &ndst);#if defined(SUPPORT_RCMD) }#endif /* if defined(SUPPORT_RCMD) */ ndst.port = sin.sin_port; ndst.host = sin.sin_addr.s_addr; if (listen(out, 1) < 0) socks_fail("listen()", in, &ndst);#if defined(SO_OOBINLINE) setsockopt(new, SOL_SOCKET, SO_OOBINLINE, &turnon, sizeof(turnon));#endif socks_SendDst(in, &ndst); len = sizeof(struct sockaddr_in); if ((new = accept(out, (struct sockaddr *)&sin, &len)) < 0) socks_fail("accept()", in, &ndst); close(out); if (sin.sin_addr.s_addr == 0) strcpy(socks_dst_name, "Unspecified.Host"); else socks_saddrtoname(&sin.sin_addr, socks_dst_name, sizeof(socks_dst_name)); socks_porttoserv(sin.sin_port, socks_dst_serv, sizeof(socks_dst_serv));#ifdef SHORTENED_RBIND if ((dst->host != 0L) && (sin.sin_addr.s_addr != dst->host)) {#else if (sin.sin_addr.s_addr != dst->host) {#endif { struct in_addr inaddr; inaddr.s_addr = dst->host; strncpy(dsthost, inet_ntoa(inaddr), sizeof(dsthost)); } syslog(LOG_LOW, "failed -- %s. Error: connected to wrong host %s (%s)", log_msg, socks_dst_name, socks_dst_serv); ndst.cmd = SOCKS_FAIL; socks_SendDst(in, &ndst); exit(1); } syslog(LOG_LOW, "connected -- %s (%s)", log_msg, socks_dst_serv); ndst.port = sin.sin_port; ndst.host = sin.sin_addr.s_addr; socks_SendDst(in, &ndst); Pump(in, new); syslog(LOG_LOW, "terminated -- %s (%s).", log_msg, socks_dst_serv); syslog(LOG_LOW, "%lu bytes from %s, %lu bytes from %s", from_in, socks_src_name, from_out, socks_dst_name);}/*** Now just pump the packets/character through..*/Pump(in, out)int in, out;{ static char buf[4096]; fd_set fds; int s, n, fdsbits; static struct timeval tout = { SOCKS_TIMEOUT, 0 };/* >>> Andy McFadden fadden@uts.amdahl.com */ struct linger ling; /* for linger */ int length; /* for linger */ alarm(0); /* * ATM: use SO_LINGER so it won't hang up on client */ ling.l_onoff = 1; /* turn it on */ ling.l_linger = /*3*/ 10; length = sizeof(ling); if (setsockopt(in, SOL_SOCKET, SO_LINGER, &ling, length) < 0) syslog(LOG_LOW, "setsockopt (SO_LINGER): %m"); if (setsockopt(out, SOL_SOCKET, SO_LINGER, &ling, length) < 0) syslog(LOG_LOW, "setsockopt (SO_LINGER): %m");/* <<< Andy McFadden fadden@uts.amdahl.com */ FD_ZERO(&fds); if (in > out) fdsbits = in + 1; else fdsbits = out +1; while (1) { tout.tv_sec = SOCKS_TIMEOUT; tout.tv_usec = 0; FD_SET(in, &fds); FD_SET(out, &fds); if ((s = select(fdsbits, &fds, NULL,NULL, &tout)) > 0) { if (FD_ISSET(in, &fds)) { if ((n = read(in, buf, sizeof buf)) > 0) { from_in += n; if (write(out, buf, n) < 0) { goto bad; } } else { goto bad; } } if (FD_ISSET(out, &fds)) { if ((n = read(out, buf, sizeof buf)) > 0) { from_out += n; if (write(in, buf, n) < 0) { goto bad; } } else { goto bad; } } } else if ((s == 0) || ((s < 0) && (errno == EINTR))) { continue; } else { syslog(LOG_LOW, "select %m\n"); goto bad; } }bad: ; /* Make the goto happy */}#ifdef FOR_PS/*** SETPROCTITLE -- set process title for ps**** Parameters:** fmt -- a printf style format string.** a, b, c -- possible parameters to fmt.**** Returns:** none.**** Side Effects:** Clobbers argv of our main procedure so ps(1) will** display the title.**** Stolen from IDA Sendmail - I don't think it's UCB code.*//*VARARGS1*/setproctitle(buf, Argv, LastArgv)char *buf;char **Argv, *LastArgv;{#if defined(FOR_PS) && !defined(SYSV) register char *p; register int i; /* make ps print "(sockd)" */ p = Argv[0]; *p++ = '-'; i = strlen(buf); if (i > LastArgv - p - 2) { i = LastArgv - p - 2; buf[i] = '\0'; } (void) strcpy(p, buf); p += i; while (p < LastArgv) *p++ = ' ';#endif /* FOR_PS && !SYSV */}#endif /* #ifdef FOR_PS */#ifdef MULTIHOMED_SERVERstatic char *sockd_route_file = SOCKD_ROUTE_FILE;#ifndef NOT_THROUGH_INETDstruct in_addr sockd_route(dsthost)u_int32 dsthost;{ struct in_addr interface, destip, destmask;#else /* NOT_THROUGH_INETD defined */int readRoute(){#endif /* #infdef NOT_THROUGH_INETD */ FILE *fd; static char buf[1024]; char *bp; int linenum = 0; char *argv[3]; int argc; int badline = 0; int error = 0; if ((fd = fopen(sockd_route_file, "r")) == NULL) { syslog(LOG_HIGH, "Unable to open routing file (%s): %m", sockd_route_file); exit(1); }#ifdef NOT_THROUGH_INETD rtEntries = (struct config **) malloc(CONF_INCR *sizeof(struct config **)); rtPtr = *rtEntries;#endif /* #ifdef NOT_THROUGH_INETD */ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) { linenum++; /* Comment starts with # anywhere in the line */ if ((bp = index(buf, '\n')) != NULL) *bp ='\0'; for (bp = buf; *bp; bp++ ) { if (*bp == '#') { *bp = '\0'; break; } else if (*bp == '\t') *bp = ' '; } socks_mkargs(buf, &argc, argv, 3); if (argc == 0) continue; if (argc != 3) { syslog(LOG_LOW, "Invalid entry at line %d in file %s", linenum, sockd_route_file); exit(1); } #ifndef NOT_THROUGH_INETD if (socks_GetQuad(argv[0], &interface) == -1) { syslog(LOG_HIGH, "Illegal interface field at line %d in file %s", linenum, sockd_route_file); exit(1); } if (socks_GetAddr(argv[1], &destip) == -1) { syslog(LOG_HIGH, "Illegal destination IP at line %d in file %s", linenum, sockd_route_file); exit(1); } if (socks_GetQuad(argv[2], &destmask) == -1) { syslog(LOG_HIGH, "Illegal destination mask at line %d in file %s", linenum, sockd_route_file); exit(1); } if ((destip.s_addr & destmask.s_addr) == (dsthost & destmask.s_addr)) { fclose(fd); return(interface); } } fclose(fd); { struct in_addr inaddr; inaddr.s_addr = dsthost; syslog(LOG_LOW, "Cannot find appropriate interface to communicate with %s\n", inet_ntoa(inaddr)); } exit(1);}#else /* NOT_THROUGH_INETD defined */ /* cache parsed entries */ if (rtPtr - *rtEntries >= rtNtries) rtEntries = (struct config **) realloc(rtEntries, (rtNtries +CONF_INCR) *sizeof(struct config **)); *(rtEntries +rtNtries) = (struct config *) malloc(sizeof (struct config)); rtPtr = *(rtEntries +rtNtries); rtNtries++; if (socks_GetQuad(argv[0], &rtPtr->interface) == -1) { syslog(LOG_HIGH, "Illegal interface field at line %d in file %s", linenum, sockd_route_file); exit(1); } if (socks_GetAddr(argv[1], &rtPtr->daddr) == -1) { syslog(LOG_HIGH, "Illegal destination IP at line %d in file %s", linenum, sockd_route_file); exit(1); } if (socks_GetQuad(argv[2], &rtPtr->dmask) == -1) { syslog(LOG_HIGH, "Illegal destination mask at line %d in file %s", linenum, sockd_route_file); exit(1); } } syslog(LOG_LOW, "Parsed %d lines in route file", rtNtries); fclose(fd); if (!rtNtries) { syslog(LOG_LOW, "No valid lines found in file %s", sockd_route_file); exit(1); } return 1;}struct in_addr sockd_route(dsthost)u_int32 dsthost;{struct in_addr dummy;int i;for (i = 0; i < rtNtries; i++) { rtPtr = *(rtEntries +i); if ((rtPtr->daddr.s_addr & rtPtr->dmask.s_addr) == (dsthost & rtPtr->dmask.s_addr)) { return(rtPtr->interface); }} { struct in_addr inaddr; inaddr.s_addr = dsthost; syslog(LOG_LOW, "Cannot find appropriate interface to communicate with %s\n", inet_ntoa(inaddr)); } exit(1);}#endif /* #ifndef NOT_THROUGH_INETD */#endif /* #ifdef MULTIHOMED_SERVER */#ifndef NOT_THROUGH_INETDcheck_sp_conf(fd, s, src, dst)FILE *fd;char *s;struct sockaddr_in *src, *dst;{ char buf[1024], *p; while (fgets(buf, sizeof(buf) - 1, fd) != NULL) { if ((p = index(buf, '\n')) != NULL) *p = '\0'; if (strncmp(s, buf, strlen(s)) == 0) { socks_shell_cmd(buf+strlen(s), src, dst); break; } } return;}Validate(src, dst, in)struct sockaddr_in *src, *dst;int in;{ unsigned short dst_sin_port = ntohs(dst->sin_port); /* dst->sin_port in host byte order */ IDENT *ident_lookup(), *idp;#else /* NOT_THROUGH_INETD defined *//* read the config file once after startup and cache all parsed configuration.* also re-read after receiving a HUP signal.*/readConfig(){#endif /* #ifndef NOT_THROUGH_INETD */ FILE *fd; static char buf[1024]; char *bp; int linenum = 0, permit; char *argv[10]; int argc; struct in_addr saddr, smask, daddr, dmask; unsigned short dport; long p; char *userlist; int next_arg; int useIdentd; char *cmdp; Portcmp tst; if ((fd = fopen(sockd_conf, "r")) == NULL) { syslog(LOG_HIGH, "Unable to open config file (%s): %m", sockd_conf); exit(1); }#ifdef NOT_THROUGH_INETD cfEntries = (struct config **) malloc(CONF_INCR *sizeof(struct config **)); cfPtr = *cfEntries; *bad_id_cmd = '\0'; *no_identd_cmd ='\0';#endif /* #ifdef NOT_THROUGH_INETD */ while (fgets(buf, sizeof(buf) - 1, fd) != NULL) { linenum++; useIdentd = use_identd; /* ** Comments start with a '#' anywhere on the line */ cmdp = (char *)0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -