1 /* 2 * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2008, 3 * 2009, 2010, 2011, 2012, 2013, 2014, 2019, 2020, 2021 4 * Inferno Nettverk A/S, Norway. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. The above copyright notice, this list of conditions and the following 10 * disclaimer must appear in all copies of the software, derivative works 11 * or modified versions, and any portions thereof, aswell as in all 12 * supporting documentation. 13 * 2. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by 16 * Inferno Nettverk A/S, Norway. 17 * 3. The name of the author may not be used to endorse or promote products 18 * derived from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 * Inferno Nettverk A/S requests users of this software to return to 32 * 33 * Software Distribution Coordinator or sdc@inet.no 34 * Inferno Nettverk A/S 35 * Oslo Research Park 36 * Gaustadall�en 21 37 * NO-0349 Oslo 38 * Norway 39 * 40 * any improvements or extensions that they make and grant Inferno Nettverk A/S 41 * the rights to redistribute these changes. 42 * 43 */ 44 45 %{ 46 47 #if 0 /* XXX automatically added at head of generated .c file */ 48 #include "common.h" 49 #endif 50 51 static const char rcsid[] = 52 "$Id: config_scan.l,v 1.238.4.3.6.9 2021/02/02 19:34:12 karls Exp $"; 53 54 #include "yacconfig.h" 55 #include "config_parse.h" 56 57 #define YY_STACK_USED 0 58 #define YY_ALWAYS_INTERACTIVE 0 59 #define YY_NEVER_INTERACTIVE 1 60 #define YY_MAIN 0 61 62 #if SOCKS_CLIENT 63 /* 64 * stuff that is only defined in the server case, but which I don't know 65 * how #ifdef out in the lex pattern matching code instead. Is it possible? 66 */ 67 #define PROC_MOTHER 0 68 #define PROC_NEGOTIATE 0 69 #define PROC_REQUEST 0 70 #define PROC_IO 0 71 #define PROC_MONITOR 0 72 73 #endif /* SOCKS_CLIENT */ 74 75 static int shouldresetstate(const int current_state, const int next_token); 76 /* 77 * If in state "current_state", and the next token is "next_token", 78 * should we reset the current state? 79 * Returns true if yes, false if not. 80 */ 81 82 83 extern const int socks_configtype; 84 extern int lex_dorestart; 85 86 char currentlexline[100]; /* just to have some context. */ 87 char previouslexline[100]; /* just to have some context. */ 88 static unsigned char ismask; 89 static int inroute, inclientrule; 90 91 %} 92 93 /* 94 * yylineno nonoptimal under flex, reason for 'find_rule' 'yy_flex_realloc' 95 * warnings. 96 */ 97 %option yylineno 98 %option noyywrap 99 %option nounput 100 101 /*%option debug */ 102 103 WORDCHAR [[:alpha:]] 104 NOT_WORDCHAR [[^:alpha:]] 105 LS ^[[:blank:]]* 106 107 SOCKETLEVEL (ip|socket|tcp|udp) 108 109 110 /* non-exclusive start conditions. */ 111 %s start_address 112 %s start_port 113 114 /* exclusive start conditions */ 115 %x lineprefix 116 %x start_command 117 %x start_compatibility 118 %x start_line 119 %x start_log 120 %x start_loglevel 121 %x start_logoutput 122 %x start_logtype 123 %x start_errorsymbol 124 %x start_method 125 %x start_option 126 %x start_proxyprotocol 127 %x start_username 128 %x start_groupname 129 %x start_libwrapfile 130 %x start_cpuoption 131 %x start_hostindex 132 %x start_statekey 133 %x start_tcpoption 134 135 /* ldap-stuff. */ 136 %x start_ldapdomain 137 %x start_ldapbasedn 138 %x start_ldapurl 139 %x start_ldapfilter 140 %x start_ldapattribute 141 %x start_ldapservername 142 %x start_ldapgroupname 143 %x start_ldapkeytabname 144 %x start_ldapcertfile 145 %x start_ldapcertpath 146 147 %x start_pacsidname 148 149 %x start_alarmtest 150 %x start_srchost 151 %x start_protocol 152 %x start_servicename 153 %x start_portnumber 154 %x start_bsdauthstylename 155 %x start_gssapiservicename 156 %x start_gssapikeytabname 157 %x start_encryption 158 %x start_realmname 159 160 %x start_socketprotocol 161 %x start_socketoption 162 %x start_socketoptionvalue 163 164 %x start_processtype 165 %x start_schedulepolicy 166 %x start_schedulemask 167 %% 168 169 %{ 170 171 if (lex_dorestart) { 172 lex_dorestart = 0; 173 inclientrule = inroute = 0; 174 175 switch (socks_configtype) { 176 case CONFIGTYPE_SERVER: 177 return SERVERCONFIG; 178 179 case CONFIGTYPE_CLIENT: 180 return CLIENTCONFIG; 181 182 default: 183 SERRX(socks_configtype); 184 } 185 } 186 187 188 #if 0 /* does not work for some reason. */ 189 \n.* { 190 const char *strip = " \n\t"; 191 const char *p = currentlexline; 192 193 SKIPLEADING(p, strip); 194 if (strlen(p) > 0) 195 strcpy(previouslexline, currentlexline); 196 /* else; blank line. */ 197 198 strncpy(currentlexline, yytext, sizeof(currentlexline) - 1); 199 currentlexline[sizeof(currentlexline) - 1] = NUL; 200 201 ++yylineno; 202 yyless(1); 203 } 204 #endif 205 206 %} 207 208 /* 209 * start-condition dependent stuff. 210 */ 211 212 <start_protocol>ipv4 { 213 yylval.string = yytext; 214 return IPV4; 215 } 216 217 <start_protocol>ipv6 { 218 yylval.string = yytext; 219 return IPV6; 220 } 221 222 <start_tcpoption>ecn { 223 yylval.string = yytext; 224 return ECN; 225 } 226 227 <start_tcpoption>sack { 228 yylval.string = yytext; 229 return SACK; 230 } 231 232 <start_tcpoption>timestamps { 233 yylval.string = yytext; 234 return TIMESTAMPS; 235 } 236 237 <start_tcpoption>wscale { 238 yylval.string = yytext; 239 return WSCALE; 240 } 241 242 243 <start_alarmtest>mtu-error { 244 yylval.string = yytext; 245 return MTU_ERROR; 246 } 247 248 <start_statekey>from|hostid[^: /\t\n]* { 249 BEGIN(0); 250 251 yylval.string = yytext; 252 return STATEKEY; 253 } 254 255 <start_servicename>[a-zA-Z]+[^: /\t\n]* { 256 BEGIN(0); 257 258 yylval.string = yytext; 259 return SERVICENAME; 260 } 261 262 <start_proxyprotocol>socks_v4 { 263 yylval.string = yytext; 264 return PROXYPROTOCOL_SOCKS_V4; 265 } 266 267 <start_proxyprotocol>socks_v5 { 268 yylval.string = yytext; 269 return PROXYPROTOCOL_SOCKS_V5; 270 } 271 272 <start_proxyprotocol>http|http_v1.0 { 273 yylval.string = yytext; 274 return PROXYPROTOCOL_HTTP; 275 } 276 277 <start_proxyprotocol>upnp { 278 yylval.string = yytext; 279 return PROXYPROTOCOL_UPNP; 280 } 281 282 <start_command>bind { 283 yylval.string = yytext; 284 return COMMAND_BIND; 285 } 286 287 <start_command>connect { 288 yylval.string = yytext; 289 return COMMAND_CONNECT; 290 } 291 292 <start_command>udpassociate { 293 yylval.string = yytext; 294 return COMMAND_UDPASSOCIATE; 295 } 296 297 <start_command>bindreply { 298 yylval.string = yytext; 299 return COMMAND_BINDREPLY; 300 } 301 302 <start_command>udpreply { 303 yylval.string = yytext; 304 return COMMAND_UDPREPLY; 305 } 306 307 308 <start_address>(http|ftp)\:\/\/.* { 309 yylval.string = yytext; 310 return URL; 311 } 312 313 <start_address>\. { 314 BEGIN(start_port); 315 316 yylval.string = yytext; 317 return DOMAINNAME; 318 } 319 320 <start_address>0/\/ { 321 /* 322 * For some reason can't get the above "0/\/" included in the 323 * address regexp below: "unrecognized rule" flex says. 324 */ 325 326 BEGIN(start_port); 327 328 yylval.string = yytext; 329 return IPVANY; 330 } 331 332 <start_address>([^ \t\n][^/ \t\n]+)|(::) { 333 struct sockaddr_storage addr, mask; 334 struct in6_addr ipv6; 335 struct in_addr ipv4; 336 char visbuf[256]; 337 338 BEGIN(start_port); 339 340 yylval.string = yytext; 341 342 /* 343 * we don't have a reliable regex to differentiate between a 344 * domainname and ifname on all systems. 345 * With a very general regex like the above, it is not so easy 346 * to exclude an ipaddress from matching it also. So instead 347 * of continuing to try and create a perfect regex, do a brute force 348 * check to see what the text represents. 349 */ 350 351 if (socks_inet_pton(AF_INET, yytext, &ipv4, NULL) == 1) 352 return IPV4; 353 354 if (socks_inet_pton(AF_INET6, yytext, &ipv6, NULL) == 1) { 355 if (IN6_IS_ADDR_V4MAPPED(&ipv6)) 356 yyerrorx("we do not use IPv4-mapped IPv6 addresses. Please specify " 357 "a regular IPv4 address instead if you want use IPv4"); 358 else 359 return IPV6; 360 } 361 362 errno = 0; 363 if (ifname2sockaddr(yytext, 0, &addr, &mask) != NULL) 364 return IFNAME; 365 else { 366 if (ERRNOISNOFILE(errno)) 367 yyerror("no free filedescriptors: can not access information on " 368 "whether \"%s\" is a local NIC or not", 369 str2vis(yytext, strlen(yytext), visbuf, sizeof(visbuf))); 370 } 371 372 slog(LOG_DEBUG, 373 "\"%s\" appears to be neither ipaddress nor ifname; assuming hostname ", 374 yytext); 375 376 return DOMAINNAME; 377 } 378 379 <start_port>port { 380 yylval.string = yytext; 381 return PORT; 382 } 383 384 /* 385 * cpu options. 386 */ 387 388 cpu { 389 BEGIN(start_cpuoption); 390 391 yylval.string = yytext; 392 return CPU; 393 } 394 395 <start_cpuoption>schedule { 396 BEGIN(start_processtype); 397 398 ismask = 0; 399 400 yylval.string = yytext; 401 return SCHEDULE; 402 } 403 404 <start_cpuoption>mask { 405 BEGIN(start_processtype); 406 407 ismask = 1; 408 409 yylval.string = yytext; 410 return MASK; 411 } 412 413 <start_processtype>mother { 414 BEGIN(ismask ? start_schedulemask : start_schedulepolicy); 415 416 yylval.number = PROC_MOTHER; 417 return PROCESSTYPE; 418 } 419 420 <start_processtype>monitor { 421 BEGIN(ismask ? start_schedulemask : start_schedulepolicy); 422 423 yylval.number = PROC_MONITOR; 424 return PROCESSTYPE; 425 } 426 427 <start_processtype>negotiate { 428 BEGIN(ismask ? start_schedulemask : start_schedulepolicy); 429 430 yylval.number = PROC_NEGOTIATE; 431 return PROCESSTYPE; 432 } 433 434 <start_processtype>request { 435 BEGIN(ismask ? start_schedulemask : start_schedulepolicy); 436 437 yylval.number = PROC_REQUEST; 438 return PROCESSTYPE; 439 } 440 441 <start_processtype>io { 442 BEGIN(ismask ? start_schedulemask : start_schedulepolicy); 443 444 yylval.number = PROC_IO; 445 return PROCESSTYPE; 446 } 447 448 <start_schedulemask>any { 449 BEGIN(0); 450 451 yylval.number = CPUMASK_ANYCPU; 452 return NUMBER; 453 } 454 455 <start_schedulepolicy>[^: 0-9\t/]+ { 456 #if SOCKS_CLIENT 457 SERRX(0); 458 459 #else /* !SOCKS_CLIENT */ 460 461 #if HAVE_SCHED_SETSCHEDULER 462 463 BEGIN(0); 464 465 if ((yylval.number = cpupolicy2numeric(yytext)) == -1) 466 yyerrorx("unknown scheduling policy \"%s\"", yytext); 467 468 return SCHEDULEPOLICY; 469 470 #else /* !HAVE_SCHED_SETSCHEDULER */ 471 472 yyerrorx("setting cpu scheduling policy is not supported on this platform"); 473 474 #endif /* !HAVE_SCHED_SETSCHEDULER */ 475 476 #endif /* SOCKS_CLIENT */ 477 } 478 479 480 /* 481 * socket option stuff. 482 */ 483 484 <start_socketprotocol>ip { 485 BEGIN(start_socketoption); 486 487 yylval.number = IPPROTO_IP; 488 return SOCKETPROTOCOL; 489 } 490 491 <start_socketprotocol>socket { 492 BEGIN(start_socketoption); 493 494 yylval.number = SOL_SOCKET; 495 return SOCKETPROTOCOL; 496 } 497 498 <start_socketprotocol>tcp { 499 BEGIN(start_socketoption); 500 501 yylval.number = IPPROTO_TCP; 502 return SOCKETPROTOCOL; 503 } 504 505 <start_socketprotocol>udp { 506 BEGIN(start_socketoption); 507 508 yylval.number = IPPROTO_UDP; 509 return SOCKETPROTOCOL; 510 } 511 512 513 <start_socketoption>[-a-zA-Z_][-a-zA-Z_\.0-9]+ { 514 const sockopt_t *sockopt; 515 516 BEGIN(start_socketoptionvalue); 517 518 if ((sockopt = optname2sockopt(yytext)) == NULL) 519 yyerrorx("unknown socket option \"%s\"", yytext); 520 521 yylval.number = (ssize_t)sockopt->optid; 522 return SOCKETOPTION_OPTID; 523 } 524 525 <start_socketoptionvalue>[^: \t\n0-9][^ \t\n]+ { 526 BEGIN(0); 527 528 yylval.string = yytext; 529 return SOCKETOPTION_SYMBOLICVALUE; 530 } 531 532 <start_log>connect { 533 yylval.string = yytext; 534 return RULE_LOG_CONNECT; 535 } 536 537 <start_log>data { 538 yylval.string = yytext; 539 return RULE_LOG_DATA; 540 } 541 542 <start_log>disconnect { 543 yylval.string = yytext; 544 return RULE_LOG_DISCONNECT; 545 } 546 547 <start_log>error { 548 yylval.string = yytext; 549 return RULE_LOG_ERROR; 550 } 551 552 <start_log>iooperation|ioop { 553 yylval.string = yytext; 554 return RULE_LOG_IOOPERATION; 555 } 556 557 <start_log>tcpinfo { 558 yylval.string = yytext; 559 return RULE_LOG_TCPINFO; 560 } 561 562 <start_loglevel>[a-zA-Z]+/\. { 563 const loglevel_t *l; 564 char visbuf[256]; 565 566 BEGIN(start_logtype); 567 568 if ((l = loglevel(yytext)) == NULL) 569 yyerror("unknown loglevel: \"%s\"", 570 str2vis(yytext, strlen(yytext), visbuf, sizeof(visbuf))); 571 572 yylval.number = l->value; 573 return LOGLEVEL; 574 } 575 576 <start_logtype>error { 577 BEGIN(start_errorsymbol); 578 579 yylval.string = yytext; 580 return LOGTYPE_ERROR; 581 } 582 583 <start_logtype>tcp\.disabled { 584 BEGIN(start_tcpoption); 585 586 yylval.string = yytext; 587 return LOGTYPE_TCP_DISABLED; 588 } 589 590 <start_logtype>tcp\.enabled { 591 BEGIN(start_tcpoption); 592 593 yylval.string = yytext; 594 return LOGTYPE_TCP_ENABLED; 595 } 596 597 598 <start_errorsymbol>[a-zA-Z][^:[:space:]]+ { 599 #if !SOCKS_CLIENT 600 601 /* 602 * Figure out what kind of error-symbol we are dealing with. 603 * Since we do not force the user to specify what kind of symbol 604 * he specifies, we have to try all variants. 605 */ 606 if ((yylval.error.valuev = gaivalue(yytext)) != NULL) 607 yylval.error.valuetype = VALUETYPE_GAIERR; 608 else if ((yylval.error.valuev = errnovalue(yytext)) != NULL) 609 yylval.error.valuetype = VALUETYPE_ERRNO; 610 611 #else /* SOCKS_CLIENT */ 612 613 yylval.error.valuev = NULL; 614 615 #endif /* SOCKS_CLIENT */ 616 617 return ERRORVALUE; 618 } 619 620 <start_bsdauthstylename>[a-zA-Z]+[^: /\t\n]* { 621 yylval.string = yytext; 622 return BSDAUTHSTYLENAME; 623 } 624 625 <start_logoutput>[^: \t\n]+ { 626 yylval.string = yytext; 627 return LOGFILE; 628 } 629 630 <start_username>[^: \t\n]+ { 631 yylval.string = yytext; 632 return USERNAME; 633 } 634 635 <start_groupname>[^: \t\n]+ { 636 yylval.string = yytext; 637 return GROUPNAME; 638 } 639 640 <start_libwrapfile>[^: \t\n]+ { 641 yylval.string = yytext; 642 return LIBWRAP_FILE; 643 } 644 645 <start_ldapdomain>[^: \t\n]+[^\t\n]+ { 646 yylval.string = yytext; 647 return LDAP_DOMAIN; 648 } 649 650 <start_ldapbasedn>[^: \t\n]+[^\t\n]+ { 651 yylval.string = yytext; 652 return LDAP_BASEDN; 653 } 654 655 <start_ldapfilter>[^: \t\n]+[^\t\n]+ { 656 yylval.string = yytext; 657 return LDAP_FILTER; 658 } 659 660 <start_ldapurl>(ldap|ldaps)\:\/\/.* { 661 yylval.string = yytext; 662 return LDAP_URL; 663 } 664 665 <start_ldapattribute>[^: \t\n]+[^\t\n]+ { 666 yylval.string = yytext; 667 return LDAP_ATTRIBUTE; 668 } 669 670 <start_ldapgroupname>[^: \t\n]+[^\t\n]+ { 671 yylval.string = yytext; 672 return LDAPGROUP_NAME; 673 } 674 675 <start_ldapservername>[^: \t\n]+[^\t\n]+ { 676 yylval.string = yytext; 677 return LDAPSERVER_NAME; 678 } 679 680 <start_ldapcertfile>[^: \t\n]+ { 681 yylval.string = yytext; 682 return LDAP_CERTFILE; 683 } 684 685 <start_ldapcertpath>[^: \t\n]+ { 686 yylval.string = yytext; 687 return LDAP_CERTPATH; 688 } 689 690 <start_ldapkeytabname>[^: \t\n]+ { 691 yylval.string = yytext; 692 return LDAPKEYTABNAME; 693 } 694 695 <start_ldapkeytabname>FILE:[^ \t\n]+ { 696 yylval.string = yytext; 697 return LDAPKEYTABNAME; 698 } 699 700 <start_pacsidname>[^: \t\n]+[^\t\n]+ { 701 yylval.string = yytext; 702 return PACSID_NAME; 703 } 704 705 <start_gssapikeytabname>[^: \t\n]+ { 706 yylval.string = yytext; 707 return GSSAPIKEYTABNAME; 708 } 709 710 <start_gssapikeytabname>FILE:[^ \t\n]+ { 711 yylval.string = yytext; 712 return GSSAPIKEYTABNAME; 713 } 714 715 <start_gssapiservicename>[^: \t\n]+ { 716 yylval.string = yytext; 717 return GSSAPISERVICENAME; 718 } 719 720 <lineprefix>: { 721 BEGIN(start_line); 722 723 yylval.string = yytext; 724 return *yytext; 725 } 726 727 <start_line>.* { 728 BEGIN(0); 729 730 yylval.string = yytext; 731 return LINE; 732 } 733 734 <start_srchost>nodnsmismatch { 735 yylval.string = yytext; 736 return NODNSMISMATCH; 737 } 738 739 <start_srchost>nodnsunknown { 740 yylval.string = yytext; 741 return NODNSUNKNOWN; 742 } 743 744 <start_srchost>checkreplyauth { 745 yylval.string = yytext; 746 return CHECKREPLYAUTH; 747 } 748 749 <start_protocol>tcp { 750 yylval.string = yytext; 751 return PROTOCOL_TCP; 752 } 753 754 <start_protocol>udp { 755 yylval.string = yytext; 756 return PROTOCOL_UDP; 757 } 758 759 <start_protocol>fake { 760 yylval.string = yytext; 761 return PROTOCOL_FAKE; 762 } 763 764 <start_encryption>any { 765 yylval.string = yytext; 766 return GSSAPIENC_ANY; 767 } 768 769 <start_encryption>clear { 770 yylval.string = yytext; 771 return GSSAPIENC_CLEAR; 772 } 773 774 <start_encryption>integrity { 775 yylval.string = yytext; 776 return GSSAPIENC_INTEGRITY; 777 } 778 779 <start_encryption>confidentiality { 780 yylval.string = yytext; 781 return GSSAPIENC_CONFIDENTIALITY; 782 } 783 784 <start_encryption>permessage { 785 yylval.string = yytext; 786 return GSSAPIENC_PERMESSAGE; 787 } 788 789 <start_realmname>[^: \t\n]+ { 790 yylval.string = yytext; 791 return REALNAME; 792 } 793 794 <start_method>none { 795 yylval.method = AUTHMETHOD_NONE; 796 return METHODNAME; 797 } 798 799 <start_method>gssapi { 800 yylval.method = AUTHMETHOD_GSSAPI; 801 return METHODNAME; 802 } 803 804 <start_method>username { 805 yylval.method = AUTHMETHOD_UNAME; 806 return METHODNAME; 807 } 808 809 <start_method>rfc931 { 810 yylval.method = AUTHMETHOD_RFC931; 811 return METHODNAME; 812 } 813 814 <start_method>pam.any { 815 yylval.number = AUTHMETHOD_PAM_ANY; 816 return METHODNAME; 817 } 818 819 <start_method>pam.address { 820 yylval.method = AUTHMETHOD_PAM_ADDRESS; 821 return METHODNAME; 822 } 823 824 <start_method>pam.username { 825 yylval.method = AUTHMETHOD_PAM_USERNAME; 826 return METHODNAME; 827 } 828 829 <start_method>pam { 830 yywarnx_deprecated(yytext, "pam.*"); 831 832 yylval.method = AUTHMETHOD_PAM_USERNAME; 833 return METHODNAME; 834 } 835 836 837 <start_method>bsdauth { 838 yylval.method = AUTHMETHOD_BSDAUTH; 839 return METHODNAME; 840 } 841 842 <start_method>ldapauth { 843 yylval.method = AUTHMETHOD_LDAPAUTH; 844 return METHODNAME; 845 } 846 847 /* non-start condition dependents. */ 848 849 eq|=|ne|!=|ge|>=|le|<=|gt|>|lt|< { 850 BEGIN(start_servicename); 851 852 yylval.string = yytext; 853 return OPERATOR; 854 } 855 856 {LS}client/[ ]+(pass|block) { 857 inclientrule = 1; 858 859 yylval.string = yytext; 860 return CLIENTRULE; 861 } 862 863 {LS}hostid/[ ]+(pass|block) { 864 yylval.string = yytext; 865 return HOSTIDRULE; 866 } 867 868 {LS}socks/[ ]+(pass|block) { 869 yylval.string = yytext; 870 return SOCKSRULE; 871 } 872 873 {LS}(pass|block) { /* deprecated socks rule syntax, without "socks "-prefix. */ 874 #if SOCKS_CLIENT 875 876 yyerrorx("pass/block rules are not used in the client"); 877 878 #else /* server */ 879 char old[256], new[256]; 880 881 snprintf(old, sizeof(old), "%s", yytext); 882 STRIPTRAILING(old, strlen(old), " \t"); 883 884 snprintf(new, sizeof(new), "socks %s", old); 885 886 yywarnx_deprecated(old, new); 887 888 yyless(0); 889 890 return SOCKSRULE; 891 892 #endif /* server */ 893 } 894 895 896 alarm.data { 897 yylval.string = yytext; 898 return ALARMTYPE_DATA; 899 } 900 901 alarm.disconnect { 902 yylval.string = yytext; 903 return ALARMTYPE_DISCONNECT; 904 } 905 906 alarm/\. { 907 BEGIN(start_alarmtest); 908 909 yylval.string = yytext; 910 return ALARM; 911 } 912 913 914 \.recv/[[:space:]]*: { 915 yylval.string = yytext; 916 return RECVSIDE; 917 } 918 919 \.send/[[:space:]]*: { 920 yylval.string = yytext; 921 return SENDSIDE; 922 } 923 924 debug { 925 yylval.string = yytext; 926 return DEBUGGING; 927 } 928 929 {LS}route { 930 inroute = 1; 931 932 yylval.string = yytext; 933 return ROUTE; 934 } 935 936 route { 937 yylval.string = yytext; 938 return ROUTE; 939 } 940 941 942 route\. { 943 yylval.string = yytext; 944 return GLOBALROUTEOPTION; 945 } 946 947 948 maxfail { 949 yylval.string = yytext; 950 return MAXFAIL; 951 } 952 953 badexpire { 954 yylval.string = yytext; 955 return BADROUTE_EXPIRE; 956 } 957 958 resolveprotocol { 959 BEGIN(start_protocol); 960 961 yylval.string = yytext; 962 return RESOLVEPROTOCOL; 963 } 964 965 srchost { 966 BEGIN(start_srchost); 967 968 yylval.string = yytext; 969 return SRCHOST; 970 } 971 972 proxyprotocol { 973 BEGIN(start_proxyprotocol); 974 975 yylval.string = yytext; 976 return PROXYPROTOCOL; 977 } 978 979 errorlog { 980 BEGIN(start_logoutput); 981 982 yylval.string = yytext; 983 return ERRORLOG; 984 } 985 986 logoutput { 987 BEGIN(start_logoutput); 988 989 yylval.string = yytext; 990 return LOGOUTPUT; 991 } 992 993 994 protocol { 995 BEGIN(start_protocol); 996 997 yylval.string = yytext; 998 return PROTOCOL; 999 } 1000 1001 command { 1002 BEGIN(start_command); 1003 1004 yylval.string = yytext; 1005 return COMMAND; 1006 } 1007 1008 udp\.portrange { 1009 yylval.string = yytext; 1010 return UDPPORTRANGE; 1011 } 1012 1013 udp\.connectdst { 1014 yylval.string = yytext; 1015 return UDPCONNECTDST; 1016 } 1017 1018 redirect { 1019 yylval.string = yytext; 1020 return REDIRECT; 1021 } 1022 1023 bandwidth { 1024 yylval.string = yytext; 1025 return BANDWIDTH; 1026 } 1027 1028 session\.max { 1029 yylval.string = yytext; 1030 return SESSIONMAX; 1031 } 1032 1033 session\.inheritable { 1034 yylval.string = yytext; 1035 return SESSION_INHERITABLE; 1036 } 1037 1038 session\.throttle { 1039 yylval.string = yytext; 1040 return SESSIONTHROTTLE; 1041 } 1042 1043 session\.state.key { 1044 BEGIN(start_statekey); 1045 1046 yylval.string = yytext; 1047 return SESSIONSTATE_KEY; 1048 } 1049 1050 session\.state.throttle { 1051 yylval.string = yytext; 1052 return SESSIONSTATE_THROTTLE; 1053 } 1054 1055 session\.state.max { 1056 yylval.string = yytext; 1057 return SESSIONSTATE_MAX; 1058 } 1059 1060 1061 in { 1062 yylval.string = yytext; 1063 return WORD__IN; 1064 } 1065 1066 from { 1067 BEGIN(start_address); 1068 1069 yylval.string = yytext; 1070 return FROM; 1071 } 1072 1073 to { 1074 BEGIN(start_address); 1075 1076 yylval.string = yytext; 1077 return TO; 1078 } 1079 1080 via { 1081 BEGIN(start_address); 1082 1083 yylval.string = yytext; 1084 return VIA; 1085 } 1086 1087 yes { 1088 yylval.string = yytext; 1089 return YES; 1090 } 1091 1092 no { 1093 yylval.string = yytext; 1094 return NO; 1095 } 1096 1097 internal\./{SOCKETLEVEL}\. { 1098 BEGIN(start_socketprotocol); 1099 1100 yylval.string = yytext; 1101 return INTERNALSOCKET; 1102 } 1103 1104 internal\./alarm\. { 1105 yylval.string = yytext; 1106 return ALARMIF_INTERNAL; 1107 } 1108 1109 internal\.log/\. { 1110 BEGIN(start_loglevel); 1111 1112 yylval.string = yytext; 1113 return LOGIF_INTERNAL; 1114 } 1115 1116 internal\.protocol { 1117 BEGIN(start_protocol); 1118 1119 yylval.string = yytext; 1120 return INTERNAL_PROTOCOL; 1121 } 1122 1123 1124 internal/[[:space:]]*: { 1125 BEGIN(start_address); 1126 1127 yylval.string = yytext; 1128 return INTERNAL; 1129 } 1130 1131 1132 external\./{SOCKETLEVEL}\. { 1133 BEGIN(start_socketprotocol); 1134 1135 yylval.string = yytext; 1136 return EXTERNALSOCKET; 1137 } 1138 1139 external\./alarm\. { 1140 yylval.string = yytext; 1141 return ALARMIF_EXTERNAL; 1142 } 1143 1144 external\.protocol { 1145 BEGIN(start_protocol); 1146 1147 yylval.string = yytext; 1148 return EXTERNAL_PROTOCOL; 1149 } 1150 1151 external\.rotation { 1152 yylval.string = yytext; 1153 return EXTERNAL_ROTATION; 1154 } 1155 1156 external\.log/\. { 1157 BEGIN(start_loglevel); 1158 1159 yylval.string = yytext; 1160 return LOGIF_EXTERNAL; 1161 } 1162 1163 external/[[:space:]]*: { 1164 BEGIN(start_address); 1165 1166 yylval.string = yytext; 1167 return EXTERNAL; 1168 } 1169 1170 none { 1171 yylval.string = yytext; 1172 return NONE; 1173 } 1174 1175 same-same { 1176 yylval.string = yytext; 1177 return SAMESAME; 1178 } 1179 1180 1181 child\.maxidle.*:.* { 1182 yywarnx_deprecated(yytext, NULL); 1183 } 1184 1185 child\.maxrequests { 1186 yylval.string = yytext; 1187 return PROC_MAXREQUESTS; 1188 } 1189 1190 child\.maxlifetime { 1191 yylval.string = yytext; 1192 return PROC_MAXLIFETIME; 1193 } 1194 1195 user { 1196 BEGIN(start_username); 1197 1198 yylval.string = yytext; 1199 return USER; 1200 } 1201 1202 group { 1203 BEGIN(start_groupname); 1204 1205 yylval.string = yytext; 1206 return GROUP; 1207 } 1208 1209 user\.privileged { 1210 BEGIN(start_username); 1211 1212 yylval.string = yytext; 1213 return USER_PRIVILEGED; 1214 } 1215 1216 user\.unprivileged|user\.notprivileged { 1217 BEGIN(start_username); 1218 1219 yylval.string = yytext; 1220 return USER_UNPRIVILEGED; 1221 } 1222 1223 user\.libwrap { 1224 BEGIN(start_username); 1225 1226 yylval.string = yytext; 1227 return USER_LIBWRAP; 1228 } 1229 1230 timeout\.connect { 1231 yylval.string = yytext; 1232 return CONNECTTIMEOUT; 1233 } 1234 1235 timeout\.tcp_fin_wait { 1236 yylval.string = yytext; 1237 return TCP_FIN_WAIT; 1238 } 1239 1240 1241 timeout\.io { 1242 yylval.string = yytext; 1243 return IOTIMEOUT; 1244 } 1245 1246 timeout\.io\.tcp { 1247 yylval.string = yytext; 1248 return IOTIMEOUT_TCP; 1249 } 1250 1251 timeout\.io\.udp { 1252 yylval.string = yytext; 1253 return IOTIMEOUT_UDP; 1254 } 1255 1256 timeout\.negotiate { 1257 yylval.string = yytext; 1258 return NEGOTIATETIMEOUT; 1259 } 1260 1261 1262 compatibility { 1263 yylval.string = yytext; 1264 return COMPATIBILITY; 1265 } 1266 1267 sameport { 1268 yylval.string = yytext; 1269 return SAMEPORT; 1270 } 1271 1272 draft-5.05 { 1273 yylval.string = yytext; 1274 return DRAFT_5_05; 1275 } 1276 1277 clientcompatibility { 1278 yylval.string = yytext; 1279 return CLIENTCOMPATIBILITY; 1280 } 1281 1282 necgssapi { 1283 yylval.string = yytext; 1284 return NECGSSAPI; 1285 } 1286 1287 extension { 1288 yylval.string = yytext; 1289 return EXTENSION; 1290 } 1291 1292 bind { 1293 yylval.string = yytext; 1294 return BIND; 1295 } 1296 1297 hostid { 1298 BEGIN(start_address); 1299 1300 yylval.string = yytext; 1301 return HOSTID; 1302 } 1303 1304 monitor { 1305 yylval.string = yytext; 1306 return MONITOR; 1307 } 1308 1309 <start_statekey,INITIAL>hostindex { 1310 BEGIN(start_hostindex); 1311 1312 yylval.string = yytext; 1313 return HOSTINDEX; 1314 } 1315 1316 <start_hostindex>any { 1317 BEGIN(0); 1318 1319 yylval.number = 0; 1320 return NUMBER; 1321 } 1322 1323 1324 socksmethod { 1325 BEGIN(start_method); 1326 1327 yylval.string = yytext; 1328 return SOCKSMETHOD; 1329 } 1330 1331 clientmethod { 1332 BEGIN(start_method); 1333 1334 yylval.string = yytext; 1335 return CLIENTMETHOD; 1336 } 1337 1338 method { 1339 BEGIN(start_method); 1340 1341 yylval.string = yytext; 1342 1343 if (inroute) 1344 return METHOD; 1345 else if (inclientrule) { 1346 yywarnx_deprecated(yytext, "clientmethod"); 1347 return CLIENTMETHOD; 1348 } 1349 else /* anywhere else; must be socksmethod. */ 1350 yywarnx_deprecated(yytext, "socksmethod"); 1351 1352 return SOCKSMETHOD; 1353 } 1354 1355 1356 /* filterrules */ 1357 1358 /* 1359 * verdicts 1360 */ 1361 1362 block { 1363 yylval.string = yytext; 1364 return VERDICT_BLOCK; 1365 } 1366 1367 pass { 1368 yylval.string = yytext; 1369 return VERDICT_PASS; 1370 } 1371 1372 log/: { 1373 BEGIN(start_log); 1374 1375 yylval.string = yytext; 1376 return RULE_LOG; 1377 } 1378 1379 1380 libwrap { 1381 BEGIN(lineprefix); 1382 1383 yylval.string = yytext; 1384 return LIBWRAPSTART; 1385 } 1386 1387 libwrap\.allow { 1388 BEGIN(start_libwrapfile); 1389 1390 yylval.string = yytext; 1391 return LIBWRAP_ALLOW; 1392 } 1393 1394 libwrap\.deny { 1395 BEGIN(start_libwrapfile); 1396 1397 yylval.string = yytext; 1398 return LIBWRAP_DENY; 1399 } 1400 1401 libwrap\.hosts_access { 1402 yylval.string = yytext; 1403 return LIBWRAP_HOSTS_ACCESS; 1404 } 1405 1406 pam\.servicename|pamservicename { 1407 BEGIN(start_servicename); 1408 1409 yylval.string = yytext; 1410 return PAMSERVICENAME; 1411 } 1412 1413 bsdauth\.stylename { 1414 BEGIN(start_bsdauthstylename); 1415 1416 yylval.string = yytext; 1417 return BSDAUTHSTYLE; 1418 } 1419 1420 gssapi\.servicename { 1421 BEGIN(start_gssapiservicename); 1422 1423 yylval.string = yytext; 1424 return GSSAPISERVICE; 1425 } 1426 1427 gssapi\.keytab { 1428 BEGIN(start_gssapikeytabname); 1429 1430 yylval.string = yytext; 1431 return GSSAPIKEYTAB; 1432 } 1433 1434 gssapi\.enctype { 1435 BEGIN(start_encryption); 1436 1437 yylval.string = yytext; 1438 return GSSAPIENCTYPE; 1439 } 1440 1441 ldap\.basedn { 1442 BEGIN(start_ldapbasedn); 1443 1444 yylval.string = yytext; 1445 return LDAPBASEDN; 1446 } 1447 1448 ldap\.basedn\.hex { 1449 BEGIN(start_ldapbasedn); 1450 1451 yylval.string = yytext; 1452 return LDAPBASEDN_HEX; 1453 } 1454 1455 ldap\.basedn\.hex\.all { 1456 BEGIN(start_ldapbasedn); 1457 1458 yylval.string = yytext; 1459 return LDAPBASEDN_HEX_ALL; 1460 } 1461 1462 ldap\.auth\.basedn { 1463 BEGIN(start_ldapbasedn); 1464 1465 yylval.string = yytext; 1466 return LDAPAUTHBASEDN; 1467 } 1468 1469 ldap\.auth\.basedn\.hex { 1470 BEGIN(start_ldapbasedn); 1471 1472 yylval.string = yytext; 1473 return LDAPAUTHBASEDN_HEX; 1474 } 1475 1476 ldap\.auth\.basedn\.hex\.all { 1477 BEGIN(start_ldapbasedn); 1478 1479 yylval.string = yytext; 1480 return LDAPAUTHBASEDN_HEX_ALL; 1481 } 1482 1483 ldap\.port { 1484 yylval.string = yytext; 1485 return LDAPPORT; 1486 } 1487 1488 ldap\.auth\.port { 1489 yylval.string = yytext; 1490 return LDAPAUTHPORT; 1491 } 1492 1493 ldap\.port\.ssl { 1494 yylval.string = yytext; 1495 return LDAPPORTSSL; 1496 } 1497 1498 ldap\.auth\.port\.ssl { 1499 yylval.string = yytext; 1500 return LDAPAUTHPORTSSL; 1501 } 1502 1503 ldap\.url { 1504 BEGIN(start_ldapurl); 1505 1506 yylval.string = yytext; 1507 return LDAPURL; 1508 } 1509 1510 ldap\.auth\.url { 1511 BEGIN(start_ldapurl); 1512 1513 yylval.string = yytext; 1514 return LDAPAUTHURL; 1515 } 1516 1517 ldap\.certfile { 1518 BEGIN(start_ldapcertfile); 1519 1520 yylval.string = yytext; 1521 return LDAPCERTFILE; 1522 } 1523 1524 ldap\.auth\.certfile { 1525 BEGIN(start_ldapcertfile); 1526 1527 yylval.string = yytext; 1528 return LDAPAUTHCERTFILE; 1529 } 1530 1531 ldap\.certpath { 1532 BEGIN(start_ldapcertpath); 1533 1534 yylval.string = yytext; 1535 return LDAPCERTPATH; 1536 } 1537 1538 ldap\.auth\.certpath { 1539 BEGIN(start_ldapcertpath); 1540 1541 yylval.string = yytext; 1542 return LDAPAUTHCERTPATH; 1543 } 1544 1545 ldap\.domain { 1546 BEGIN(start_ldapdomain); 1547 1548 yylval.string = yytext; 1549 return LDAPDOMAIN; 1550 } 1551 1552 ldap\.auth\.domain { 1553 BEGIN(start_ldapdomain); 1554 1555 yylval.string = yytext; 1556 return LDAPAUTHDOMAIN; 1557 } 1558 1559 ldap\.debug { 1560 yylval.string = yytext; 1561 return LDAPDEBUG; 1562 } 1563 1564 ldap\.auth\.debug { 1565 yylval.string = yytext; 1566 return LDAPAUTHDEBUG; 1567 } 1568 1569 ldap\.mdepth { 1570 yylval.string = yytext; 1571 return LDAPDEPTH; 1572 } 1573 1574 ldap\.ssl { 1575 yylval.string = yytext; 1576 return LDAPSSL; 1577 } 1578 1579 ldap\.auth\.ssl { 1580 yylval.string = yytext; 1581 return LDAPAUTHSSL; 1582 } 1583 1584 ldap\.auto\.off { 1585 yylval.string = yytext; 1586 return LDAPAUTO; 1587 } 1588 1589 ldap\.auth\.auto\.off { 1590 yylval.string = yytext; 1591 return LDAPAUTHAUTO; 1592 } 1593 1594 ldap\.certcheck { 1595 yylval.string = yytext; 1596 return LDAPCERTCHECK; 1597 } 1598 1599 ldap\.auth\.certcheck { 1600 yylval.string = yytext; 1601 return LDAPAUTHCERTCHECK; 1602 } 1603 1604 ldap\.keeprealm { 1605 yylval.string = yytext; 1606 return LDAPKEEPREALM; 1607 } 1608 1609 ldap\.filter { 1610 BEGIN(start_ldapfilter); 1611 1612 yylval.string = yytext; 1613 return LDAPFILTER; 1614 } 1615 1616 ldap\.auth\.filter { 1617 BEGIN(start_ldapfilter); 1618 1619 yylval.string = yytext; 1620 return LDAPAUTHFILTER; 1621 } 1622 1623 ldap\.filter\.ad { 1624 BEGIN(start_ldapfilter); 1625 1626 yylval.string = yytext; 1627 return LDAPFILTER_AD; 1628 } 1629 1630 ldap\.filter\.hex { 1631 BEGIN(start_ldapfilter); 1632 1633 yylval.string = yytext; 1634 return LDAPFILTER_HEX; 1635 } 1636 1637 ldap\.filter\.ad\.hex { 1638 BEGIN(start_ldapfilter); 1639 1640 yylval.string = yytext; 1641 return LDAPFILTER_AD_HEX; 1642 } 1643 1644 ldap\.attribute { 1645 BEGIN(start_ldapattribute); 1646 1647 yylval.string = yytext; 1648 return LDAPATTRIBUTE; 1649 } 1650 1651 ldap\.attribute\.ad { 1652 BEGIN(start_ldapattribute); 1653 1654 yylval.string = yytext; 1655 return LDAPATTRIBUTE_AD; 1656 } 1657 1658 ldap\.attribute\.hex { 1659 BEGIN(start_ldapattribute); 1660 1661 yylval.string = yytext; 1662 return LDAPATTRIBUTE_HEX; 1663 } 1664 1665 ldap\.attribute\.ad\.hex { 1666 BEGIN(start_ldapattribute); 1667 1668 yylval.string = yytext; 1669 return LDAPATTRIBUTE_AD_HEX; 1670 } 1671 1672 ldap\.server { 1673 BEGIN(start_ldapservername); 1674 1675 yylval.string = yytext; 1676 return LDAPSERVER; 1677 } 1678 1679 ldap\.auth\.server { 1680 BEGIN(start_ldapservername); 1681 1682 yylval.string = yytext; 1683 return LDAPAUTHSERVER; 1684 } 1685 1686 ldap\.group { 1687 BEGIN(start_ldapgroupname); 1688 1689 yylval.string = yytext; 1690 return LDAPGROUP; 1691 } 1692 1693 ldap\.group\.hex { 1694 BEGIN(start_ldapgroupname); 1695 1696 yylval.string = yytext; 1697 return LDAPGROUP_HEX; 1698 } 1699 1700 ldap\.group\.hex\.all { 1701 BEGIN(start_ldapgroupname); 1702 1703 yylval.string = yytext; 1704 return LDAPGROUP_HEX_ALL; 1705 } 1706 1707 ldap\.keytab { 1708 BEGIN(start_ldapkeytabname); 1709 1710 yylval.string = yytext; 1711 return LDAPKEYTAB; 1712 } 1713 1714 ldap\.auth\.keytab { 1715 BEGIN(start_ldapkeytabname); 1716 1717 yylval.string = yytext; 1718 return LDAPAUTHKEYTAB; 1719 } 1720 1721 pac\.sid\.b64 { 1722 BEGIN(start_pacsidname); 1723 1724 yylval.string = yytext; 1725 return PACSID_B64; 1726 } 1727 1728 pac\.sid { 1729 BEGIN(start_pacsidname); 1730 1731 yylval.string = yytext; 1732 return PACSID; 1733 } 1734 1735 pac\.off { 1736 yylval.string = yytext; 1737 return PACSID_FLAG; 1738 } 1739 1740 bounce { 1741 yylval.string = yytext; 1742 return BOUNCE; 1743 } 1744 1745 realm { 1746 BEGIN(start_realmname); 1747 1748 yylval.string = yytext; 1749 return REALM; 1750 } 1751 1752 /* 1753 * global keywords that are no longer used. 1754 */ 1755 1756 localdomain.*:.* { 1757 yywarnx_deprecated(yytext, NULL); 1758 } 1759 1760 connecttimeout { 1761 yywarnx_deprecated(yytext, "timeout.connect"); 1762 1763 yylval.string = yytext; 1764 return CONNECTTIMEOUT; 1765 } 1766 1767 iotimeout { 1768 yywarnx_deprecated(yytext, "timeout.io"); 1769 1770 yylval.string = yytext; 1771 return IOTIMEOUT; 1772 } 1773 1774 socket.(recvbuf|sendbuf).(tcp|udp) { 1775 yylval.deprecated.oldname = yytext; 1776 1777 yylval.deprecated.newname = 1778 "a general socket api. E.g. \"internal.tcp.so_rcvbuf\" for setting " 1779 "the socket receive buffer size on the internal interface side, or " 1780 "\"external.tcp.so_sndbuf\" for setting the socket send buffer size on " 1781 "the external interface side. Please see manual for more information"; 1782 1783 return DEPRECATED; 1784 } 1785 1786 1787 /* misc. generic stuff. */ 1788 1789 /* 1790 * note that to support negative numbers we need to handle number ranges 1791 * like port 1-65535 correctly also. 1792 */ 1793 <*>([0-9]|0x[a-fA-F0-9])+ { 1794 char *ep; 1795 long long llval; 1796 1797 errno = 0; 1798 llval = strtoll(yytext, &ep, 0); 1799 if (*yytext == NUL || *ep != NUL) 1800 yyerror("confusing. Thought we would have a number here"); 1801 1802 if (errno == ERANGE) 1803 yyerror("number given is out of range"); 1804 1805 yylval.number = llval; 1806 1807 if (shouldresetstate(YYSTATE, NUMBER)) 1808 BEGIN(0); 1809 1810 return NUMBER; 1811 } 1812 1813 /* ignored */ 1814 <*>[[:blank:]]+ { 1815 ; 1816 } 1817 1818 /* shell style comment */ 1819 <*>#.* { 1820 BEGIN(0); 1821 ; 1822 } 1823 1824 /* state always ends at eol ... */ 1825 <*>\n { 1826 BEGIN(0); 1827 } 1828 1829 /* ... unless it's escaped. */ 1830 <*>\\\n { 1831 ; 1832 } 1833 1834 <*>\} { 1835 inclientrule = inroute = 0; 1836 1837 yylval.string = yytext; 1838 return *yytext; 1839 } 1840 1841 <*>. { 1842 yylval.string = yytext; 1843 return *yytext; 1844 } 1845 1846 %% 1847 1848 static int 1849 shouldresetstate(current_state, next_token) 1850 const int current_state; 1851 const int next_token; 1852 { 1853 switch (current_state) { 1854 case start_hostindex: 1855 case start_schedulemask: 1856 case start_servicename: 1857 switch (next_token) { 1858 case NUMBER: 1859 return 1; 1860 } 1861 break; 1862 } 1863 1864 return 0; 1865 } 1866