conf.c
上传用户:sddyfurun
上传日期:2007-01-04
资源大小:525k
文件大小:9k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /* Copyright (c) 1995,1996,1997 NEC Corporation.  All rights reserved.       */
  2. /*                                                                           */
  3. /* The redistribution, use and modification in source or binary forms of     */
  4. /* this software is subject to the conditions set forth in the copyright     */
  5. /* document ("Copyright") included with this distribution.                   */
  6. /*
  7.  * $Id: conf.c,v 1.37.2.1.2.4 1998/11/11 23:27:48 wlu Exp $
  8.  */
  9. #include "socks5p.h"
  10. #include "buffer.h"
  11. #include "addr.h"
  12. #include "confutil.h"
  13. #include "wrap.h"
  14. #include "hostname.h"
  15. #include "log.h"
  16. #ifndef SOCKS_DEFAULT_VERSION
  17. #define SOCKS_DEFAULT_VERSION (strcmp(LIBCONF_FILE, "no"))?0:SOCKS5_VERSION
  18. #endif
  19. struct tagProxyTuple {
  20.     u_char version;
  21.     list *command;
  22.     list *userlist;
  23.     struct host dest;
  24.     struct port dport;
  25.     S5NetAddr netaddr[S5_SERVER_NUM];
  26.     int nnetaddr;
  27. };
  28. typedef struct tagProxyTuple ProxyTuple;
  29. static void ProxyHandler P((void **, int, int, char *));
  30. static ProxyTuple *pts = NULL;
  31. static int nplines = 0, np = 0;
  32. static struct intfc *intfcs = NULL;
  33. static int ifcnt = 0;
  34. static confid confids[] = {
  35.     { "noproxy", "n",    ProxyHandler, (void **)&pts, &nplines, &np, sizeof(ProxyTuple) },
  36. #define NOPROXYIND 0
  37.     { "socks4",  "s4",   ProxyHandler, (void **)&pts, &nplines, &np, 0 },
  38. #define SOCKS4IND  1
  39.     { "socks5",  "s5",   ProxyHandler, (void **)&pts, &nplines, &np, 0 }
  40. #define SOCKS5IND  2
  41. };
  42. static u_char  DefaultProto = (u_char)-1; /* default protocol to use...   */
  43. static u_short DefaultPort = INVALIDPORT;
  44. static S5NetAddr Socks4Addr;
  45. static S5NetAddr Socks5Addr;
  46. static void ProxyHandler(void **array, int indx, int i, char *tmp) {
  47.     ProxyTuple *pa = (*(ProxyTuple **)array);
  48.     int j;
  49.     if (indx >= nplines) {
  50. S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Config file error: Not enough lines allocated");
  51. return;
  52.     }
  53.     
  54.     SKIPNONSPACE(tmp);
  55.     pa[indx].version                     = 0;
  56.     pa[indx].nnetaddr                    = 0;
  57.     memset((char *)pa[indx].netaddr, 0, sizeof(pa[indx].netaddr));
  58.     if (lsGetPermCommand (&tmp, &pa[indx].command))  {
  59. S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Command", lsLineNo);
  60. return;
  61.     }
  62.     if (lsGetHostAndMask  (&tmp, &pa[indx].dest)) {
  63. S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Host", lsLineNo);
  64. return;
  65.     }
  66.     if (lsGetPortOrService(&tmp, &pa[indx].dport)) {
  67. S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Services", lsLineNo);
  68. return;
  69.     }
  70.     if (lsGetPermUsers    (&tmp, &pa[indx].userlist)) {
  71. S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Users", lsLineNo);
  72. return;
  73.     }
  74.     switch (i) {
  75. case NOPROXYIND: return;
  76. case SOCKS4IND:  pa[indx].version = SOCKS4_VERSION; break;
  77.      case SOCKS5IND:  pa[indx].version = SOCKS5_VERSION; break;
  78.     }
  79.     for (j = 0; j < S5_SERVER_NUM && *tmp && *tmp != 'n'; j++, tmp++) {
  80. if (lsGetHostAddressAndPort(&tmp, &pa[indx].netaddr[j])) {
  81.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_ERROR, 0, "Bad line in configuration (%s) file: %d", "Servers", lsLineNo);
  82.     return;
  83. }
  84. SKIPSPACE(tmp);
  85. if (*tmp != ',') {
  86.     j++;
  87.     break;
  88. }
  89.     }
  90.     pa[indx].nnetaddr = j;
  91. }
  92. void SetUpDefaults() {
  93.     u_short tmpport = INVALIDPORT;
  94.     char *tmp, *tmp2;
  95.     DefaultProto =
  96.     getenv("SOCKS5_SERVER")?SOCKS5_VERSION:
  97.     getenv("SOCKS4_SERVER")?SOCKS4_VERSION:
  98.     getenv("SOCKS_SERVER")?SOCKS5_VERSION:
  99.     SOCKS_DEFAULT_VERSION;
  100. /*
  101.     lsName2Port("socks", "tcp", &DefaultPort);
  102. */
  103.     if (DefaultPort == INVALIDPORT) DefaultPort = ntohs(SOCKS_DEFAULT_PORT);
  104.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Socks default port is: %d", ntohs(DefaultPort));
  105.     
  106.     if (!(tmp = getenv("SOCKS4_SERVER")) && !(tmp = getenv("SOCKS_SERVER"))) {
  107. tmp = SOCKS_DEFAULT_SERVER;
  108.     }
  109.     
  110.     if ((tmp2 = strchr(tmp, ':'))) {
  111. *tmp2 = '';
  112. lsName2Port(tmp2+1, "tcp", &tmpport);
  113.     } else {
  114. tmpport = DefaultPort;
  115.     }
  116.     lsName2Addr(tmp, &Socks4Addr);
  117.     lsAddrSetPort(&Socks4Addr, tmpport);
  118.     
  119.     if (tmp2) *tmp2 = ':';
  120.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Default socks4 server is: %s %s:%d", tmp, ADDRANDPORT(&Socks4Addr));
  121.     
  122.     if (!(tmp = getenv("SOCKS5_SERVER")) && !(tmp = getenv("SOCKS_SERVER")))
  123. tmp = SOCKS_DEFAULT_SERVER;
  124.     
  125.     Socks5Addr.sin.sin_family = AF_INET;
  126.     
  127.     if ((tmp2 = strchr(tmp, ':'))) {
  128. *tmp2 = '';
  129. lsName2Port(tmp2+1, "tcp", &tmpport);
  130.     } else {
  131. tmpport = DefaultPort;
  132.     }
  133.     
  134.     lsName2Addr(tmp, &Socks5Addr);
  135.     lsAddrSetPort(&Socks5Addr, tmpport);
  136.     
  137.     if (tmp2) *tmp2 = ':';
  138.     S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Default socks5 server is: %s %s:%d", tmp, ADDRANDPORT(&Socks5Addr));
  139.     if (getenv("SOCKS5_NONETMASKCHECK") == NULL) lsSetupIntfcs(&intfcs, &ifcnt);
  140. }
  141. u_char lsHowToConnect(const S5NetAddr *dest, u_char command, S5NetAddr **proxy, int *nproxies, char *user, S5NetAddr *ret) {
  142.     u_char proto = (u_char)-1;
  143.     static int read = 0;
  144.     static S5NetAddr defaddr;
  145.     char hostname[S5_HOSTNAME_SIZE];
  146.     int i, j, rval;
  147.     /* The "no" check here is so you can disable the config file reading     */
  148.     /* entirely by configuring --without-libconffile, this should also make  */
  149.     /* the default version 5 unless otherwise configured...                  */
  150.     if (!read) {
  151. if (strcmp(LIBCONF_FILE, "no")) {
  152.     char *tmp = getenv("SOCKS5_LIBCONF");
  153.     tmp = tmp?strdup(tmp):strdup(LIBCONF_FILE);
  154.     if (tmp) {
  155.                 lsReadConfig(tmp, confids, sizeof(confids)/sizeof(confid));
  156.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: Config file (%s) read", tmp);
  157.         free(tmp);
  158.     } else {
  159. S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: Config file not defined");
  160.     }
  161. }
  162. read = 1;
  163. memset(&defaddr, 0, sizeof(S5NetAddr));
  164. SetUpDefaults();
  165.     }
  166.     memset(ret, 0, sizeof(S5NetAddr));
  167.     *proxy = NULL;
  168.     *nproxies = 0;
  169.     memset(hostname, 0, sizeof(hostname));
  170.     rval = lsGetCachedHostname((S5NetAddr *)dest, hostname, sizeof(hostname));
  171.     /* If the destination is localhost or the host itself return DIRECT.     */
  172.     if (rval && dest->sin.sin_family == AF_INET) {
  173. if (dest->sin.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) return DIRECT;
  174. if (getenv("SOCKS5_NONETMASKCHECK") == NULL) {
  175.     for (i = 0; i < ifcnt; i++) {
  176.         for (j = 0; j < intfcs[i].addrcnt; j++) {
  177.                  /* null address and null mask doesn't count ...          */
  178.                  if (!(intfcs[i].addrlist[j].ip.s_addr & intfcs[i].addrlist[j].net.s_addr)) continue;
  179.          if (checkifc(intfcs[i].addrlist[j], dest->sin.sin_addr)) {
  180.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "lsHowToConnect: dest(%08x) matches if (%s:%08x)",
  181.         dest->sin.sin_addr.s_addr, intfcs[i].name,
  182.         intfcs[i].addrlist[j].ip.s_addr);
  183.         return DIRECT;
  184.     }
  185.         }
  186.     }
  187. }
  188.     }
  189.     for (i = 0; i < nplines; i++) {
  190. if (pts[i].version == SOCKS4_VERSION) {
  191.     if ((command != SOCKS_BIND && command != SOCKS_CONNECT) || !rval) continue;
  192. }
  193. if (!lsCheckByte(pts[i].command, command, "commands"))       continue;
  194. if (!lsCheckHost(&pts[i].dest, (S5NetAddr *)dest, hostname)) continue;
  195. if (command != SOCKS_PING && command != SOCKS_TRACER && !lsCheckPort(&pts[i].dport, (S5NetAddr *)dest, NULL, (command == SOCKS_UDP)?"udp":"tcp")) continue;
  196. if (!lsCheckUser(pts[i].userlist, user))                     continue;
  197. *proxy    = pts[i].netaddr;
  198. *nproxies = pts[i].nnetaddr;
  199. proto     = pts[i].version;
  200. break;
  201.     }
  202.     if (i != nplines) { 
  203.         S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Config file line #%d matched", i);
  204.         if (proto == DIRECT) return proto;
  205.     } else *proxy = &defaddr;
  206.     if (*nproxies == 0) *nproxies = 1;
  207.     if (proto == (u_char)-1) proto = DefaultProto;
  208.     /* Fill in the default ports and addresses if any are still invalid...   */
  209.     for (i = 0; i < *nproxies; i++) {
  210. (*proxy)[i].sa.sa_family = AF_INET;
  211. if ((*proxy)[i].sin.sin_addr.s_addr == 0L || (*proxy)[i].sin.sin_addr.s_addr == INVALIDADDR) {
  212.     lsAddrCopy(&(*proxy)[i], (proto == SOCKS4_VERSION)?&Socks4Addr:&Socks5Addr, sizeof((*proxy)[i]));
  213. }
  214. if (lsAddr2Port(&(*proxy)[i]) == 0 || lsAddr2Port(&(*proxy)[i]) == INVALIDPORT) {
  215.     lsAddrSetPort(&(*proxy)[i], lsAddr2Port((proto == SOCKS4_VERSION)?&Socks4Addr:&Socks5Addr));
  216. }
  217.         /* If the destination matches the proxy server, client must be able  */
  218.         /* to reach it DIRECTly. Return DIRECT...                            */
  219. if (!lsAddrComp(&(*proxy)[i], dest)) {
  220.     *proxy = NULL;
  221.     *nproxies = 0;
  222.     return DIRECT;
  223. }
  224.     }
  225.     
  226.     if (!rval && proto != SOCKS5_VERSION) {
  227. *nproxies = 0;
  228. *proxy    = NULL;
  229. proto = (u_char)-1;
  230.     } else if (!rval) {
  231.         ret->sa.sa_family = AF_S5NAME;
  232.         ret->sn.sn_port   = lsAddr2Port(dest);
  233.         strcpy(ret->sn.sn_name, hostname);
  234.     } else lsAddrCopy(ret, dest, lsAddrSize(dest));
  235.     return proto;
  236. }