conf.c
资源名称:socks5.zip [点击查看]
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:9k
源码类别:
代理服务器
开发平台:
Unix_Linux
- /* Copyright (c) 1995,1996,1997 NEC Corporation. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
- /*
- * $Id: conf.c,v 1.37.2.1.2.4 1998/11/11 23:27:48 wlu Exp $
- */
- #include "socks5p.h"
- #include "buffer.h"
- #include "addr.h"
- #include "confutil.h"
- #include "wrap.h"
- #include "hostname.h"
- #include "log.h"
- #ifndef SOCKS_DEFAULT_VERSION
- #define SOCKS_DEFAULT_VERSION (strcmp(LIBCONF_FILE, "no"))?0:SOCKS5_VERSION
- #endif
- struct tagProxyTuple {
- u_char version;
- list *command;
- list *userlist;
- struct host dest;
- struct port dport;
- S5NetAddr netaddr[S5_SERVER_NUM];
- int nnetaddr;
- };
- typedef struct tagProxyTuple ProxyTuple;
- static void ProxyHandler P((void **, int, int, char *));
- static ProxyTuple *pts = NULL;
- static int nplines = 0, np = 0;
- static struct intfc *intfcs = NULL;
- static int ifcnt = 0;
- static confid confids[] = {
- { "noproxy", "n", ProxyHandler, (void **)&pts, &nplines, &np, sizeof(ProxyTuple) },
- #define NOPROXYIND 0
- { "socks4", "s4", ProxyHandler, (void **)&pts, &nplines, &np, 0 },
- #define SOCKS4IND 1
- { "socks5", "s5", ProxyHandler, (void **)&pts, &nplines, &np, 0 }
- #define SOCKS5IND 2
- };
- static u_char DefaultProto = (u_char)-1; /* default protocol to use... */
- static u_short DefaultPort = INVALIDPORT;
- static S5NetAddr Socks4Addr;
- static S5NetAddr Socks5Addr;
- static void ProxyHandler(void **array, int indx, int i, char *tmp) {
- ProxyTuple *pa = (*(ProxyTuple **)array);
- int j;
- if (indx >= nplines) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Config file error: Not enough lines allocated");
- return;
- }
- SKIPNONSPACE(tmp);
- pa[indx].version = 0;
- pa[indx].nnetaddr = 0;
- memset((char *)pa[indx].netaddr, 0, sizeof(pa[indx].netaddr));
- if (lsGetPermCommand (&tmp, &pa[indx].command)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Command", lsLineNo);
- return;
- }
- if (lsGetHostAndMask (&tmp, &pa[indx].dest)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Host", lsLineNo);
- return;
- }
- if (lsGetPortOrService(&tmp, &pa[indx].dport)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Services", lsLineNo);
- return;
- }
- if (lsGetPermUsers (&tmp, &pa[indx].userlist)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Users", lsLineNo);
- return;
- }
- switch (i) {
- case NOPROXYIND: return;
- case SOCKS4IND: pa[indx].version = SOCKS4_VERSION; break;
- case SOCKS5IND: pa[indx].version = SOCKS5_VERSION; break;
- }
- for (j = 0; j < S5_SERVER_NUM && *tmp && *tmp != 'n'; j++, tmp++) {
- if (lsGetHostAddressAndPort(&tmp, &pa[indx].netaddr[j])) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Servers", lsLineNo);
- return;
- }
- SKIPSPACE(tmp);
- if (*tmp != ',') {
- j++;
- break;
- }
- }
- pa[indx].nnetaddr = j;
- }
- void SetUpDefaults() {
- u_short tmpport = INVALIDPORT;
- char *tmp, *tmp2;
- DefaultProto =
- getenv("SOCKS5_SERVER")?SOCKS5_VERSION:
- getenv("SOCKS4_SERVER")?SOCKS4_VERSION:
- getenv("SOCKS_SERVER")?SOCKS5_VERSION:
- SOCKS_DEFAULT_VERSION;
- /*
- lsName2Port("socks", "tcp", &DefaultPort);
- */
- if (DefaultPort == INVALIDPORT) DefaultPort = ntohs(SOCKS_DEFAULT_PORT);
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Socks default port is: %d", ntohs(DefaultPort));
- if (!(tmp = getenv("SOCKS4_SERVER")) && !(tmp = getenv("SOCKS_SERVER"))) {
- tmp = SOCKS_DEFAULT_SERVER;
- }
- if ((tmp2 = strchr(tmp, ':'))) {
- *tmp2 = ' ';
- lsName2Port(tmp2+1, "tcp", &tmpport);
- } else {
- tmpport = DefaultPort;
- }
- lsName2Addr(tmp, &Socks4Addr);
- lsAddrSetPort(&Socks4Addr, tmpport);
- if (tmp2) *tmp2 = ':';
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Default socks4 server is: %s %s:%d", tmp, ADDRANDPORT(&Socks4Addr));
- if (!(tmp = getenv("SOCKS5_SERVER")) && !(tmp = getenv("SOCKS_SERVER")))
- tmp = SOCKS_DEFAULT_SERVER;
- Socks5Addr.sin.sin_family = AF_INET;
- if ((tmp2 = strchr(tmp, ':'))) {
- *tmp2 = ' ';
- lsName2Port(tmp2+1, "tcp", &tmpport);
- } else {
- tmpport = DefaultPort;
- }
- lsName2Addr(tmp, &Socks5Addr);
- lsAddrSetPort(&Socks5Addr, tmpport);
- if (tmp2) *tmp2 = ':';
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Default socks5 server is: %s %s:%d", tmp, ADDRANDPORT(&Socks5Addr));
- if (getenv("SOCKS5_NONETMASKCHECK") == NULL) lsSetupIntfcs(&intfcs, &ifcnt);
- }
- u_char lsHowToConnect(const S5NetAddr *dest, u_char command, S5NetAddr **proxy, int *nproxies, char *user, S5NetAddr *ret) {
- u_char proto = (u_char)-1;
- static int read = 0;
- static S5NetAddr defaddr;
- char hostname[S5_HOSTNAME_SIZE];
- int i, j, rval;
- /* The "no" check here is so you can disable the config file reading */
- /* entirely by configuring --without-libconffile, this should also make */
- /* the default version 5 unless otherwise configured... */
- if (!read) {
- if (strcmp(LIBCONF_FILE, "no")) {
- char *tmp = getenv("SOCKS5_LIBCONF");
- tmp = tmp?strdup(tmp):strdup(LIBCONF_FILE);
- if (tmp) {
- lsReadConfig(tmp, confids, sizeof(confids)/sizeof(confid));
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: Config file (%s) read", tmp);
- free(tmp);
- } else {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: Config file not defined");
- }
- }
- read = 1;
- memset(&defaddr, 0, sizeof(S5NetAddr));
- SetUpDefaults();
- }
- memset(ret, 0, sizeof(S5NetAddr));
- *proxy = NULL;
- *nproxies = 0;
- memset(hostname, 0, sizeof(hostname));
- rval = lsGetCachedHostname((S5NetAddr *)dest, hostname, sizeof(hostname));
- /* If the destination is localhost or the host itself return DIRECT. */
- if (rval && dest->sin.sin_family == AF_INET) {
- if (dest->sin.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) return DIRECT;
- if (getenv("SOCKS5_NONETMASKCHECK") == NULL) {
- for (i = 0; i < ifcnt; i++) {
- for (j = 0; j < intfcs[i].addrcnt; j++) {
- /* null address and null mask doesn't count ... */
- if (!(intfcs[i].addrlist[j].ip.s_addr & intfcs[i].addrlist[j].net.s_addr)) continue;
- if (checkifc(intfcs[i].addrlist[j], dest->sin.sin_addr)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: dest(%08x) matches if (%s:%08x)",
- dest->sin.sin_addr.s_addr, intfcs[i].name,
- intfcs[i].addrlist[j].ip.s_addr);
- return DIRECT;
- }
- }
- }
- }
- }
- for (i = 0; i < nplines; i++) {
- if (pts[i].version == SOCKS4_VERSION) {
- if ((command != SOCKS_BIND && command != SOCKS_CONNECT) || !rval) continue;
- }
- if (!lsCheckByte(pts[i].command, command, "commands")) continue;
- if (!lsCheckHost(&pts[i].dest, (S5NetAddr *)dest, hostname)) continue;
- if (command != SOCKS_PING && command != SOCKS_TRACER && !lsCheckPort(&pts[i].dport, (S5NetAddr *)dest, NULL, (command == SOCKS_UDP)?"udp":"tcp")) continue;
- if (!lsCheckUser(pts[i].userlist, user)) continue;
- *proxy = pts[i].netaddr;
- *nproxies = pts[i].nnetaddr;
- proto = pts[i].version;
- break;
- }
- if (i != nplines) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Config file line #%d matched", i);
- if (proto == DIRECT) return proto;
- } else *proxy = &defaddr;
- if (*nproxies == 0) *nproxies = 1;
- if (proto == (u_char)-1) proto = DefaultProto;
- /* Fill in the default ports and addresses if any are still invalid... */
- for (i = 0; i < *nproxies; i++) {
- (*proxy)[i].sa.sa_family = AF_INET;
- if ((*proxy)[i].sin.sin_addr.s_addr == 0L || (*proxy)[i].sin.sin_addr.s_addr == INVALIDADDR) {
- lsAddrCopy(&(*proxy)[i], (proto == SOCKS4_VERSION)?&Socks4Addr:&Socks5Addr, sizeof((*proxy)[i]));
- }
- if (lsAddr2Port(&(*proxy)[i]) == 0 || lsAddr2Port(&(*proxy)[i]) == INVALIDPORT) {
- lsAddrSetPort(&(*proxy)[i], lsAddr2Port((proto == SOCKS4_VERSION)?&Socks4Addr:&Socks5Addr));
- }
- /* If the destination matches the proxy server, client must be able */
- /* to reach it DIRECTly. Return DIRECT... */
- if (!lsAddrComp(&(*proxy)[i], dest)) {
- *proxy = NULL;
- *nproxies = 0;
- return DIRECT;
- }
- }
- if (!rval && proto != SOCKS5_VERSION) {
- *nproxies = 0;
- *proxy = NULL;
- proto = (u_char)-1;
- } else if (!rval) {
- ret->sa.sa_family = AF_S5NAME;
- ret->sn.sn_port = lsAddr2Port(dest);
- strcpy(ret->sn.sn_name, hostname);
- } else lsAddrCopy(ret, dest, lsAddrSize(dest));
- return proto;
- }