X-Git-Url: http://git.pk910.de/?a=blobdiff_plain;f=ircd%2Fircd_parser.y;h=83cab62fb0483bdbb8fc36f4adf6b1bd9e2b0109;hb=refs%2Fheads%2Fupstream;hp=dc815f937cfee5cf0e3cb35cc41c1a479ee6b877;hpb=f201a4605fb3c20f6bb5bc32034b35a1855591b7;p=ircu2.10.12-pk.git diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y index dc815f9..83cab62 100644 --- a/ircd/ircd_parser.y +++ b/ircd/ircd_parser.y @@ -60,8 +60,8 @@ #include #define MAX_STRINGS 80 /* Maximum number of feature params. */ -#define USE_IPV4 (1 << 0) -#define USE_IPV6 (1 << 1) +#define USE_IPV4 (1 << 16) +#define USE_IPV6 (1 << 17) extern struct LocalConf localConf; extern struct DenyConf* denyConfList; @@ -175,15 +175,19 @@ static void free_slist(struct SLink **link) { %token PROGRAM %token TOK_IPV4 TOK_IPV6 %token DNS +%token SSL +%token CERTFILE +%token KEYFILE +%token CAFILE /* and now a lot of privileges... */ %token TPRIV_CHAN_LIMIT TPRIV_MODE_LCHAN TPRIV_DEOP_LCHAN TPRIV_WALK_LCHAN %token TPRIV_LOCAL_KILL TPRIV_REHASH TPRIV_RESTART TPRIV_DIE %token TPRIV_GLINE TPRIV_LOCAL_GLINE TPRIV_LOCAL_JUPE TPRIV_LOCAL_BADCHAN %token TPRIV_LOCAL_OPMODE TPRIV_OPMODE TPRIV_SET TPRIV_WHOX TPRIV_BADCHAN %token TPRIV_SEE_CHAN TPRIV_SHOW_INVIS TPRIV_SHOW_ALL_INVIS TPRIV_PROPAGATE -%token TPRIV_UNLIMIT_QUERY TPRIV_DISPLAY TPRIV_SEE_OPERS TPRIV_WIDE_GLINE -%token TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE TPRIV_APASS_OPMODE -%token TPRIV_LIST_CHAN +%token TPRIV_UNLIMIT_QUERY TPRIV_UNLIMIT_FLOOD TPRIV_DISPLAY TPRIV_SEE_OPERS +%token TPRIV_WIDE_GLINE TPRIV_FORCE_OPMODE TPRIV_FORCE_LOCAL_OPMODE +%token TPRIV_APASS_OPMODE TPRIV_LIST_CHAN /* and some types... */ %type sizespec %type timespec timefactor factoredtimes factoredtime @@ -199,7 +203,7 @@ static void free_slist(struct SLink **link) { %% /* Blocks in the config file... */ blocks: blocks block | block; -block: adminblock | generalblock | classblock | connectblock | +block: adminblock | generalblock | classblock | connectblock | sslblock | uworldblock | operblock | portblock | jupeblock | clientblock | killblock | cruleblock | motdblock | featuresblock | quarantineblock | pseudoblock | iauthblock | error ';'; @@ -406,6 +410,40 @@ admincontact: CONTACT '=' QSTRING ';' localConf.contact = $3; }; +sslblock: SSL +{ + MyFree(localConf.sslcertfile); + MyFree(localConf.sslkeyfile); + MyFree(localConf.sslcafile); + localConf.sslcertfile = localConf.sslkeyfile = localConf.sslcafile = NULL; +} +'{' sslitems '}' ';' +{ + if (localConf.sslcertfile == NULL) + DupString(localConf.sslcertfile, ""); + if (localConf.sslkeyfile == NULL) + DupString(localConf.sslkeyfile, ""); + if (localConf.sslcafile == NULL) + DupString(localConf.sslcafile, ""); +}; +sslitems: sslitems sslitem | sslitem; +sslitem: sslcertfile | sslkeyfile | sslcafile; +sslcertfile: CERTFILE '=' QSTRING ';' +{ + MyFree(localConf.sslcertfile); + localConf.sslcertfile = $3; +}; +sslkeyfile: KEYFILE '=' QSTRING ';' +{ + MyFree(localConf.sslkeyfile); + localConf.sslkeyfile = $3; +}; +sslcafile: CAFILE '=' QSTRING ';' +{ + MyFree(localConf.sslcafile); + localConf.sslcafile = $3; +}; + classblock: CLASS { tping = 90; } '{' classitems '}' ';' @@ -463,7 +501,6 @@ classusermode: USERMODE '=' QSTRING ';' connectblock: CONNECT { - maxlinks = 65535; flags = CONF_AUTOCONNECT; } '{' connectitems '}' ';' { @@ -488,7 +525,10 @@ connectblock: CONNECT aconf->conn_class = c_class; aconf->address.port = port; aconf->host = host; - aconf->maximum = maxlinks; + /* If the user specified a hub allowance, but not maximum links, + * allow an effectively unlimited number of hops. + */ + aconf->maximum = (hub_limit != NULL && maxlinks == 0) ? 65535 : maxlinks; aconf->hub_limit = hub_limit; aconf->flags = flags; lookup_confhost(aconf); @@ -502,7 +542,7 @@ connectblock: CONNECT } name = pass = host = origin = hub_limit = NULL; c_class = NULL; - port = flags = 0; + port = flags = maxlinks = 0; }; connectitems: connectitem connectitems | connectitem; connectitem: connectname | connectpass | connectclass | connecthost @@ -672,6 +712,7 @@ privtype: TPRIV_CHAN_LIMIT { $$ = PRIV_CHAN_LIMIT; } | TPRIV_SHOW_ALL_INVIS { $$ = PRIV_SHOW_ALL_INVIS; } | TPRIV_PROPAGATE { $$ = PRIV_PROPAGATE; } | TPRIV_UNLIMIT_QUERY { $$ = PRIV_UNLIMIT_QUERY; } | + TPRIV_UNLIMIT_FLOOD { $$ = PRIV_UNLIMIT_FLOOD; } | TPRIV_DISPLAY { $$ = PRIV_DISPLAY; } | TPRIV_SEE_OPERS { $$ = PRIV_SEE_OPERS; } | TPRIV_WIDE_GLINE { $$ = PRIV_WIDE_GLINE; } | @@ -695,45 +736,77 @@ address_family: ; /* The port block... */ -portblock: PORT '{' portitems '}' ';' -{ - if (!FlagHas(&listen_flags, LISTEN_IPV4) - && !FlagHas(&listen_flags, LISTEN_IPV6)) - { - FlagSet(&listen_flags, LISTEN_IPV4); - FlagSet(&listen_flags, LISTEN_IPV6); +portblock: PORT '{' portitems '}' ';' { + struct ListenerFlags flags_here; + struct SLink *link; + if (hosts == NULL) { + struct SLink *link; + link = make_link(); + DupString(link->value.cp, "*"); + link->flags = 0; + link->next = hosts; + hosts = link; } - if (port > 0 && port <= 0xFFFF) - add_listener(port, host, pass, &listen_flags); - else - parse_error("Port %d is out of range", port); - MyFree(host); + for (link = hosts; link != NULL; link = link->next) { + memcpy(&flags_here, &listen_flags, sizeof(flags_here)); + switch (link->flags & (USE_IPV4 | USE_IPV6)) { + case USE_IPV4: + FlagSet(&flags_here, LISTEN_IPV4); + break; + case USE_IPV6: + FlagSet(&flags_here, LISTEN_IPV6); + break; + default: /* 0 or USE_IPV4|USE_IPV6 */ + FlagSet(&flags_here, LISTEN_IPV4); + FlagSet(&flags_here, LISTEN_IPV6); + break; + } + + if (link->flags & 65535) + port = link->flags & 65535; + add_listener(port, link->value.cp, pass, &flags_here); + } + free_slist(&hosts); MyFree(pass); memset(&listen_flags, 0, sizeof(listen_flags)); - host = pass = NULL; + pass = NULL; port = 0; }; portitems: portitem portitems | portitem; -portitem: portnumber | portvhost | portmask | portserver | porthidden; +portitem: portnumber | portvhost | portvhostnumber | portmask | portserver | portssl | porthidden; portnumber: PORT '=' address_family NUMBER ';' { - int families = $3; - if (families & USE_IPV4) - FlagSet(&listen_flags, LISTEN_IPV4); - else if (families & USE_IPV6) - FlagSet(&listen_flags, LISTEN_IPV6); - port = $4; + if ($4 < 1 || $4 > 65535) { + parse_error("Port %d is out of range", port); + } else { + port = $3 | $4; + if (hosts && (0 == (hosts->flags & 65535))) + hosts->flags = (hosts->flags & ~65535) | port; + } }; portvhost: VHOST '=' address_family QSTRING ';' { - int families = $3; - if (families & USE_IPV4) - FlagSet(&listen_flags, LISTEN_IPV4); - else if (families & USE_IPV6) - FlagSet(&listen_flags, LISTEN_IPV6); - MyFree(host); - host = $4; + struct SLink *link; + link = make_link(); + link->value.cp = $4; + link->flags = $3 | port; + link->next = hosts; + hosts = link; +}; + +portvhostnumber: VHOST '=' address_family QSTRING NUMBER ';' +{ + if ($5 < 1 || $5 > 65535) { + parse_error("Port %d is out of range", port); + } else { + struct SLink *link; + link = make_link(); + link->value.cp = $4; + link->flags = $3 | $5; + link->next = hosts; + hosts = link; + } }; portmask: MASK '=' QSTRING ';' @@ -750,6 +823,14 @@ portserver: SERVER '=' YES ';' FlagClr(&listen_flags, LISTEN_SERVER); }; +portssl: SSL '=' YES ';' +{ + FlagSet(&listen_flags, LISTEN_SSL); +} | SSL '=' NO ';' +{ + FlagClr(&listen_flags, LISTEN_SSL); +}; + porthidden: HIDDEN '=' YES ';' { FlagSet(&listen_flags, LISTEN_HIDDEN); @@ -799,6 +880,7 @@ clientblock: CLIENT host = NULL; username = NULL; c_class = NULL; + maxlinks = 0; ip = NULL; pass = NULL; port = 0; @@ -931,28 +1013,30 @@ cruleblock: CRULE } '{' cruleitems '}' ';' { struct CRuleNode *node = NULL; - if (host == NULL) - parse_error("Missing host in crule block"); + struct SLink *link; + + if (hosts == NULL) + parse_error("Missing server(s) in crule block"); else if (pass == NULL) parse_error("Missing rule in crule block"); else if ((node = crule_parse(pass)) == NULL) parse_error("Invalid rule '%s' in crule block", pass); - else + else for (link = hosts; link != NULL; link = link->next) { struct CRuleConf *p = (struct CRuleConf*) MyMalloc(sizeof(*p)); - p->hostmask = host; - p->rule = pass; + if (node == NULL) + node = crule_parse(pass); + DupString(p->hostmask, link->value.cp); + DupString(p->rule, pass); p->type = tconn; p->node = node; + node = NULL; p->next = cruleConfList; cruleConfList = p; } - if (!node) - { - MyFree(host); - MyFree(pass); - } - host = pass = NULL; + free_slist(&hosts); + MyFree(pass); + pass = NULL; tconn = 0; }; @@ -961,9 +1045,11 @@ cruleitem: cruleserver | crulerule | cruleall; cruleserver: SERVER '=' QSTRING ';' { - MyFree(host); - collapse($3); - host = $3; + struct SLink *link; + link = make_link(); + link->value.cp = $3; + link->next = hosts; + hosts = link; }; crulerule: RULE '=' QSTRING ';' @@ -1055,6 +1141,8 @@ pseudoitems '}' ';' parse_error("Missing name in pseudo %s block", smap->command); else if (!smap->services) parse_error("Missing nick in pseudo %s block", smap->command); + else if (!strIsAlpha(smap->command)) + parse_error("Pseudo command %s invalid: must all be letters", smap->command); else valid = 1; if (valid && register_mapping(smap)) @@ -1104,7 +1192,10 @@ iauthblock: IAUTH '{' iauthitems '}' ';' { auth_spawn(stringno, stringlist); while (stringno > 0) - MyFree(stringlist[--stringno]); + { + --stringno; + MyFree(stringlist[stringno]); + } }; iauthitems: iauthitem iauthitems | iauthitem; @@ -1112,5 +1203,8 @@ iauthitem: iauthprogram; iauthprogram: PROGRAM '=' { while (stringno > 0) - MyFree(stringlist[--stringno]); + { + --stringno; + MyFree(stringlist[stringno]); + } } stringlist ';';