📄 sockd.c
字号:
if ((bp = index(buf, '\n')) != NULL) *bp = '\0'; for (bp = buf; *bp != '\0'; bp++) { if (*bp == ':') { *bp++ = '\0'; cmdp = bp; break; } else if (*bp == '#') {#ifdef NOT_THROUGH_INETD if ((*bad_id_cmd == '\0') && !strncmp(bp, BAD_ID_STR, strlen(BAD_ID_STR))) strcpy(bad_id_cmd, bp +strlen(BAD_ID_STR)); if ((*no_identd_cmd == '\0') && !strncmp(bp, NO_IDENTD_STR, strlen(NO_IDENTD_STR))) strcpy(no_identd_cmd, bp +strlen(NO_IDENTD_STR));#endif /* #ifdef NOT_THROUGH_INETD */ *bp = '\0'; break; } else if (*bp == '\t') *bp = ' '; } socks_mkargs(buf, &argc, argv, 8); if (argc == 0) continue; if ((argc < 3) || (argc > 9)) { syslog(LOG_HIGH, "Invalid entry at line %d in file %s", linenum, sockd_conf); exit(1); } /* first parse all args */ if (STREQ(argv[0], "permit")) { permit = 1; } else if (STREQ(argv[0], "deny")) { permit = 0; } else { syslog(LOG_HIGH, "Invalid permit/deny field at line %d in file %s", linenum, sockd_conf); exit(1); } userlist = (char *)0; next_arg = 1; if (strncmp(argv[next_arg], "?=", 2) == 0) { switch (argv[next_arg++][2]) { case 'I': useIdentd = 2; break; case 'i': useIdentd = 1; break; case 'n': case '\0': useIdentd = 0; break; default: syslog(LOG_HIGH, "Invalid ?= field at line %d in file %s", linenum, sockd_conf); exit(1); } } /* syslog(LOG_LOW,"useIdentd=%d",useIdentd); */ if (strncmp(argv[next_arg], "*=", 2) == 0) { if (argv[next_arg][2]) { userlist = argv[next_arg] + 2; } next_arg++; } if(argc <= next_arg+1) { syslog(LOG_HIGH, "Invalid entry at line %d in file %s", linenum, sockd_conf); exit(1); } if (socks_GetAddr(argv[next_arg++], &saddr) == -1) { syslog(LOG_HIGH, "Illegal source IP at line %d in file %s", linenum, sockd_conf); exit(1); } if (socks_GetQuad(argv[next_arg++], &smask) == -1) { syslog(LOG_HIGH, "Illegal source mask at line %d in file %s", linenum, sockd_conf); exit(1); } if ((argc > next_arg + 1) && !(STREQ(argv[next_arg], "eq") || STREQ(argv[next_arg], "neq") || STREQ(argv[next_arg], "lt") || STREQ(argv[next_arg], "gt") || STREQ(argv[next_arg], "le") || STREQ(argv[next_arg], "ge"))) { if (socks_GetAddr(argv[next_arg++], &daddr) == -1) { syslog(LOG_HIGH, "Illegal destination IP at line %d in file %s", linenum, sockd_conf); exit(1); } if (socks_GetQuad(argv[next_arg++], &dmask) == -1) { syslog(LOG_HIGH, "Illegal destination mask at line %d in file %s", linenum, sockd_conf); exit(1); } } else { daddr.s_addr = 0; dmask.s_addr = 0; } if (argc > next_arg + 1) { if (STREQ(argv[next_arg], "eq")) tst = e_eq; else if (STREQ(argv[next_arg], "neq")) tst = e_neq; else if (STREQ(argv[next_arg], "lt")) tst = e_lt; else if (STREQ(argv[next_arg], "gt")) tst = e_gt; else if (STREQ(argv[next_arg], "le")) tst = e_le; else if (STREQ(argv[next_arg], "ge")) tst = e_ge; else { syslog(LOG_HIGH, "Invalid comparison at line %d in file %s", linenum, sockd_conf); exit(1); } if (((p = socks_GetPort(argv[next_arg+1])) < 0) || (p >= (1L << 16))) { syslog(LOG_HIGH, "Invalid port number at line %d in file %s", linenum, sockd_conf); exit(1); } else { dport = p; } } else { tst = e_nil; dport = 0; }#ifdef DEBUG { char msg[1024]; if (userlist) sprintf(msg,"%s %s 0x%08x 0x%08x 0x%08x 0x%08x %s %u", permit ? "permit" : "deny", userlist, saddr.s_addr, smask.s_addr, daddr.s_addr, dmask.s_addr, tst == e_eq ? "==" : tst == e_neq ? "!=" : tst == e_lt ? "<" : tst == e_gt ? ">" : tst == e_le ? "<=" : tst == e_ge ? ">=" : "NIL", dport); else sprintf(msg,"%s 0x%08x 0x%08x 0x%08x 0x%08x %s %u", permit ? "permit" : "deny", saddr.s_addr, smask.s_addr, daddr.s_addr, dmask.s_addr, tst == e_eq ? "==" : tst == e_neq ? "!=" : tst == e_lt ? "<" : tst == e_gt ? ">" : tst == e_le ? "<=" : tst == e_ge ? ">=" : "NIL", dport); syslog(LOG_LOW, "%s", msg); }#endif /* DEBUG */#ifndef NOT_THROUGH_INETD /* comparisons of port numbers must be done in host order */ if((saddr.s_addr & smask.s_addr) == (src->sin_addr.s_addr & smask.s_addr) && (daddr.s_addr & dmask.s_addr) == (dst->sin_addr.s_addr & dmask.s_addr) && socks_check_user(userlist, socks_src_user)) { if (tst == e_nil) goto GotIt; if ((tst == e_eq) && (dst_sin_port == dport)) goto GotIt; if ((tst == e_neq) && (dst_sin_port != dport)) goto GotIt; if ((tst == e_lt) && (dst_sin_port < dport)) goto GotIt; if ((tst == e_gt) && (dst_sin_port > dport)) goto GotIt; if ((tst == e_le) && (dst_sin_port <= dport)) goto GotIt; if ((tst == e_ge) && (dst_sin_port >= dport)) goto GotIt; } } fclose(fd); return 0;GotIt: if ((useIdentd == 0) || (permit == 0)) { fclose(fd); if (cmdp != (char *)0) { socks_shell_cmd(cmdp, src, dst); } return permit; } fseek(fd, 0L, 0); if ((idp = ident_lookup(in, IDENTD_TIMEOUT)) == ((IDENT *)0)) { check_sp_conf(fd, NO_IDENTD_STR, src, dst); permit = -useIdentd; } else { strncpy(socks_real_user, idp->identifier, sizeof(socks_real_user)); if (strcmp(socks_src_user, socks_real_user)) {#if defined(SUPPORT_RCMD) if ((socks_client_port >= IPPORT_RESERVED) || (socks_client_port < IPPORT_RESERVED/2) || strcmp(socks_src_user, "root")) {#endif /* #if defined(SUPPORT_RCMD) */ check_sp_conf(fd, BAD_ID_STR, src, dst); permit = -3;#if defined(SUPPORT_RCMD) }#endif /* #if defined(SUPPORT_RCMD) */ } } ident_free(idp); fclose(fd); if ((permit >= -1) && cmdp) socks_shell_cmd(cmdp, src, dst); return permit;}#else /* NOT_THROUGH_INETD defined */ /* save all parsed arguments */ if (cfPtr - *cfEntries >= cfNtries) cfEntries = (struct config **) realloc(cfEntries, (cfNtries +CONF_INCR) *sizeof(struct config **)); *(cfEntries +cfNtries) = (struct config *) malloc(sizeof (struct config)); cfPtr = *(cfEntries +cfNtries); cfNtries++; cfPtr->action = permit; cfPtr->use_identd = useIdentd; cfPtr->tst = tst; if (userlist) { cfPtr->userlist = (char *) malloc(strlen(userlist) +1); strcpy(cfPtr->userlist, userlist); } else cfPtr->userlist = NULL; cfPtr->saddr.s_addr = saddr.s_addr; cfPtr->smask.s_addr = smask.s_addr; cfPtr->daddr.s_addr = daddr.s_addr; cfPtr->dmask.s_addr = dmask.s_addr; if (cmdp) { cfPtr->cmdp = (char *) malloc(strlen(cmdp) +1); strcpy(cfPtr->cmdp, cmdp); } else cfPtr->cmdp = NULL; cfPtr->dport = dport; } syslog(LOG_LOW, "parsed %d config lines", cfNtries); fclose(fd); if (!cfNtries) { syslog(LOG_HIGH, "no valid lines found in file %s", sockd_conf); exit(1); } return 1;}void rereadConfig(){ int i; int fd; syslog(LOG_LOW, "Received SIGHUP, rereading config file"); if (cfNtries) { for (i = 0; i < cfNtries; i++) { cfPtr = *(cfEntries +i); if (cfPtr->userlist) free(cfPtr->userlist); if (cfPtr->cmdp) free(cfPtr->cmdp); free(cfPtr); } free(cfEntries); cfNtries = 0; } if (!readConfig()) syslog(LOG_HIGH, "Terminate");#ifdef MULTIHOMED_SERVER syslog(LOG_LOW, "Rereading route file"); if (rtNtries) { for (i = 0; i < rtNtries; i++) { rtPtr = *(rtEntries +i); free(rtPtr); } free(rtEntries); rtNtries = 0; } if (!readRoute()) syslog(LOG_HIGH, "Terminate");#endif /* MULTIHOMED_SERVER */}/* system V machines may have to reset the signal here */void reapChild(){ int status; wait(&status); signal(SIGCHLD, reapChild);}/*void killChildren(){ kill(0, SIGTERM); exit();}*/Validate(src, dst, in)struct sockaddr_in *src, *dst;int in;{ int permit; unsigned short dst_sin_port = ntohs(dst->sin_port); /* dst->sin_port in host byte order */ IDENT *ident_lookup(), *idp; int i; for (i = 0; i < cfNtries; i++) { cfPtr = *(cfEntries +i); /* comparisons of port numbers must be done in host order */ if((cfPtr->saddr.s_addr & cfPtr->smask.s_addr) == (src->sin_addr.s_addr & cfPtr->smask.s_addr) && (cfPtr->daddr.s_addr & cfPtr->dmask.s_addr) == (dst->sin_addr.s_addr & cfPtr->dmask.s_addr) && socks_check_user(cfPtr->userlist, socks_src_user)) { if (cfPtr->tst == e_nil) goto GotIt; if ((cfPtr->tst == e_eq) && (dst_sin_port == cfPtr->dport)) goto GotIt; if ((cfPtr->tst == e_neq) && (dst_sin_port != cfPtr->dport)) goto GotIt; if ((cfPtr->tst == e_lt) && (dst_sin_port < cfPtr->dport)) goto GotIt; if ((cfPtr->tst == e_gt) && (dst_sin_port > cfPtr->dport)) goto GotIt; if ((cfPtr->tst == e_le) && (dst_sin_port <= cfPtr->dport)) goto GotIt; if ((cfPtr->tst == e_ge) && (dst_sin_port >= cfPtr->dport)) goto GotIt; } } return 0; GotIt: permit = cfPtr->action; if ((cfPtr->use_identd == 0) || (permit == 0)) { if (cfPtr->cmdp != (char *)0) { socks_shell_cmd(cfPtr->cmdp, src, dst); } return permit; } if ((idp = ident_lookup(in, IDENTD_TIMEOUT)) == ((IDENT *)0)) { if (*no_identd_cmd) socks_shell_cmd(no_identd_cmd, src, dst); permit = -cfPtr->use_identd; } else { strncpy(socks_real_user, idp->identifier, sizeof(socks_real_user)); if (strcmp(socks_src_user, socks_real_user)) {#if defined(SUPPORT_RCMD) if ((socks_client_port >= IPPORT_RESERVED) || (socks_client_port < IPPORT_RESERVED/2) || strcmp(socks_src_user, "root")) {#endif /* SUPPORT_RCMD */ if (*bad_id_cmd) socks_shell_cmd(bad_id_cmd, src, dst); permit = -3;#if defined(SUPPORT_RCMD) }#endif /* SUPPORT_RCMD */ } } ident_free(idp); if ((permit >= -1) && cfPtr->cmdp) socks_shell_cmd(cfPtr->cmdp, src, dst); return permit;}void dumpconf(){ char buf[1024], *bp = buf; char buf2[30]; int i, t; struct in_addr addr; syslog(LOG_HIGH, "Received SIGUSR1\n"); t = cfNtries; if (*no_identd_cmd) t++; if (*bad_id_cmd) t++; syslog(LOG_HIGH,"Effective sockd.conf entries: %d",t); for (i = 0; i < cfNtries; i++) { *bp = '\0'; buf2[0] = '\0'; cfPtr = *(cfEntries + i); strcat(bp, cfPtr->action ? "permit " : "deny "); t = cfPtr->use_identd; strcat(bp, t == 0 ? "?=n " : t == 1 ? "?=i " : t == 2 ? "?=I " : "?=*badvalue* "); if (cfPtr->userlist != NULL) { strcat(bp, "*="); strcat(bp, cfPtr->userlist); strcat(bp, " "); } addr.s_addr = cfPtr->saddr.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); addr.s_addr = cfPtr->smask.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); addr.s_addr = cfPtr->daddr.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); addr.s_addr = cfPtr->dmask.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); switch (cfPtr->tst) { case e_lt: sprintf(buf2,"lt %d ", cfPtr->dport); break; case e_gt: sprintf(buf2,"gt %d ", cfPtr->dport); break; case e_eq: sprintf(buf2,"eq %d ", cfPtr->dport); break; case e_neq: sprintf(buf2,"neq %d ", cfPtr->dport); break; case e_le: sprintf(buf2,"le %d ", cfPtr->dport); break; case e_ge: sprintf(buf2,"ge %d ", cfPtr->dport); break; case e_nil: break; default: sprintf(buf2, "*badcmp* %d ", cfPtr->dport); } strcat(bp, buf2); if (cfPtr->cmdp) { strcat(bp, ": "); strcat(bp, cfPtr->cmdp); } syslog(LOG_HIGH, "CF%d>>%s<<",i+1,bp); } if (*no_identd_cmd) syslog(LOG_HIGH, "CF%d>>%s %s<<", i+1, NO_IDENTD_STR, no_identd_cmd); if (*bad_id_cmd) syslog(LOG_HIGH, "CF%d>>%s %s<<", i+2, BAD_ID_STR, bad_id_cmd);#ifdef MULTIHOMED_SERVER syslog(LOG_HIGH,"Effective sockd.route entries: %d",rtNtries); for (i = 0; i < rtNtries; i++) { *bp = '\0'; rtPtr = *(rtEntries + i); addr.s_addr = rtPtr->interface.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); addr.s_addr = rtPtr->daddr.s_addr; strcat(bp, inet_ntoa(addr)); strcat(bp, " "); addr.s_addr = rtPtr->dmask.s_addr; strcat(bp, inet_ntoa(addr)); syslog(LOG_HIGH, "RT%d>>%s<<\n",i+1,bp); }#endif /* #ifdef MULTIHOMED_SERVER */}#endif /* #ifdef NOT_THROUGH_INETD */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -