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

代理服务器

开发平台:

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. %{
  44. #include "common.h"
  45. #include "yacconfig.h"
  46. static const char rcsid[] =
  47. "$Id: config_parse.y,v 1.121 1999/12/22 09:29:23 karls Exp $";
  48. __BEGIN_DECLS
  49. #if HAVE_LIBWRAP && SOCKS_SERVER
  50. extern jmp_buf tcpd_buf;
  51. #endif /* HAVE_LIBWRAP && SOCKS_SERVER */
  52. static void
  53. addressinit __P((struct ruleaddress_t *address));
  54. __END_DECLS
  55. extern int yylineno;
  56. extern char *yytext;
  57. #if SOCKS_SERVER
  58. static struct rule_t ruleinit;
  59. static struct rule_t rule; /* new rule. */
  60. static struct protocol_t protocolmem; /* new protocolmem. */
  61. struct linkedname_t **userbase; /* users rule applies to. */
  62. #endif
  63. #if SOCKS_CLIENT
  64. static struct serverstate_t state;
  65. static struct route_t route; /* new route. */
  66. static struct ruleaddress_t gw; /* new gateway. */
  67. #endif
  68. static struct ruleaddress_t src; /* new src. */
  69. static struct ruleaddress_t dst; /* new dst. */
  70. static struct ruleaddress_t *ruleaddress; /* current ruleaddress */
  71. static struct extension_t *extension; /* new extensions */
  72. static struct proxyprotocol_t *proxyprotocol;/* proxy protocol. */
  73. static char *atype; /* atype of new address. */
  74. static struct in_addr *ipaddr; /* new ipaddress */
  75. static struct in_addr *netmask; /* new netmask */
  76. static char *domain; /* new domain. */
  77. static in_port_t *port_tcp; /* new tcp portnumber. */
  78. static in_port_t *port_udp; /* new udp portnumber. */
  79. static int *methodv; /* new authmethods. */
  80. static int *methodc; /* number of them. */
  81. static struct protocol_t *protocol; /* new protocol. */
  82. static struct command_t *command; /* new command. */
  83. static enum operator_t *operator; /* new operator. */
  84. static const struct {
  85. const char *name;
  86. const int value;
  87. } syslogfacility[] = {
  88. #ifdef LOG_AUTH
  89. { "auth", LOG_AUTH },
  90. #endif /* LOG_AUTH */
  91. #ifdef LOG_AUTHPRIV
  92. { "authpriv", LOG_AUTHPRIV },
  93. #endif /* LOG_AUTHPRIV */
  94. #ifdef LOG_DAEMON
  95. { "daemon", LOG_DAEMON },
  96. #endif /* LOG_DAEMON */
  97. #ifdef LOG_USER
  98. { "user", LOG_USER },
  99. #endif /* LOG_USER */
  100. #ifdef LOG_LOCAL0
  101. { "local0", LOG_LOCAL0 },
  102. #endif /* LOG_LOCAL0 */
  103. #ifdef LOG_LOCAL1
  104. { "local1", LOG_LOCAL1 },
  105. #endif /* LOG_LOCAL1 */
  106. #ifdef LOG_LOCAL2
  107. { "local2", LOG_LOCAL2 },
  108. #endif /* LOG_LOCAL2 */
  109. #ifdef LOG_LOCAL3
  110. { "local3", LOG_LOCAL3 },
  111. #endif /* LOG_LOCAL3 */
  112. #ifdef LOG_LOCAL4
  113. { "local4", LOG_LOCAL4 },
  114. #endif /* LOG_LOCAL4 */
  115. #ifdef LOG_LOCAL5
  116. { "local5", LOG_LOCAL5 },
  117. #endif /* LOG_LOCAL5 */
  118. #ifdef LOG_LOCAL6
  119. { "local6", LOG_LOCAL6 },
  120. #endif /* LOG_LOCAL6 */
  121. #ifdef LOG_LOCAL7
  122. { "local7", LOG_LOCAL7 }
  123. #endif /* LOG_LOCAL7 */
  124. };
  125. #define YYDEBUG 1
  126. #define ADDMETHOD(method) 
  127. do { 
  128. if (*methodc >= AUTHMETHOD_MAX)
  129. yyerror("internal error or duplicate methods given");
  130. methodv[(*methodc)++] = method; 
  131. } while (0)
  132. %}
  133. %union {
  134. char *string;
  135. uid_t uid;
  136. }
  137. %type <string> configtype serverline clientline deprecated
  138. %token <string> SERVERCONFIG CLIENTCONFIG DEPRECATED
  139. %type <string> protocol protocols protocolname
  140. %type <string> proxyprotocol proxyprotocolname proxyprotocols
  141. %type <string> user username usernames
  142. %type <string> resolveprotocol resolveprotocolname
  143. %type <string> srchost srchostoption srchostoptions
  144. %type <string> command commands commandname
  145. %type <string> routeinit
  146. /* clientconfig exclusive. */
  147. %type <string> clientinit clientconfig
  148. %type <string> clientoption
  149. %type <string> debuging
  150. /* serverconfig exclusive */
  151. %type <string> iotimeout connecttimeout
  152. %type <string> extension extensionname extensions
  153. %type <string> internal internalinit external externalinit
  154. %type <string> logoutput logoutputdevice logoutputdevices
  155. %type <string> compatibility compatibilityname compatibilitys
  156. %type <string> authmethod authmethods authmethodname
  157. %type <string> serveroption
  158. %type <string> serverinit serverconfig
  159. %type <string> userids user_privileged user_unprivileged user_libwrap
  160. %type <uid> userid
  161. %token <string> CLIENTRULE
  162. %token <string> INTERNAL EXTERNAL
  163. %token <string> DEBUGING RESOLVEPROTOCOL
  164. %token <string> SRCHOST NOMISMATCH NOUNKNOWN
  165. %token <string> EXTENSION BIND PRIVILEGED
  166. %token <string> IOTIMEOUT CONNECTTIMEOUT
  167. %token <string> METHOD NONE GSSAPI UNAME RFC931
  168. %token <string> COMPATIBILITY REUSEADDR SAMEPORT
  169. %token <string> USERNAME
  170. %token <string> USER_PRIVILEGED USER_UNPRIVILEGED USER_LIBWRAP
  171. %token <string> LOGOUTPUT LOGFILE
  172. /* route */
  173. %type <string> route
  174. %type <string> via gateway routeoption routeoptions
  175. %token <string> ROUTE VIA
  176. /* rulelines */
  177. %type <string> rule ruleoption ruleoptions
  178. %type <string> clientrule clientruleoption clientruleoptions
  179. %type <string> verdict
  180. %type <string> fromto
  181. %type <string> log logs logname
  182. %type <string> libwrap
  183. %type <string> srcaddress dstaddress
  184. %type <string> address ipaddress gwaddress domain direct
  185. %type <string> from to
  186. %type <string> netmask
  187. %type <string> port portrange portstart portoperator portnumber portservice
  188. %token <string> VERDICT_BLOCK VERDICT_PASS
  189. %token <string> PROTOCOL PROTOCOL_TCP PROTOCOL_UDP PROTOCOL_FAKE
  190. %token <string> PROXYPROTOCOL PROXYPROTOCOL_SOCKS_V4 PROXYPROTOCOL_SOCKS_V5
  191.  PROXYPROTOCOL_MSPROXY_V2
  192. %token <string> USER
  193. %token <string> COMMAND COMMAND_BIND COMMAND_CONNECT COMMAND_UDPASSOCIATE  COMMAND_BINDREPLY COMMAND_UDPREPLY
  194. %token <string> ACTION
  195. %token <string> LINE
  196. %token <string> LIBWRAPSTART
  197. %token <string> OPERATOR
  198. %token <string> LOG LOG_CONNECT  LOG_DATA LOG_DISCONNECT LOG_ERROR     LOG_IOOPERATION
  199. %token <string> IPADDRESS DOMAIN DIRECT
  200. %token <string> PORT PORTNUMBER SERVICENAME
  201. %token <string> NUMBER
  202. %token <string> FROM TO
  203. %%
  204. /*
  205.  * first token we get should say whether we are parsing for client
  206.  * or server.  Init as appropriate.
  207.  */
  208. configtype: serverinit serverline
  209. | clientinit clientline
  210. ;
  211. serverinit: SERVERCONFIG {
  212. #if SOCKS_SERVER
  213. protocol = &protocolmem;
  214. extension = &config.extension;
  215. methodv = config.methodv;
  216. methodc = &config.methodc;
  217. #endif
  218. }
  219. ;
  220. serverline: { $$ = NULL; }
  221. | serverline 'n'
  222. | serverline serverconfig
  223. | serverline clientrule
  224. | serverline rule
  225. ;
  226. clientline: { $$ = NULL; }
  227. | clientline 'n'
  228. | clientline clientconfig
  229. | clientline route
  230. ;
  231. clientinit: CLIENTCONFIG {
  232. }
  233. ;
  234. clientconfig: clientoption
  235. |  deprecated
  236. ;
  237. serverconfig: authmethod
  238. |  deprecated
  239. | internal
  240. | external
  241. | logoutput
  242. | serveroption
  243. | userids
  244. ;
  245. serveroption: compatibility
  246. | connecttimeout
  247. | extension
  248. | iotimeout
  249. | resolveprotocol
  250. | srchost
  251. ;
  252. deprecated: DEPRECATED {
  253. yyerror("given keyword is deprecated");
  254. }
  255. route: ROUTE routeinit '{' routeoptions fromto gateway routeoptions '}' {
  256. #if SOCKS_CLIENT
  257. route.src = src;
  258. route.dst = dst;
  259. ruleaddress2sockshost(&gw, &route.gw.host, SOCKS_TCP);
  260. route.gw.state = state;
  261. addroute(&route);
  262. #endif
  263. }
  264. ;
  265. routeinit: {
  266. #if SOCKS_CLIENT
  267. command = &state.command;
  268. extension = &state.extension;
  269. methodv = state.methodv;
  270. methodc = &state.methodc;
  271. protocol = &state.protocol;
  272. proxyprotocol = &state.proxyprotocol;
  273. bzero(&state, sizeof(state));
  274. bzero(&route, sizeof(route));
  275. bzero(&gw, sizeof(gw));
  276. bzero(&src, sizeof(src));
  277. bzero(&dst, sizeof(dst));
  278. src.atype = SOCKS_ADDR_IPV4;
  279. dst.atype = SOCKS_ADDR_IPV4;
  280. #endif
  281. }
  282. ;
  283. proxyprotocol: PROXYPROTOCOL ':' proxyprotocols
  284. ;
  285. proxyprotocolname: PROXYPROTOCOL_SOCKS_V4 {
  286. proxyprotocol->socks_v4 = 1;
  287. }
  288. | PROXYPROTOCOL_SOCKS_V5 {
  289. proxyprotocol->socks_v5 = 1;
  290. }
  291. |  PROXYPROTOCOL_MSPROXY_V2 {
  292. proxyprotocol->msproxy_v2 = 1;
  293. }
  294. ;
  295. proxyprotocols: proxyprotocolname
  296. | proxyprotocolname proxyprotocols
  297. ;
  298. user: USER ':' usernames
  299. ;
  300. username: USERNAME {
  301. #if SOCKS_SERVER
  302. #if !HAVE_LIBWRAP
  303. if (strcmp($1, method2string(AUTHMETHOD_RFC931)) == 0)
  304. yyerror("method rfc931 requires libwrap");
  305. #endif /* !HAVE_LIBWRAP */
  306. if (adduser(userbase, $1) == NULL)
  307. yyerror(NOMEM);
  308. #endif /* SOCKS_SERVER */
  309. }
  310. ;
  311. usernames: username
  312. | username usernames
  313. ;
  314. extension: EXTENSION ':' extensions
  315. ;
  316. extensionname: BIND {
  317. extension->bind = 1;
  318. }
  319. ;
  320. extensions: extensionname
  321. | extensionname extensions
  322. ;
  323. internal: INTERNAL internalinit ':' ipaddress port {
  324. #if SOCKS_SERVER
  325. if (config.state.init) {
  326. int i;
  327. for (i = 0; i < config.internalc; ++i)
  328. if (config.internalv[i].addr.sin_addr.s_addr == ipaddr->s_addr
  329. &&  config.internalv[i].addr.sin_port == *port_tcp)
  330. break;
  331. if (i == config.internalc)
  332. swarnx("can not change internal addresses once running");
  333. }
  334. #endif /* SOCKS_SERVER */
  335. }
  336. ;
  337. internalinit: {
  338. #if SOCKS_SERVER
  339. static struct ruleaddress_t mem;
  340. struct servent *service;
  341. addressinit(&mem);
  342. if (!config.state.init) {
  343. if ((config.internalv = (struct listenaddress_t *)
  344. realloc(config.internalv, sizeof(*config.internalv) * ++config.internalc))
  345. == NULL)
  346. yyerror(NOMEM);
  347. bzero(&config.internalv[config.internalc - 1].addr,
  348. sizeof((*config.internalv).addr));
  349. config.internalv[config.internalc - 1].addr.sin_family = AF_INET;
  350. ipaddr = &config.internalv[config.internalc - 1].addr.sin_addr;
  351. port_tcp = &config.internalv[config.internalc - 1].addr.sin_port;
  352. }
  353. else { /* can only set internal addresses once. */
  354. static struct in_addr inaddrmem;
  355. static in_port_t portmem;
  356. ipaddr = &inaddrmem;
  357. port_tcp = &portmem;
  358. }
  359. /* set default port. */
  360. if ((service = getservbyname("socks", "tcp")) == NULL)
  361. *port_tcp = htons(SOCKD_PORT);
  362. else
  363. *port_tcp = service->s_port;
  364. #endif
  365. }
  366. ;
  367. external: EXTERNAL externalinit ':' ipaddress {
  368. #if SOCKS_SERVER
  369. if (config.externalv[config.externalc - 1].sin_addr.s_addr
  370. == htonl(INADDR_ANY))
  371. yyerror("external address can't be a wildcard address");
  372. #endif
  373. }
  374. ;
  375. externalinit: {
  376. #if SOCKS_SERVER
  377. static struct ruleaddress_t mem;
  378. if ((config.externalv = (struct sockaddr_in *)realloc(config.externalv,
  379. sizeof(*config.externalv) * ++config.externalc)) == NULL)
  380. yyerror(NOMEM);
  381. bzero(&config.externalv[config.externalc - 1], sizeof(*config.externalv));
  382. config.externalv[config.externalc - 1].sin_family = AF_INET;
  383. addressinit(&mem);
  384. ipaddr = &config.externalv[config.externalc - 1].sin_addr;
  385. #endif
  386. }
  387. ;
  388. clientoption: logoutput
  389. | debuging
  390. | resolveprotocol
  391. ;
  392. logoutput: LOGOUTPUT ':' logoutputdevices
  393. ;
  394. logoutputdevice: LOGFILE {
  395. if (!config.state.init) {
  396. const char *syslogname = "syslog";
  397. if (strncmp($1, syslogname, strlen(syslogname)) == 0
  398. && ($1[strlen(syslogname)] == NUL || $1[strlen(syslogname)] == '/')) {
  399. char *sl;
  400. config.log.type |= LOGTYPE_SYSLOG;
  401. if (*(sl = &($1[strlen(syslogname)])) == '/') { /* facility. */
  402. size_t i;
  403. for (i = 0, ++sl; i < ELEMENTS(syslogfacility); ++i)
  404. if (strcmp(sl, syslogfacility[i].name) == 0)
  405. break;
  406. if (i == ELEMENTS(syslogfacility))
  407. serrx(EXIT_FAILURE, "unknown syslog facility "%s"", sl);
  408. config.log.facility = syslogfacility[i].value;
  409. }
  410. else
  411. config.log.facility = LOG_DAEMON; /* default. */
  412. }
  413. else {
  414. config.log.type |= LOGTYPE_FILE;
  415. if ((config.log.fpv = (FILE **)realloc(config.log.fpv,
  416. sizeof(*config.log.fpv) * (config.log.fpc + 1))) == NULL
  417. || (config.log.fplockv = (int *)realloc(config.log.fplockv,
  418. sizeof(*config.log.fplockv) * (config.log.fpc + 1))) == NULL)
  419. serrx(EXIT_FAILURE, NOMEM);
  420. if ((config.log.fplockv[config.log.fpc]
  421. = socks_mklock(SOCKS_LOCKFILE)) == -1)
  422. serr(EXIT_FAILURE, "socks_mklock()");
  423. if (strcmp($1, "stdout") == 0)
  424. config.log.fpv[config.log.fpc] = stdout;
  425. else if (strcmp($1, "stderr") == 0)
  426. config.log.fpv[config.log.fpc] = stderr;
  427. else {
  428. int flag;
  429. if ((config.log.fpv[config.log.fpc] = fopen($1, "a"))
  430. == NULL)
  431. serr(EXIT_FAILURE, "fopen(%s)", $1);
  432. if ((flag = fcntl(fileno(config.log.fpv[config.log.fpc]),
  433. F_GETFD, 0)) == -1
  434. ||  fcntl(fileno(config.log.fpv[config.log.fpc]), F_SETFD,
  435. flag | FD_CLOEXEC) == -1)
  436. serr(EXIT_FAILURE, "fcntl(F_GETFD/F_SETFD)");
  437. }
  438. ++config.log.fpc;
  439. }
  440. }
  441. else
  442. ; /* XXX warn/exit if output changed. */
  443. }
  444. ;
  445. logoutputdevices: logoutputdevice
  446. | logoutputdevice logoutputdevices
  447. ;
  448. userids: user_privileged
  449. | user_unprivileged
  450. | user_libwrap
  451. ;
  452. user_privileged: USER_PRIVILEGED ':' userid {
  453. #if SOCKS_SERVER
  454. config.uid.privileged = $3;
  455. config.uid.privileged_isset = 1;
  456. #endif
  457. }
  458. ;
  459. user_unprivileged: USER_UNPRIVILEGED ':' userid {
  460. #if SOCKS_SERVER
  461. config.uid.unprivileged = $3;
  462. config.uid.unprivileged_isset = 1;
  463. #endif
  464. }
  465. ;
  466. user_libwrap: USER_LIBWRAP ':' userid {
  467. #if HAVE_LIBWRAP && SOCKS_SERVER
  468. config.uid.libwrap = $3;
  469. config.uid.libwrap_isset = 1;
  470. #else  /* HAVE_LIBWRAP */
  471. yyerror("libwrap support not compiled in");
  472. #endif /* !HAVE_LIBWRAP */
  473. }
  474. ;
  475. userid: USERNAME {
  476. struct passwd *pw;
  477. if ((pw = getpwnam($1)) == NULL)
  478. serrx(EXIT_FAILURE, "no such user "%s"", $1);
  479. else
  480. $$ = pw->pw_uid;
  481. }
  482. ;
  483. iotimeout: IOTIMEOUT ':' NUMBER {
  484. #if SOCKS_SERVER
  485. config.timeout.io = atol($3);
  486. #endif
  487. }
  488. ;
  489. connecttimeout: CONNECTTIMEOUT ':' NUMBER {
  490. #if SOCKS_SERVER
  491. config.timeout.negotiate = atol($3);
  492. #endif
  493. }
  494. ;
  495. debuging: DEBUGING ':' NUMBER {
  496. config.option.debug = atoi($3);
  497. }
  498. ;
  499. compatibility: COMPATIBILITY ':' compatibilitys
  500. ;
  501. compatibilityname: REUSEADDR {
  502. #if SOCKS_SERVER
  503. config.compat.reuseaddr = 1;
  504. }
  505. | SAMEPORT {
  506. config.compat.sameport = 1;
  507. #endif
  508. }
  509. ;
  510. compatibilitys: compatibilityname
  511. | compatibilityname compatibilitys
  512. ;
  513. resolveprotocol: RESOLVEPROTOCOL ':' resolveprotocolname
  514. ;
  515. resolveprotocolname: PROTOCOL_FAKE {
  516. config.resolveprotocol = RESOLVEPROTOCOL_FAKE;
  517. }
  518. |  PROTOCOL_TCP {
  519. #if HAVE_NO_RESOLVESTUFF
  520. yyerror("resolveprotocol keyword not supported on this installation");
  521. #else /* HAVE_NO_RESOLVESTUFF */
  522. config.resolveprotocol = RESOLVEPROTOCOL_TCP;
  523. #endif /* !HAVE_NO_RESOLVESTUFF */
  524. }
  525. | PROTOCOL_UDP {
  526. config.resolveprotocol = RESOLVEPROTOCOL_UDP;
  527. }
  528. ;
  529. srchost: SRCHOST ':' srchostoptions
  530. ;
  531. srchostoption: NOMISMATCH {
  532. #if HAVE_LIBWRAP && SOCKS_SERVER
  533. config.srchost.nomismatch = 1;
  534. }
  535. |  NOUNKNOWN {
  536. config.srchost.nounknown = 1;
  537. #else
  538. yyerror("srchostoption requires libwrap");
  539. #endif
  540. }
  541. ;
  542. srchostoptions: srchostoption
  543. | srchostoption srchostoptions
  544. ;
  545. authmethod: METHOD ':' authmethods
  546. ;
  547. authmethodname: NONE {
  548. ADDMETHOD(AUTHMETHOD_NONE);
  549. };
  550. | GSSAPI {
  551. yyerror("GSSAPI not supported");
  552. }
  553. | UNAME {
  554. ADDMETHOD(AUTHMETHOD_UNAME);
  555. }
  556. | RFC931 {
  557. #if HAVE_LIBWRAP && SOCKS_SERVER
  558. ADDMETHOD(AUTHMETHOD_RFC931);
  559. #else /* !HAVE_LIBWRAP */
  560. yyerror("method rfc931 requires libwrap");
  561. #endif /* !HAVE_LIBWRAP */
  562. }
  563. ;
  564. authmethods: authmethodname
  565. | authmethodname authmethods
  566. ;
  567. /* filterrules */
  568. clientrule: CLIENTRULE verdict '{' clientruleoptions fromto clientruleoptions '}' {
  569. #if SOCKS_SERVER
  570. rule.src = src;
  571. rule.dst = dst;
  572. addclientrule(&rule);
  573. bzero(&src, sizeof(src));
  574. bzero(&dst, sizeof(dst));
  575. rule = ruleinit;
  576. src.atype = SOCKS_ADDR_IPV4;
  577. dst.atype = SOCKS_ADDR_IPV4;
  578. #endif
  579. }
  580. ;
  581. clientruleoption: libwrap
  582. | log
  583. | user
  584. ;
  585. clientruleoptions: { $$ = NULL; }
  586. | clientruleoption clientruleoptions
  587. ;
  588. rule: verdict '{' ruleoptions fromto ruleoptions '}' {
  589. #if SOCKS_SERVER
  590. rule.src = src;
  591. rule.dst = dst;
  592. addsocksrule(&rule);
  593. bzero(&src, sizeof(src));
  594. bzero(&dst, sizeof(dst));
  595. rule = ruleinit;
  596. src.atype = SOCKS_ADDR_IPV4;
  597. dst.atype = SOCKS_ADDR_IPV4;
  598. #endif
  599. }
  600. ;
  601. ruleoption: authmethod
  602. | command
  603. | libwrap
  604. | log
  605. | protocol
  606. | proxyprotocol
  607. | user
  608. ;
  609. ruleoptions: { $$ = NULL; }
  610. | ruleoption ruleoptions
  611. ;
  612. verdict: VERDICT_BLOCK {
  613. #if SOCKS_SERVER
  614. rule.verdict = VERDICT_BLOCK;
  615. command = &rule.state.command;
  616. methodv = rule.state.methodv;
  617. methodc = &rule.state.methodc;
  618. protocol = &rule.state.protocol;
  619. proxyprotocol = &rule.state.proxyprotocol;
  620. userbase = &rule.user;
  621. }
  622. | VERDICT_PASS {
  623. rule.verdict = VERDICT_PASS;
  624. command = &rule.state.command;
  625. methodv = rule.state.methodv;
  626. methodc = &rule.state.methodc;
  627. protocol = &rule.state.protocol;
  628. proxyprotocol = &rule.state.proxyprotocol;
  629. userbase = &rule.user;
  630. #endif
  631. }
  632. ;
  633. command: COMMAND ':' commands
  634. ;
  635. commandname: COMMAND_BIND {
  636. command->bind = 1;
  637. }
  638. | COMMAND_CONNECT {
  639. command->connect = 1;
  640. }
  641. | COMMAND_UDPASSOCIATE {
  642. command->udpassociate = 1;
  643. }
  644. /* pseudocommands */
  645. | COMMAND_BINDREPLY {
  646. command->bindreply = 1;
  647. }
  648. | COMMAND_UDPREPLY {
  649. command->udpreply = 1;
  650. }
  651. ;
  652. commands: commandname
  653. | commandname commands
  654. ;
  655. protocol: PROTOCOL ':'  protocols
  656. ;
  657. protocolname: PROTOCOL_TCP {
  658. protocol->tcp = 1;
  659. }
  660. | PROTOCOL_UDP {
  661. protocol->udp = 1;
  662. }
  663. ;
  664. protocols: protocolname
  665. | protocolname protocols
  666. ;
  667. fromto: srcaddress dstaddress
  668. ;
  669. log: LOG ':' logs
  670. ;
  671. logname:  LOG_CONNECT {
  672. #if SOCKS_SERVER
  673. rule.log.connect = 1;
  674. }
  675. | LOG_DATA {
  676. rule.log.data = 1;
  677. }
  678. | LOG_DISCONNECT {
  679. rule.log.disconnect = 1;
  680. }
  681. | LOG_ERROR {
  682. rule.log.error = 1;
  683. }
  684. | LOG_IOOPERATION {
  685. rule.log.iooperation = 1;
  686. #endif
  687. }
  688. ;
  689. logs: logname
  690. |  logname logs
  691. ;
  692. libwrap: LIBWRAPSTART ':' LINE {
  693. #if HAVE_LIBWRAP && SOCKS_SERVER
  694. struct request_info request;
  695. char libwrap[LIBWRAPBUF];
  696. if (strlen($3) >= sizeof(rule.libwrap))
  697. yyerror("libwrap line too long, make LIBWRAPBUF bigger");
  698. strcpy(rule.libwrap, $3);
  699. /* libwrap modifies the passed buffer. */
  700. SASSERTX(strlen(rule.libwrap) < sizeof(libwrap));
  701. strcpy(libwrap, rule.libwrap);
  702. ++dry_run;
  703. request_init(&request, RQ_FILE, -1, RQ_DAEMON, __progname, 0);
  704. if (setjmp(tcpd_buf) != 0)
  705. yyerror("bad libwrap line");
  706. process_options(libwrap, &request);
  707. --dry_run;
  708. #else /* !HAVE_LIBWRAP */
  709. yyerror("libwrap support not compiled in");
  710. #endif
  711. }
  712. ;
  713. srcaddress: from ':' address
  714. ;
  715. dstaddress: to ':' address
  716. ;
  717. gateway: via ':' gwaddress
  718. ;
  719. routeoption: command
  720. | extension
  721. | protocol
  722. | proxyprotocol
  723. | authmethod
  724. ;
  725. routeoptions: { $$ = NULL; }
  726. | routeoption routeoptions
  727. ;
  728. from: FROM {
  729. addressinit(&src);
  730. }
  731. ;
  732. to: TO {
  733. addressinit(&dst);
  734. }
  735. ;
  736. via: VIA {
  737. #if SOCKS_CLIENT
  738. addressinit(&gw);
  739. #endif
  740. }
  741. ;
  742. address: ipaddress '/' netmask port
  743. | domain port
  744. ;
  745. gwaddress: ipaddress port
  746. | domain port
  747. | direct
  748. ;
  749. ipaddress: IPADDRESS {
  750. *atype = SOCKS_ADDR_IPV4;
  751. if (inet_aton($1, ipaddr) != 1)
  752. yyerror("bad address");
  753. }
  754. ;
  755. netmask: NUMBER {
  756. if (atoi($1) < 0 || atoi($1) > 32)
  757. yyerror("bad netmask");
  758. netmask->s_addr
  759. = atoi($1) == 0 ? 0 : htonl(0xffffffff << (32 - atoi($1)));
  760. }
  761. | IPADDRESS {
  762. if (!inet_aton($1, netmask))
  763. yyerror("bad netmask");
  764. }
  765. ;
  766. domain: DOMAIN {
  767. *atype = SOCKS_ADDR_DOMAIN;
  768. if (strlen($1) >= MAXHOSTNAMELEN)
  769. yyerror("domain too long");
  770. strcpy(domain, $1);
  771. }
  772. ;
  773. direct: DIRECT {
  774. *atype = SOCKS_ADDR_DOMAIN;
  775. if (strlen($1) >= MAXHOSTNAMELEN)
  776. yyerror("domain too long");
  777. strcpy(domain, $1);
  778. #if SOCKS_CLIENT
  779. route.state.direct = 1;
  780. #endif
  781. }
  782. ;
  783. port: { $$ = NULL; }
  784. | PORT portoperator portnumber
  785. | PORT portrange
  786. ;
  787. portnumber: portservice
  788. | portstart
  789. ;
  790. portrange: portstart '-' portend
  791. ;
  792. portstart: PORTNUMBER {
  793. *port_tcp = htons((in_port_t)atoi($1));
  794. *port_udp = htons((in_port_t)atoi($1));
  795. }
  796. ;
  797. portservice: SERVICENAME {
  798. struct servent *service;
  799. struct protocol_t protocolunset;
  800. int set;
  801. bzero(&protocolunset, sizeof(protocolunset));
  802. /* set all protocols if none set, default. */
  803. if (memcmp(protocol, &protocolunset, sizeof(*protocol)) == 0) {
  804. memset(protocol, UCHAR_MAX, sizeof(*protocol));
  805. set = 0;
  806. }
  807. else
  808. set = 1;
  809. if (protocol->tcp) {
  810. if ((service = getservbyname($1, "tcp")) == NULL) {
  811. if (set)
  812. yyerror("bad servicename for tcp");
  813. else
  814. *port_tcp = htons(0);
  815. }
  816. else
  817. *port_tcp = (in_port_t)service->s_port;
  818. }
  819. if (protocol->udp) {
  820. if ((service = getservbyname($1, "udp")) == NULL) {
  821. if (set)
  822. yyerror("bad servicename for udp");
  823. else
  824. *port_udp = htons(0);
  825. }
  826. else
  827. *port_udp = (in_port_t)service->s_port;
  828. }
  829. /* check we got both protocol ports set right. */
  830. if (*port_tcp == htons(0) && *port_udp == htons(0))
  831. yyerror("bad service name for tcp/udp");
  832. if (*port_tcp == htons(0))
  833. *port_tcp = *port_udp;
  834. else if (*port_udp == htons(0))
  835. *port_udp = *port_tcp;
  836. }
  837. ;
  838. portend: PORTNUMBER {
  839. ruleaddress->portend = htons((in_port_t)atoi($1));
  840. ruleaddress->operator = range;
  841. }
  842. ;
  843. portoperator: OPERATOR {
  844. *operator = string2operator($1);
  845. }
  846. ;
  847. %%
  848. #define INTERACTIVE 0
  849. #if SOCKS_SERVER
  850. #define ELECTRICFENCE 0
  851. #else
  852. #define ELECTRICFENCE 0
  853. #endif
  854. #if ELECTRICFENCE
  855. extern int EF_PROTECT_FREE;
  856. extern int EF_ALLOW_MALLOC_0;
  857. extern int EF_ALIGNMENT;
  858. extern int EF_PROTECT_BELOW;
  859. #endif /* ELECTRICFENCE */
  860. extern FILE *yyin;
  861. int parseinit;
  862. int
  863. readconfig(filename)
  864. const char *filename;
  865. {
  866. const char *function = "readconfig()";
  867. #if ELECTRICFENCE
  868. EF_PROTECT_FREE         = 1;
  869. EF_ALLOW_MALLOC_0       = 1;
  870. EF_ALIGNMENT            = 0;
  871. EF_PROTECT_BELOW = 0;
  872. #endif /* ELECTRICFENCE */
  873. /* yydebug = 0; */
  874. yylineno = 1;
  875. parseinit = 0;
  876. if ((yyin = fopen(filename, "r")) == NULL) {
  877. swarn("%s: %s", function, filename);
  878. return -1;
  879. }
  880. yyparse();
  881. fclose(yyin);
  882. errno = 0; /* yacc for some reason alters errno sometimes. */
  883. return 0;
  884. }
  885. void
  886. yyerror(s)
  887. const char *s;
  888. {
  889. serrx(1, "%s: error on line %d, near '%.10s': %s",
  890. config.option.configfile, yylineno,
  891. (yytext == NULL || *yytext == NUL) ? "'start of line'" : yytext, s);
  892. }
  893. static void
  894. addressinit(address)
  895. struct ruleaddress_t *address;
  896. {
  897. ruleaddress = address;
  898. atype = &ruleaddress->atype;
  899. ipaddr = &ruleaddress->addr.ipv4.ip;
  900. netmask = &ruleaddress->addr.ipv4.mask;
  901. domain = ruleaddress->addr.domain;
  902. port_tcp = &ruleaddress->port.tcp;
  903. port_udp = &ruleaddress->port.udp;
  904. operator = &ruleaddress->operator;
  905. }