serverconfig.c
上传用户:zm130024
上传日期:2007-01-04
资源大小:432k
文件大小:28k
源码类别:

代理服务器

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1997, 1998, 1999
  3.  *      Inferno Nettverk A/S, Norway.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. The above copyright notice, this list of conditions and the following
  9.  *    disclaimer must appear in all copies of the software, derivative works
  10.  *    or modified versions, and any portions thereof, aswell as in all
  11.  *    supporting documentation.
  12.  * 2. All advertising materials mentioning features or use of this software
  13.  *    must display the following acknowledgement:
  14.  *      This product includes software developed by
  15.  *      Inferno Nettverk A/S, Norway.
  16.  * 3. The name of the author may not be used to endorse or promote products
  17.  *    derived from this software without specific prior written permission.
  18.  *
  19.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  20.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  21.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  24.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  *
  30.  * Inferno Nettverk A/S requests users of this software to return to
  31.  *
  32.  *  Software Distribution Coordinator  or  sdc@inet.no
  33.  *  Inferno Nettverk A/S
  34.  *  Oslo Research Park
  35.  *  Gaustadal閑n 21
  36.  *  N-0349 Oslo
  37.  *  Norway
  38.  *
  39.  * any improvements or extensions that they make and grant Inferno Nettverk A/S
  40.  * the rights to redistribute these changes.
  41.  *
  42.  */
  43. #include "common.h"
  44. #include "config_parse.h"
  45. static const char rcsid[] =
  46. "$Id: serverconfig.c,v 1.92 1999/12/22 09:29:25 karls Exp $";
  47. __BEGIN_DECLS
  48. static void
  49. showuser __P((const struct linkedname_t *user));
  50. /*
  51.  * shows usernames in "user".
  52.  */
  53. static void
  54. showlog __P((const struct log_t *log));
  55. /*
  56.  * shows what type of logging is specified in "log".
  57.  */
  58. #if HAVE_LIBWRAP
  59. extern jmp_buf tcpd_buf;
  60. static void
  61. libwrapinit __P((int s, struct request_info *request));
  62. /*
  63.  * Initializes "request" for later usage via libwrap.
  64.  */
  65. static int
  66. connectisok __P((struct request_info *request, const struct rule_t *rule,
  67.   struct connectionstate_t *state));
  68. #else /* !HAVE_LIBWRAP */
  69. static int
  70. connectisok __P((void *request, const struct rule_t *rule,
  71.   struct connectionstate_t *state));
  72. #endif /* !HAVE_LIBWRAP */
  73. /*
  74.  * Checks the connection on "s".
  75.  * "rule" is the rule that matched the connection and "state" is the current
  76.  * state.
  77.  * This function should be called after each rulecheck for a new
  78.  * connection/packet.
  79.  *
  80.  * Returns:
  81.  * If connection is acceptable: true
  82.  * If connection is not acceptable: false
  83.  */
  84. static struct rule_t *
  85. addrule __P((const struct rule_t *newrule, struct rule_t **rulebase));
  86. /*
  87.  * Appends a copy of "newrule" to "rulebase".
  88.  * Returns a pointer to the added rule (not "newrule").
  89.  */
  90. static void
  91. checkrule __P((const struct rule_t *rule));
  92. /*
  93.  * Check that the rule "rule" makes sense.
  94.  */
  95. __END_DECLS
  96. struct config_t config;
  97. const int configtype = CONFIGTYPE_SERVER;
  98. #if HAVE_LIBWRAP
  99. int allow_severity, deny_severity;
  100. #endif  /* HAVE_LIBWRAP */
  101. struct rule_t *
  102. addclientrule(newrule)
  103. const struct rule_t *newrule;
  104. {
  105. struct rule_t *rule;
  106. rule = addrule(newrule, &config.crule);
  107. /*
  108.  * there are a few things that need to be changed versus the generic
  109.  * init done by addrule().
  110.  */
  111. if (rule->user != NULL) {
  112. /*
  113.  * this is a clientrule so strip away any methods that
  114.  * can not provide a username without socks negotiation.
  115.  */
  116. int i;
  117. for (i = 0; i < rule->state.methodc; ++i)
  118. switch (rule->state.methodv[i]) {
  119. case AUTHMETHOD_RFC931:
  120. break;
  121. default:
  122. rule->state.methodv[i--]
  123. = rule->state.methodv[--rule->state.methodc];
  124. }
  125. }
  126. checkrule(rule);
  127. /* LINTED cast discards 'const' from pointer target type */
  128. return (struct rule_t *)rule;
  129. }
  130. struct rule_t *
  131. addsocksrule(newrule)
  132. const struct rule_t *newrule;
  133. {
  134. struct rule_t *rule;
  135. rule = addrule(newrule, &config.srule);
  136. if (rule->user == NULL) {
  137. /*
  138.  * For each method taking a username, default to
  139.  * allowing everybody that's in the passwordfile.
  140.  */
  141. int i;
  142. for (i = 0; i < rule->state.methodc; ++i)
  143. switch (rule->state.methodv[i]) {
  144. case AUTHMETHOD_UNAME:
  145. case AUTHMETHOD_RFC931:
  146. if (adduser(&rule->user, method2string(rule->state.methodv[i]))
  147. == NULL)
  148. serrx(EXIT_FAILURE, NOMEM);
  149. break;
  150. }
  151. }
  152. checkrule(rule);
  153. /* LINTED cast discards 'const' from pointer target type */
  154. return (struct rule_t *)rule;
  155. }
  156. struct linkedname_t *
  157. adduser(ruleuser, name)
  158. struct linkedname_t **ruleuser;
  159. const char *name;
  160. {
  161. struct linkedname_t *user, *last;
  162. for (user = *ruleuser, last = NULL; user != NULL; user = user->next)
  163. last = user;
  164. if ((user = (struct linkedname_t *)malloc(sizeof(*user))) == NULL)
  165. return NULL;
  166. if ((user->name = strdup(name)) == NULL)
  167. return NULL;
  168. user->next = NULL;
  169. if (*ruleuser == NULL)
  170. *ruleuser = user;
  171. else
  172. last->next = user;
  173. return *ruleuser;
  174. }
  175. void
  176. showrule(rule)
  177. const struct rule_t *rule;
  178. {
  179. char addr[MAXRULEADDRSTRING];
  180. slog(LOG_INFO, "socks-rule #%d",
  181. rule->number);
  182. slog(LOG_INFO, "verdict: %s",
  183. rule->verdict == VERDICT_PASS ? VERDICT_PASSs : VERDICT_BLOCKs);
  184. slog(LOG_INFO, "src: %s",
  185. ruleaddress2string(&rule->src, addr, sizeof(addr)));
  186. slog(LOG_INFO, "dst: %s",
  187. ruleaddress2string(&rule->dst, addr, sizeof(addr)));
  188. showuser(rule->user);
  189. showstate(&rule->state);
  190. showlog(&rule->log);
  191. #if HAVE_LIBWRAP
  192. if (*rule->libwrap != NUL)
  193. slog(LOG_INFO, "libwrap: %s", rule->libwrap);
  194. #endif  /* HAVE_LIBWRAP */
  195. }
  196. void
  197. showclient(rule)
  198. const struct rule_t *rule;
  199. {
  200. char addr[MAXRULEADDRSTRING];
  201. slog(LOG_INFO, "client-rule #%d", rule->number);
  202. slog(LOG_INFO, "verdict: %s",
  203. rule->verdict == VERDICT_PASS ? VERDICT_PASSs : VERDICT_BLOCKs);
  204. slog(LOG_INFO, "from: %s",
  205. ruleaddress2string(&rule->src, addr, sizeof(addr)));
  206. slog(LOG_INFO, "to: %s",
  207. ruleaddress2string(&rule->dst, addr, sizeof(addr)));
  208. showuser(rule->user);
  209. showlog(&rule->log);
  210. #if HAVE_LIBWRAP
  211. if (*rule->libwrap != NUL)
  212. slog(LOG_INFO, "libwrap: %s", rule->libwrap);
  213. #endif  /* HAVE_LIBWRAP */
  214. }
  215. void
  216. showconfig(config)
  217. const struct config_t *config;
  218. {
  219. int i;
  220. char address[MAXSOCKADDRSTRING], buf[1024];
  221. size_t bufused;
  222. slog(LOG_INFO, "internal addresses (%d):", config->internalc);
  223. for (i = 0; i < config->internalc; ++i)
  224. slog(LOG_INFO, "%s",
  225. /* LINTED pointer casts may be troublesome */
  226. sockaddr2string((struct sockaddr *)&config->internalv[i], address,
  227. sizeof(address)));
  228. slog(LOG_INFO, "external addresses (%d):", config->externalc);
  229. for (i = 0; i < config->externalc; ++i)
  230. slog(LOG_INFO, "%s",
  231. /* LINTED pointer casts may be troublesome */
  232. sockaddr2string((struct sockaddr *)&config->externalv[i], address,
  233. sizeof(address)));
  234. bufused = snprintf(buf, sizeof(buf), "compatibility options: ");
  235. if (config->compat.reuseaddr)
  236. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "reuseaddr, ");
  237. if (config->compat.sameport)
  238. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "sameport, ");
  239. slog(LOG_INFO, buf);
  240. bufused = snprintf(buf, sizeof(buf), "extensions enabled: ");
  241. if (config->extension.bind)
  242. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "bind, ");
  243. slog(LOG_INFO, buf);
  244. bufused = snprintf(buf, sizeof(buf), "logoutput goes to: ");
  245. if (config->log.type & LOGTYPE_SYSLOG)
  246. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "syslog, ");
  247. if (config->log.type & LOGTYPE_FILE)
  248. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "files (%d)",
  249. config->log.fpc);
  250. slog(LOG_INFO, buf);
  251. slog(LOG_INFO, "debug level: %d",
  252. config->option.debug);
  253. bufused = snprintf(buf, sizeof(buf), "resolveprotocol: ");
  254. switch (config->resolveprotocol) {
  255. case RESOLVEPROTOCOL_TCP:
  256. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused,
  257. PROTOCOL_TCPs);
  258. break;
  259. case RESOLVEPROTOCOL_UDP:
  260. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused,
  261. PROTOCOL_UDPs);
  262. break;
  263. case RESOLVEPROTOCOL_FAKE:
  264. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused,
  265. "fake");
  266. break;
  267. default:
  268. SERRX(config->resolveprotocol);
  269. }
  270. slog(LOG_INFO, buf);
  271. slog(LOG_INFO, "address/host mismatch tolerated: %s",
  272. config->srchost.nomismatch ? "no" : "yes");
  273. slog(LOG_INFO, "unresolvable addresses tolerated: %s",
  274. config->srchost.nounknown ? "no" : "yes");
  275. slog(LOG_INFO, "negotiate timeout: %lds",
  276. (long)config->timeout.negotiate);
  277. slog(LOG_INFO, "I/O timeout: %lds",
  278. (long)config->timeout.io);
  279. slog(LOG_INFO, "euid: %d", config->state.euid);
  280. slog(LOG_INFO, "userid.privileged: %lu",
  281. (unsigned long)config->uid.privileged);
  282. slog(LOG_INFO, "userid.unprivileged: %lu",
  283. (unsigned long)config->uid.unprivileged);
  284. slog(LOG_INFO, "userid.libwrap: %lu",
  285. (unsigned long)config->uid.libwrap);
  286. bufused = snprintf(buf, sizeof(buf), "method(s): ");
  287. for (i = 0; i < config->methodc; ++i)
  288. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s%s",
  289. i > 0 ? ", " : "", method2string(config->methodv[i]));
  290. slog(LOG_INFO, buf);
  291. if (config->option.debug) {
  292. struct rule_t *rule;
  293. int count;
  294. for (count = 0, rule = config->crule; rule != NULL; rule = rule->next)
  295. ++count;
  296. slog(LOG_INFO, "client-rules (%d): ", count);
  297. for (rule = config->crule; rule != NULL; rule = rule->next)
  298. showclient(rule);
  299. for (count = 0, rule = config->srule; rule != NULL; rule = rule->next)
  300. ++count;
  301. slog(LOG_INFO, "socks-rules (%d): ", count);
  302. for (rule = config->srule; rule != NULL; rule = rule->next)
  303. showrule(rule);
  304. }
  305. }
  306. void
  307. resetconfig(void)
  308. {
  309. struct rule_t *rule;
  310. /*
  311.  * internal; don't touch, only settable at start.
  312.  */
  313. /* external addresses can be changed. */
  314. free(config.externalv);
  315. config.externalv = NULL;
  316. config.externalc = 0;
  317. /* delete all old rules */
  318. rule = config.srule;
  319. while (rule != NULL) {
  320. struct rule_t *next = rule->next;
  321. struct linkedname_t *user, *nextuser;
  322. user = rule->user;
  323. while (user != NULL) {
  324. nextuser = user->next;
  325. free(user);
  326. user = nextuser;
  327. }
  328. free(rule);
  329. rule = next;
  330. }
  331. config.srule = NULL;
  332. /* clientrules too. */
  333. rule = config.crule;
  334. while (rule != NULL) {
  335. struct rule_t *next = rule->next;
  336. struct linkedname_t *user, *nextuser;
  337. user = rule->user;
  338. while (user != NULL) {
  339. nextuser = user->next;
  340. free(user);
  341. user = nextuser;
  342. }
  343. free(rule);
  344. rule = next;
  345. }
  346. config.crule = NULL;
  347. /* route; currently not supported in server. */
  348. /* compat, read from configfile. */
  349. bzero(&config.compat, sizeof(config.compat));
  350. /* extensions, read from configfile. */
  351. bzero(&config.extension, sizeof(config.extension));
  352. /* log; only settable at start. */
  353. /* option; only settable at commandline. */
  354. /* resolveprotocol, read from configfile. */
  355. bzero(&config.resolveprotocol, sizeof(config.resolveprotocol));
  356. /* srchost, read from configfile. */
  357. bzero(&config.srchost, sizeof(config.srchost));
  358. /* stat: keep it. */
  359. /* state; keep it. */
  360. /* methods, read from configfile. */
  361. bzero(config.methodv, sizeof(config.methodv));
  362. config.methodc = 0;
  363. /* timeout, read from configfile. */
  364. bzero(&config.timeout, sizeof(config.timeout));
  365. /* uid, read from configfile. */
  366. bzero(&config.uid, sizeof(config.uid));
  367. /*
  368.  * initialize misc options to sensible default.
  369.  */
  370. config.resolveprotocol = RESOLVEPROTOCOL_UDP;
  371. config.option.keepalive = 1;
  372. config.timeout.negotiate = SOCKD_NEGOTIATETIMEOUT;
  373. config.timeout.io = SOCKD_IOTIMEOUT;
  374. }
  375. void
  376. iolog(rule, state, operation, src, dst, data, count)
  377. struct rule_t *rule;
  378. const struct connectionstate_t *state;
  379. int operation;
  380. const struct sockshost_t *src, *dst;
  381. const char *data;
  382. size_t count;
  383. {
  384. char srcstring[MAXSOCKSHOSTSTRING + MAXNAMELEN + sizeof("@") - 1];
  385. char dststring[MAXSOCKSHOSTSTRING];
  386. const char *name;
  387. int p;
  388. name = NULL;
  389. switch (state->auth.method) {
  390. case AUTHMETHOD_NONE:
  391. case AUTHMETHOD_NOACCEPT: /* closing connection. */
  392. /*
  393.  * doesn't take any space so it's possible it has a name, even
  394.  * if method doesn't indicate it.
  395.  */
  396. name = state->auth.mdata.rfc931.name;
  397. break;
  398. case AUTHMETHOD_UNAME:
  399. name = state->auth.mdata.uname.name;
  400. break;
  401. case AUTHMETHOD_RFC931:
  402. name = state->auth.mdata.rfc931.name;
  403. break;
  404. default:
  405. SERRX(state->auth.method);
  406. }
  407. if (name != NULL && *name != NUL)
  408. p = snprintf(srcstring, sizeof(srcstring), "%s@", name);
  409. else
  410. p = 0;
  411. sockshost2string(src, &srcstring[p], sizeof(srcstring) - p);
  412. sockshost2string(dst, dststring, sizeof(dststring));
  413. /* XXX should probably include authinfo somewhere here too. */
  414. switch (operation) {
  415. case OPERATION_ACCEPT:
  416. case OPERATION_DISCONNECT:
  417. case OPERATION_CONNECT:
  418. if (rule->log.connect || rule->log.disconnect)
  419. slog(LOG_INFO, "%s(%d): %s: %s -> %s",
  420. rule->verdict == VERDICT_PASS ? VERDICT_PASSs : VERDICT_BLOCKs,
  421. rule->number, command2string(state->command),
  422. srcstring, dststring);
  423. break;
  424. case OPERATION_ABORT:
  425. if (rule->log.disconnect || rule->log.error)
  426. slog(LOG_INFO, "%s(%d): %s abort: %s -> %s: %s",
  427. rule->verdict == VERDICT_PASS ? VERDICT_PASSs : VERDICT_BLOCKs,
  428. rule->number, command2string(state->command), srcstring, dststring,
  429. data == NULL ? strerror(errno) : data);
  430. break;
  431. case OPERATION_ERROR:
  432. if (rule->log.error)
  433. slog(LOG_INFO, "%s(%d): %s error: %s -> %s: %s",
  434. rule->verdict == VERDICT_PASS ? VERDICT_PASSs : VERDICT_BLOCKs,
  435. rule->number, protocol2string(state->protocol), srcstring,
  436. dststring, data == NULL ? strerror(errno) : data);
  437. break;
  438. case OPERATION_IO:
  439. if (rule->log.data) {
  440. char *visdata;
  441. SASSERTX(data != NULL);
  442. slog(LOG_INFO, "%s(%d): %s: %s -> %s (%lu): %s",
  443. rule->verdict == VERDICT_BLOCK ? VERDICT_BLOCKs : VERDICT_PASSs,
  444. rule->number, protocol2string(state->protocol),
  445. srcstring, dststring, (unsigned long)count,
  446. strcheck(visdata = str2vis(data, count)));
  447. free(visdata);
  448. }
  449. else if (rule->log.iooperation)
  450. slog(LOG_INFO, "%s(%d): %s: %s -> %s (%lu)",
  451. rule->verdict == VERDICT_BLOCK ? VERDICT_BLOCKs : VERDICT_PASSs,
  452. rule->number, protocol2string(state->protocol),
  453. srcstring, dststring, (unsigned long)count);
  454. break;
  455. default:
  456. SERRX(operation);
  457. }
  458. }
  459. int
  460. rulespermit(s, match, state, src, dst)
  461. int s;
  462. struct rule_t *match;
  463. struct connectionstate_t *state;
  464. const struct sockshost_t *src;
  465. const struct sockshost_t *dst;
  466. {
  467. const char *function = "rulespermit()";
  468. static int init;
  469. static struct rule_t defrule;
  470. struct rule_t *rule;
  471. struct connectionstate_t ostate;
  472. #if HAVE_LIBWRAP
  473. struct request_info libwraprequest;
  474. libwrapinit(s, &libwraprequest);
  475. #else /* !HAVE_LIBWRAP */
  476. void *libwraprequest = NULL;
  477. #endif
  478. /* make a somewhat sensible default rule for entries with no match. */
  479. if (!init) {
  480. defrule.verdict = VERDICT_BLOCK;
  481. defrule.number = 0;
  482. defrule.src.atype = SOCKS_ADDR_IPV4;
  483. defrule.src.addr.ipv4.ip.s_addr = htonl(INADDR_ANY);
  484. defrule.src.addr.ipv4.mask.s_addr = htonl(0);
  485. defrule.src.port.tcp = htons(0);
  486. defrule.src.port.udp = htons(0);
  487. defrule.src.portend = htons(0);
  488. defrule.src.operator = none;
  489. defrule.dst = defrule.src;
  490. if (config.option.debug) {
  491. defrule.log.connect = 1;
  492. defrule.log.disconnect = 1;
  493. defrule.log.error = 1;
  494. defrule.log.iooperation = 1;
  495. }
  496. else {
  497. memset(&defrule.log, 0, sizeof(defrule.log));
  498. defrule.log.connect = 1;
  499. }
  500. memset(&defrule.state.command, UCHAR_MAX, sizeof(defrule.state.command));
  501. defrule.state.methodc = 0;
  502. memset(&defrule.state.protocol, UCHAR_MAX,
  503. sizeof(defrule.state.protocol));
  504. memset(&defrule.state.proxyprotocol, UCHAR_MAX,
  505. sizeof(defrule.state.proxyprotocol));
  506. #if HAVE_LIBWRAP
  507. *defrule.libwrap = NUL;
  508. #endif  /* HAVE_LIBWRAP */
  509. init = 1;
  510. }
  511. /* what rulebase to use.  XXX nicer way to do this. */
  512. switch (state->command) {
  513. case SOCKS_ACCEPT:
  514. /* only set by negotiate children so must be clientrule. */
  515. rule = config.crule;
  516. break;
  517. default:
  518. /* everyone else, socksrules. */
  519. rule = config.srule;
  520. break;
  521. }
  522. /* let "state" be unchanged from original unless we actually get a match. */
  523. for (ostate = *state; rule != NULL; rule = rule->next, *state = ostate) {
  524. char *name, *password;
  525. /* current rule covers desired command? */
  526. switch (state->command) {
  527. case SOCKS_BIND:
  528. if (!rule->state.command.bind)
  529. continue;
  530. break;
  531. case SOCKS_CONNECT:
  532. if (!rule->state.command.connect)
  533. continue;
  534. break;
  535. case SOCKS_UDPASSOCIATE:
  536. if (!rule->state.command.udpassociate)
  537. continue;
  538. break;
  539. /* pseudo commands. */
  540. case SOCKS_BINDREPLY:
  541. if (!rule->state.command.bindreply)
  542. continue;
  543. break;
  544. case SOCKS_UDPREPLY:
  545. if (!rule->state.command.udpreply)
  546. continue;
  547. break;
  548. /* client-rule commands. */
  549. case SOCKS_ACCEPT:
  550. break;
  551. default:
  552. SERRX(state->command);
  553. }
  554. /* current rule covers desired protocol? */
  555. switch (state->protocol) {
  556. case SOCKS_TCP:
  557. if (!rule->state.protocol.tcp)
  558. continue;
  559. break;
  560. case SOCKS_UDP:
  561. if (!rule->state.protocol.udp)
  562. continue;
  563. break;
  564. default:
  565. SERRX(state->protocol);
  566. }
  567. /* current rule covers desired version? */
  568. switch (state->version) {
  569. case SOCKS_V4:
  570. if (!rule->state.proxyprotocol.socks_v4)
  571. continue;
  572. break;
  573. case SOCKS_V5:
  574. if (!rule->state.proxyprotocol.socks_v5)
  575. continue;
  576. break;
  577. default:
  578. SERRX(state->version);
  579. }
  580. /* current rule allows for selected authentication? */
  581. if (!methodisset(state->auth.method, rule->state.methodv,
  582. (size_t)rule->state.methodc))
  583. /*
  584.  * There are some "extra" methods that are independent of
  585.  * socks protocol negotiation and it's thus possible
  586.  * to get a match on them even if above check failed.
  587.  * Currently it's only rfc931.
  588.  */
  589. #if HAVE_LIBWRAP
  590. if (methodisset(AUTHMETHOD_RFC931, rule->state.methodv,
  591. (size_t)rule->state.methodc)) {
  592. strncpy(state->auth.mdata.rfc931.name, eval_user(&libwraprequest),
  593. sizeof(state->auth.mdata.rfc931.name) - 1);
  594. if (state->auth.mdata.rfc931.name[
  595. sizeof(state->auth.mdata.rfc931.name) - 1] != NUL) {
  596. slog(LOG_INFO, "%s: rfc931 name truncated", function);
  597. state->auth.mdata.rfc931.name[
  598. sizeof(state->auth.mdata.rfc931.name) - 1] = NUL;
  599. }
  600. state->auth.method = AUTHMETHOD_RFC931;
  601. }
  602. else
  603. #endif /* HAVE_LIBWRAP */
  604. continue;
  605. SASSERTX(methodisset(state->auth.method, rule->state.methodv,
  606. (size_t)rule->state.methodc));
  607. switch (state->auth.method) {
  608. case AUTHMETHOD_UNAME:
  609. name = state->auth.mdata.uname.name;
  610. password = state->auth.mdata.uname.password;
  611. break;
  612. case AUTHMETHOD_RFC931:
  613. name = state->auth.mdata.rfc931.name;
  614. password = NULL;
  615. break;
  616. default:
  617. name = password = NULL;
  618. }
  619. if (name != NULL && rule->user != NULL) {
  620. const char *methodname;
  621. char srcstring[MAXSOCKSHOSTSTRING];
  622. struct linkedname_t *ruleuser;
  623. /*
  624.  * The rule->user names restricts access further, only names
  625.  * appearing there and in the passwordfile are matched.
  626.  * An alias for "everyone" is a name that is the same as the
  627.  * name of the selected method.
  628.  */
  629. methodname = method2string(state->auth.method);
  630. ruleuser = rule->user;
  631. do {
  632. if (strcmp(methodname, ruleuser->name) == 0)
  633. break; /* all usernames "match" here. */
  634. else if (string2method(name) >= 0)
  635. slog(LOG_INFO, "%s: suspicious username from %s: %s",
  636. function, sockshost2string(src, srcstring, sizeof(srcstring)),
  637. name);
  638. else if (strcmp(name, ruleuser->name) == 0)
  639. break;
  640. } while ((ruleuser = ruleuser->next) != NULL);
  641. if (ruleuser == NULL)
  642. continue; /* no match. */
  643. if (!state->auth.matched) { /* may have been checked at lower level. */
  644. /* all users must also be in passwordfile. */
  645. if (passwordcheck(name, password) != 0)
  646. continue;
  647. state->auth.matched = 1;
  648. }
  649. }
  650. /*
  651.  * This is a little tricky, but for some commands we may not
  652.  * have all info at time of (preliminary) rulechecks.
  653.  * What we want to do if there is no (complete) address given is
  654.  * to see if there's any chance at all the rules will permit this
  655.  * request when the address (later) becomes available.
  656.  * We therefore continue to scan the rules until we either get
  657.  * a pass (ignoring peer with missing info), or the default block
  658.  * is triggered.
  659.  */
  660. if (src != NULL) {
  661. if (!addressmatch(&rule->src, src, state->protocol, 0))
  662. continue;
  663. }
  664. else
  665. if (rule->verdict == VERDICT_BLOCK)
  666. continue; /* continue scan. */
  667. if (dst != NULL) {
  668. if (!addressmatch(&rule->dst, dst, state->protocol, 0))
  669. continue;
  670. }
  671. else
  672. if (rule->verdict == VERDICT_BLOCK)
  673. continue; /* continue scan. */
  674. break;
  675. }
  676. if (rule == NULL) /* no rules matched; match default rule. */
  677. rule = &defrule;
  678. *match = *rule;
  679. /*
  680.  * got our rule, now check connection.  Connectioncheck
  681.  * requires the rule matched so needs to be delayed til here.
  682.  */
  683. if (!connectisok(&libwraprequest, match, state))
  684. match->verdict = VERDICT_BLOCK;
  685. /*
  686.  * specialcases that we delay til here to get correct addr/rule match,
  687.  * even if we could have decided on the final answer before.
  688.  */
  689. switch (state->command) {
  690. case SOCKS_BIND:
  691. if (dst->atype == SOCKS_ADDR_IPV4 && dst->addr.ipv4.s_addr == htonl(0))
  692. if (!config.extension.bind) {
  693. slog(LOG_DEBUG, "%s: client requested disabled extension: bind",
  694. function);
  695. match->verdict = VERDICT_BLOCK;
  696. }
  697. break;
  698. }
  699. return match->verdict == VERDICT_PASS;
  700. }
  701. static struct rule_t *
  702. addrule(newrule, rulebase)
  703. const struct rule_t *newrule;
  704. struct rule_t **rulebase;
  705. {
  706. static const struct serverstate_t state;
  707. const char *function = "addrule()";
  708. struct rule_t *rule;
  709. if ((rule = malloc(sizeof(*rule))) == NULL)
  710. serrx(1, "%s: %s", function, NOMEM);
  711. *rule = *newrule;
  712. /* try to set values not set to a sensible default. */
  713. if (config.option.debug) {
  714. rule->log.connect = 1;
  715. rule->log.disconnect = 1;
  716. rule->log.error = 1;
  717. rule->log.iooperation = 1;
  718. }
  719. /* else; don't touch logging, no logging is ok. */
  720. /* if no command set, set all. */
  721. if (memcmp(&state.command, &rule->state.command, sizeof(state.command)) == 0)
  722. memset(&rule->state.command, UCHAR_MAX, sizeof(rule->state.command));
  723. /*
  724.  * If no method set, set all we support.  This in practice
  725.  * limits the methods we accept here to the globally set methods
  726.  * (config.methodv), since they are checked before we get to
  727.  * rulespesific checks.  We can't just copy config.methodv
  728.  * since it may not be set yet.
  729.  */
  730. if (rule->state.methodc == 0) {
  731. int *methodv = rule->state.methodv;
  732. int *methodc = &rule->state.methodc;
  733. if (rule->user == NULL)
  734. methodv[(*methodc)++] = AUTHMETHOD_NONE;
  735. methodv[(*methodc)++] = AUTHMETHOD_UNAME;
  736. #if HAVE_LIBWRAP
  737. methodv[(*methodc)++] = AUTHMETHOD_RFC931;
  738. #endif
  739. }
  740. /* if no protocol set, set all. */
  741. if (memcmp(&state.protocol, &rule->state.protocol, sizeof(state.protocol))
  742. == 0)
  743. memset(&rule->state.protocol, UCHAR_MAX, sizeof(rule->state.protocol));
  744. /* if no proxyprotocol set, set all except msproxy. */
  745. if (memcmp(&state.proxyprotocol, &rule->state.proxyprotocol,
  746. sizeof(state.proxyprotocol)) == 0) {
  747. memset(&rule->state.proxyprotocol, UCHAR_MAX,
  748. sizeof(rule->state.proxyprotocol));
  749. rule->state.proxyprotocol.msproxy_v2 = 0;
  750. }
  751. if (*rulebase == NULL) {
  752. *rulebase = rule;
  753. (*rulebase)->number = 1;
  754. }
  755. else {
  756. struct rule_t *lastrule;
  757. /* append this rule to the end of our list. */
  758. lastrule = *rulebase;
  759. while (lastrule->next != NULL)
  760. lastrule = lastrule->next;
  761. rule->number = lastrule->number + 1;
  762. lastrule->next = rule;
  763. }
  764. rule->next = NULL;
  765. return rule;
  766. }
  767. static void
  768. checkrule(rule)
  769. const struct rule_t *rule;
  770. {
  771. if (rule->user != NULL)
  772. if (rule->state.methodc == 0)
  773. yyerror("rule restricts by name, but no username-based method given");
  774. }
  775. static void
  776. showuser(user)
  777. const struct linkedname_t *user;
  778. {
  779. char buf[10240];
  780. size_t bufused;
  781. bufused = snprintf(buf, sizeof(buf), "user: ");
  782. for (; user != NULL; user = user->next)
  783. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  784. user->name);
  785. if (bufused > sizeof("user: "))
  786. slog(LOG_INFO, buf);
  787. }
  788. static void
  789. showlog(log)
  790. const struct log_t *log;
  791. {
  792. char buf[1024];
  793. size_t bufused;
  794. bufused = snprintf(buf, sizeof(buf), "log: ");
  795. if (log->connect)
  796. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  797. LOG_CONNECTs);
  798. if (log->disconnect)
  799. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  800. LOG_DISCONNECTs);
  801. if (log->data)
  802. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  803. LOG_DATAs);
  804. if (log->error)
  805. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  806. LOG_ERRORs);
  807. if (log->iooperation)
  808. bufused += snprintf(&buf[bufused], sizeof(buf) - bufused, "%s, ",
  809. LOG_IOOPERATIONs);
  810. slog(LOG_INFO, buf);
  811. }
  812. #if HAVE_LIBWRAP
  813. static void
  814. libwrapinit(s, request)
  815. int s;
  816. struct request_info *request;
  817. {
  818. request_init(request, RQ_FILE, s, RQ_DAEMON, __progname, 0);
  819. fromhost(request);
  820. }
  821. #endif /* HAVE_LIBWRAP */
  822. static int
  823. connectisok(request, rule, state)
  824. #if HAVE_LIBWRAP
  825. struct request_info *request;
  826. #else
  827. void *request;
  828. #endif
  829. const struct rule_t *rule;
  830. struct connectionstate_t *state;
  831. {
  832. #if HAVE_LIBWRAP
  833. /* do we need to involve libwrap for this rule? */
  834. if (*rule->libwrap != NUL
  835. ||  config.srchost.nomismatch
  836. ||  config.srchost.nounknown) {
  837. const char *function = "connectisok()";
  838. char libwrap[LIBWRAPBUF];
  839. uid_t euid;
  840. int checkforname;
  841. socks_seteuid(&euid, config.uid.libwrap);
  842. /* libwrap modifies the passed buffer. */
  843. SASSERTX(strlen(rule->libwrap) < sizeof(libwrap));
  844. strcpy(libwrap, rule->libwrap);
  845. /* Wietse Venema says something along the lines of: */
  846. if (setjmp(tcpd_buf) != 0) {
  847. socks_reseteuid(config.uid.libwrap, euid);
  848. swarnx("%s: failed libwrap line: %s", function, libwrap);
  849. return 0; /* something got screwed up. */
  850. }
  851. process_options(libwrap, request);
  852. /*
  853.  * check if we got a username and won't clobber anything by saving it.
  854.  */
  855. switch (state->auth.method) {
  856. case AUTHMETHOD_NONE: /* doesn't take any memory from rfc931. */
  857. checkforname = 1;
  858. break;
  859. default:
  860. checkforname = 0; /* can't take it or should already have it. */
  861. }
  862. if (checkforname) {
  863. /* XXX can't use eval_user() since it always does rfc931 lookup. */
  864. if (*request->user != NUL) {
  865. strncpy(state->auth.mdata.rfc931.name, request->user,
  866. sizeof(state->auth.mdata.rfc931.name) - 1);
  867. if (state->auth.mdata.rfc931.name
  868. [sizeof(state->auth.mdata.rfc931.name) - 1] != NUL) {
  869. slog(LOG_DEBUG, "%s: rfc931 name too long, truncated", function);
  870. state->auth.mdata.rfc931.name
  871. [sizeof(state->auth.mdata.rfc931.name)
  872. - 1] = NUL;
  873. }
  874. }
  875. }
  876. if (config.srchost.nounknown)
  877. if (strcmp(eval_hostname(request->client), STRING_UNKNOWN) == 0) {
  878. slog(LOG_INFO, "%s: srchost unknown",
  879. eval_hostaddr(request->client));
  880. socks_reseteuid(config.uid.libwrap, euid);
  881. return 0;
  882. }
  883. if (config.srchost.nomismatch)
  884. if (strcmp(eval_hostname(request->client), STRING_PARANOID) == 0) {
  885. slog(LOG_INFO, "%s: srchost ip/host mismatch",
  886. eval_hostaddr(request->client));
  887. socks_reseteuid(config.uid.libwrap, euid);
  888. return 0;
  889. }
  890. socks_reseteuid(config.uid.libwrap, euid);
  891. }
  892. #else /* !HAVE_LIBWRAP */
  893. #endif  /* !HAVE_LIBWRAP */
  894. return 1;
  895. }