--- ircd-hybrid/trunk/src/conf_parser.y 2015/10/22 17:52:15 6599 +++ ircd-hybrid/trunk/src/conf_parser.y 2020/10/31 19:05:15 9692 @@ -1,7 +1,7 @@ /* * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) * - * Copyright (c) 2000-2015 ircd-hybrid development team + * Copyright (c) 2000-2020 ircd-hybrid development team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,41 +27,31 @@ %{ -#include -#include - #include "config.h" #include "stdinc.h" #include "ircd.h" #include "list.h" +#include "parse.h" #include "conf.h" #include "conf_class.h" +#include "conf_cluster.h" +#include "conf_gecos.h" #include "conf_pseudo.h" +#include "conf_resv.h" +#include "conf_service.h" +#include "conf_shared.h" #include "event.h" #include "id.h" #include "log.h" -#include "client.h" /* for UMODE_SERVNOTICE only */ #include "irc_string.h" #include "memory.h" #include "modules.h" #include "server.h" #include "hostmask.h" -#include "send.h" #include "listener.h" -#include "resv.h" -#include "numeric.h" #include "user.h" #include "motd.h" -#ifdef HAVE_LIBCRYPTO -#include -#include -#include -#include -#endif - -#include "rsa.h" - int yylex(void); static struct @@ -101,16 +91,15 @@ static struct size, type, port, + timeout, aftype, ping_freq, - max_perip, + max_perip_local, + max_perip_global, con_freq, min_idle, max_idle, max_total, - max_global, - max_local, - max_ident, max_sendq, max_recvq, max_channels, @@ -122,27 +111,18 @@ static struct static void reset_block_state(void) { - dlink_node *node = NULL, *node_next = NULL; - - DLINK_FOREACH_SAFE(node, node_next, block_state.mask.list.head) - { - MyFree(node->data); - dlinkDelete(node, &block_state.mask.list); - free_dlink_node(node); - } - - DLINK_FOREACH_SAFE(node, node_next, block_state.leaf.list.head) - { - MyFree(node->data); - dlinkDelete(node, &block_state.leaf.list); - free_dlink_node(node); - } + dlink_node *node, *node_next; + dlink_list *tab[] = { &block_state.mask.list, + &block_state.leaf.list, &block_state.hub.list, NULL }; - DLINK_FOREACH_SAFE(node, node_next, block_state.hub.list.head) + for (dlink_list **list = tab; *list; ++list) { - MyFree(node->data); - dlinkDelete(node, &block_state.hub.list); - free_dlink_node(node); + DLINK_FOREACH_SAFE(node, node_next, (*list)->head) + { + xfree(node->data); + dlinkDelete(node, *list); + free_dlink_node(node); + } } memset(&block_state, 0, sizeof(block_state)); @@ -170,14 +150,17 @@ reset_block_state(void) %token CIDR_BITLEN_IPV4 %token CIDR_BITLEN_IPV6 %token CLASS +%token CLIENT %token CLOSE %token CONNECT %token CONNECTFREQ %token CYCLE_ON_HOST_CHANGE %token DEFAULT_FLOODCOUNT +%token DEFAULT_FLOODTIME %token DEFAULT_JOIN_FLOOD_COUNT %token DEFAULT_JOIN_FLOOD_TIME %token DEFAULT_MAX_CLIENTS +%token DEFER %token DENY %token DESCRIPTION %token DIE @@ -188,9 +171,11 @@ reset_block_state(void) %token DLINE_MIN_CIDR6 %token DOTS_IN_IDENT %token EMAIL +%token ENABLE_EXTBANS %token ENCRYPTED %token EXCEED_LIMIT %token EXEMPT +%token EXPIRATION %token FAILED_OPER_NOTICE %token FLATTEN_LINKS %token FLATTEN_LINKS_DELAY @@ -208,10 +193,11 @@ reset_block_state(void) %token HOST %token HUB %token HUB_MASK -%token IGNORE_BOGUS_TS %token INVISIBLE_ON_CONNECT %token INVITE_CLIENT_COUNT %token INVITE_CLIENT_TIME +%token INVITE_DELAY_CHANNEL +%token INVITE_EXPIRE_TIME %token IP %token IRCD_AUTH %token IRCD_FLAGS @@ -231,11 +217,10 @@ reset_block_state(void) %token MASK %token MAX_ACCEPT %token MAX_BANS +%token MAX_BANS_LARGE %token MAX_CHANNELS -%token MAX_GLOBAL -%token MAX_IDENT %token MAX_IDLE -%token MAX_LOCAL +%token MAX_INVITES %token MAX_NICK_CHANGES %token MAX_NICK_LENGTH %token MAX_NICK_TIME @@ -252,14 +237,15 @@ reset_block_state(void) %token NAME %token NEED_IDENT %token NEED_PASSWORD -%token NETWORK_DESC +%token NETWORK_DESCRIPTION %token NETWORK_NAME %token NICK %token NO_OPER_FLOOD %token NO_TILDE %token NUMBER %token NUMBER_PER_CIDR -%token NUMBER_PER_IP +%token NUMBER_PER_IP_GLOBAL +%token NUMBER_PER_IP_LOCAL %token OPER_ONLY_UMODES %token OPER_UMODES %token OPERATOR @@ -289,14 +275,7 @@ reset_block_state(void) %token SERVERINFO %token SHORT_MOTD %token SPOOF -%token SPOOF_NOTICE %token SQUIT -%token SSL_CERTIFICATE_FILE -%token SSL_CERTIFICATE_FINGERPRINT -%token SSL_CONNECTION_REQUIRED -%token SSL_DH_ELLIPTIC_CURVE -%token SSL_DH_PARAM_FILE -%token SSL_MESSAGE_DIGEST_ALGORITHM %token STATS_E_DISABLED %token STATS_I_OPER_ONLY %token STATS_K_OPER_ONLY @@ -305,7 +284,7 @@ reset_block_state(void) %token STATS_P_OPER_ONLY %token STATS_U_OPER_ONLY %token T_ALL -%token T_BOTS +%token T_BIND %token T_CALLERID %token T_CCONN %token T_COMMAND @@ -316,7 +295,7 @@ reset_block_state(void) %token T_EXTERNAL %token T_FARCONNECT %token T_FILE -%token T_FULL +%token T_FLOOD %token T_GLOBOPS %token T_INVISIBLE %token T_IPV4 @@ -340,11 +319,9 @@ reset_block_state(void) %token T_SKILL %token T_SOFTCALLERID %token T_SPY -%token T_SSL -%token T_SSL_CIPHER_LIST %token T_TARGET +%token T_TLS %token T_UMODES -%token T_UNAUTH %token T_UNDLINE %token T_UNLIMITED %token T_UNRESV @@ -355,8 +332,15 @@ reset_block_state(void) %token TBOOL %token THROTTLE_COUNT %token THROTTLE_TIME -%token TKLINE_EXPIRE_NOTICES -%token TMASKED +%token TIMEOUT +%token TLS_CERTIFICATE_FILE +%token TLS_CERTIFICATE_FINGERPRINT +%token TLS_CIPHER_LIST +%token TLS_CIPHER_SUITES +%token TLS_CONNECTION_REQUIRED +%token TLS_DH_PARAM_FILE +%token TLS_MESSAGE_DIGEST_ALGORITHM +%token TLS_SUPPORTED_GROUPS %token TS_MAX_DELTA %token TS_WARN_DELTA %token TWODOTS @@ -368,6 +352,7 @@ reset_block_state(void) %token VHOST6 %token WARN_NO_CONNECT_BLOCK %token WHOIS +%token WHOWAS_HISTORY_LENGTH %token XLINE %token XLINE_EXEMPT @@ -430,10 +415,9 @@ sizespec: NUMBER sizespec_ { $$ = $1 + /*************************************************************************** - * section modules + * modules {} section ***************************************************************************/ -modules_entry: MODULES - '{' modules_items '}' ';'; +modules_entry: MODULES '{' modules_items '}' ';'; modules_items: modules_items modules_item | modules_item; modules_item: modules_module | modules_path | error ';' ; @@ -451,232 +435,120 @@ modules_path: PATH '=' QSTRING ';' }; +/*************************************************************************** + * serverinfo {} section + ***************************************************************************/ serverinfo_entry: SERVERINFO '{' serverinfo_items '}' ';'; serverinfo_items: serverinfo_items serverinfo_item | serverinfo_item ; serverinfo_item: serverinfo_name | - serverinfo_vhost | serverinfo_hub | serverinfo_description | serverinfo_network_name | - serverinfo_network_desc | + serverinfo_network_description | serverinfo_default_max_clients | serverinfo_max_nick_length | serverinfo_max_topic_length | - serverinfo_ssl_dh_param_file | - serverinfo_ssl_dh_elliptic_curve | + serverinfo_tls_dh_param_file | + serverinfo_tls_supported_groups | serverinfo_rsa_private_key_file | - serverinfo_vhost6 | serverinfo_sid | - serverinfo_ssl_certificate_file | - serverinfo_ssl_cipher_list | - serverinfo_ssl_message_digest_algorithm | + serverinfo_tls_certificate_file | + serverinfo_tls_cipher_list | + serverinfo_tls_cipher_suites | + serverinfo_tls_message_digest_algorithm | error ';' ; -serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';' +serverinfo_tls_certificate_file: TLS_CERTIFICATE_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO if (conf_parser_ctx.pass == 2) { - if (!ConfigServerInfo.rsa_private_key_file) - { - conf_error_report("No rsa_private_key_file specified, SSL disabled"); - break; - } - - if (SSL_CTX_use_certificate_chain_file(ConfigServerInfo.server_ctx, yylval.string) <= 0 || - SSL_CTX_use_certificate_chain_file(ConfigServerInfo.client_ctx, yylval.string) <= 0) - { - report_crypto_errors(); - conf_error_report("Could not open/read certificate file"); - break; - } - - if (SSL_CTX_use_PrivateKey_file(ConfigServerInfo.server_ctx, ConfigServerInfo.rsa_private_key_file, - SSL_FILETYPE_PEM) <= 0 || - SSL_CTX_use_PrivateKey_file(ConfigServerInfo.client_ctx, ConfigServerInfo.rsa_private_key_file, - SSL_FILETYPE_PEM) <= 0) - { - report_crypto_errors(); - conf_error_report("Could not read RSA private key"); - break; - } - - if (!SSL_CTX_check_private_key(ConfigServerInfo.server_ctx) || - !SSL_CTX_check_private_key(ConfigServerInfo.client_ctx)) - { - report_crypto_errors(); - conf_error_report("Could not read RSA private key"); - break; - } + xfree(ConfigServerInfo.tls_certificate_file); + ConfigServerInfo.tls_certificate_file = xstrdup(yylval.string); } -#endif }; serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - BIO *file = NULL; - - if (conf_parser_ctx.pass != 1) - break; - - if (ConfigServerInfo.rsa_private_key) - { - RSA_free(ConfigServerInfo.rsa_private_key); - ConfigServerInfo.rsa_private_key = NULL; - } - - if (ConfigServerInfo.rsa_private_key_file) - { - MyFree(ConfigServerInfo.rsa_private_key_file); - ConfigServerInfo.rsa_private_key_file = NULL; - } - - ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string); - - if ((file = BIO_new_file(yylval.string, "r")) == NULL) + if (conf_parser_ctx.pass == 2) { - conf_error_report("File open failed, ignoring"); - break; - } - - ConfigServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL); - - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - - if (ConfigServerInfo.rsa_private_key == NULL) - { - conf_error_report("Couldn't extract key, ignoring"); - break; + xfree(ConfigServerInfo.rsa_private_key_file); + ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string); } +}; - if (!RSA_check_key(ConfigServerInfo.rsa_private_key)) +serverinfo_tls_dh_param_file: TLS_DH_PARAM_FILE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) { - RSA_free(ConfigServerInfo.rsa_private_key); - ConfigServerInfo.rsa_private_key = NULL; - - conf_error_report("Invalid key, ignoring"); - break; + xfree(ConfigServerInfo.tls_dh_param_file); + ConfigServerInfo.tls_dh_param_file = xstrdup(yylval.string); } - - if (RSA_size(ConfigServerInfo.rsa_private_key) < 128) - { - RSA_free(ConfigServerInfo.rsa_private_key); - ConfigServerInfo.rsa_private_key = NULL; - - conf_error_report("Ignoring serverinfo::rsa_private_key_file -- need at least a 1024 bit key size"); - } -#endif }; -serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';' +serverinfo_tls_cipher_list: TLS_CIPHER_LIST '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO if (conf_parser_ctx.pass == 2) { - BIO *file = BIO_new_file(yylval.string, "r"); - - if (file) - { - DH *dh = PEM_read_bio_DHparams(file, NULL, NULL, NULL); - - BIO_free(file); - - if (dh) - { - if (DH_size(dh) < 128) - conf_error_report("Ignoring serverinfo::ssl_dh_param_file -- need at least a 1024 bit DH prime size"); - else - SSL_CTX_set_tmp_dh(ConfigServerInfo.server_ctx, dh); - - DH_free(dh); - } - } - else - conf_error_report("Ignoring serverinfo::ssl_dh_param_file -- could not open/read Diffie-Hellman parameter file"); + xfree(ConfigServerInfo.tls_cipher_list); + ConfigServerInfo.tls_cipher_list = xstrdup(yylval.string); } -#endif }; -serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +serverinfo_tls_cipher_suites: TLS_CIPHER_SUITES '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO if (conf_parser_ctx.pass == 2) - SSL_CTX_set_cipher_list(ConfigServerInfo.server_ctx, yylval.string); -#endif + { + xfree(ConfigServerInfo.tls_cipher_suites); + ConfigServerInfo.tls_cipher_suites = xstrdup(yylval.string); + } }; -serverinfo_ssl_message_digest_algorithm: SSL_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';' +serverinfo_tls_message_digest_algorithm: TLS_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO if (conf_parser_ctx.pass == 2) { - if ((ConfigServerInfo.message_digest_algorithm = EVP_get_digestbyname(yylval.string)) == NULL) - { - ConfigServerInfo.message_digest_algorithm = EVP_sha256(); - conf_error_report("Ignoring serverinfo::ssl_message_digest_algorithm -- unknown message digest algorithm"); - } + xfree(ConfigServerInfo.tls_message_digest_algorithm); + ConfigServerInfo.tls_message_digest_algorithm = xstrdup(yylval.string); } -#endif } -serverinfo_ssl_dh_elliptic_curve: SSL_DH_ELLIPTIC_CURVE '=' QSTRING ';' +serverinfo_tls_supported_groups: TLS_SUPPORTED_GROUPS '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO -#if OPENSSL_VERSION_NUMBER >= 0x009080FFL && !defined(OPENSSL_NO_ECDH) - int nid = 0; - EC_KEY *key = NULL; - if (conf_parser_ctx.pass == 2) { - if ((nid = OBJ_sn2nid(yylval.string)) == 0) - { - conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- unknown curve name"); - break; - } - - if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) - { - conf_error_report("Ignoring serverinfo::ssl_dh_elliptic_curve -- could not create curve"); - break; - } - - SSL_CTX_set_tmp_ecdh(ConfigServerInfo.server_ctx, key); - EC_KEY_free(key); -} -#endif -#endif + xfree(ConfigServerInfo.tls_supported_groups); + ConfigServerInfo.tls_supported_groups = xstrdup(yylval.string); + } }; serverinfo_name: NAME '=' QSTRING ';' { - /* this isn't rehashable */ - if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.name) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && ConfigServerInfo.name == NULL) { - if (valid_servname(yylval.string)) + if (server_valid_name(yylval.string) == true) ConfigServerInfo.name = xstrdup(yylval.string); else { conf_error_report("Ignoring serverinfo::name -- invalid name. Aborting."); - exit(0); + exit(EXIT_FAILURE); } } }; serverinfo_sid: IRCD_SID '=' QSTRING ';' { - /* this isn't rehashable */ - if (conf_parser_ctx.pass == 2 && !ConfigServerInfo.sid) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && ConfigServerInfo.sid == NULL) { if (valid_sid(yylval.string)) ConfigServerInfo.sid = xstrdup(yylval.string); else { conf_error_report("Ignoring serverinfo::sid -- invalid SID. Aborting."); - exit(0); + exit(EXIT_FAILURE); } } }; @@ -685,7 +557,7 @@ serverinfo_description: DESCRIPTION '=' { if (conf_parser_ctx.pass == 2) { - MyFree(ConfigServerInfo.description); + xfree(ConfigServerInfo.description); ConfigServerInfo.description = xstrdup(yylval.string); strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info)); } @@ -695,79 +567,23 @@ serverinfo_network_name: NETWORK_NAME '= { if (conf_parser_ctx.pass == 2) { - char *p; + char *p = strchr(yylval.string, ' '); - if ((p = strchr(yylval.string, ' '))) + if (p) *p = '\0'; - MyFree(ConfigServerInfo.network_name); + xfree(ConfigServerInfo.network_name); ConfigServerInfo.network_name = xstrdup(yylval.string); } }; -serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';' +serverinfo_network_description: NETWORK_DESCRIPTION '=' QSTRING ';' { if (conf_parser_ctx.pass != 2) break; - MyFree(ConfigServerInfo.network_desc); - ConfigServerInfo.network_desc = xstrdup(yylval.string); -}; - -serverinfo_vhost: VHOST '=' QSTRING ';' -{ - if (conf_parser_ctx.pass == 2 && *yylval.string != '*') - { - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - - if (getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); - else - { - assert(res); - - memcpy(&ConfigServerInfo.ip, res->ai_addr, res->ai_addrlen); - ConfigServerInfo.ip.ss.ss_family = res->ai_family; - ConfigServerInfo.ip.ss_len = res->ai_addrlen; - freeaddrinfo(res); - - ConfigServerInfo.specific_ipv4_vhost = 1; - } - } -}; - -serverinfo_vhost6: VHOST6 '=' QSTRING ';' -{ - if (conf_parser_ctx.pass == 2 && *yylval.string != '*') - { - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; - - if (getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost6(%s)", yylval.string); - else - { - assert(res); - - memcpy(&ConfigServerInfo.ip6, res->ai_addr, res->ai_addrlen); - ConfigServerInfo.ip6.ss.ss_family = res->ai_family; - ConfigServerInfo.ip6.ss_len = res->ai_addrlen; - freeaddrinfo(res); - - ConfigServerInfo.specific_ipv6_vhost = 1; - } - } + xfree(ConfigServerInfo.network_description); + ConfigServerInfo.network_description = xstrdup(yylval.string); }; serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';' @@ -775,20 +591,18 @@ serverinfo_default_max_clients: DEFAULT_ if (conf_parser_ctx.pass != 2) break; - if ($3 < MAXCLIENTS_MIN) + if ($3 < 1) { - char buf[IRCD_BUFSIZE] = ""; - - snprintf(buf, sizeof(buf), "MAXCLIENTS too low, setting to %d", MAXCLIENTS_MIN); - conf_error_report(buf); - ConfigServerInfo.default_max_clients = MAXCLIENTS_MIN; + conf_error_report("default_max_clients too low, setting to 1"); + ConfigServerInfo.default_max_clients = 1; } else if ($3 > MAXCLIENTS_MAX) { - char buf[IRCD_BUFSIZE] = ""; + char buf[IRCD_BUFSIZE]; - snprintf(buf, sizeof(buf), "MAXCLIENTS too high, setting to %d", MAXCLIENTS_MAX); + snprintf(buf, sizeof(buf), "default_max_clients too high, setting to %d", MAXCLIENTS_MAX); conf_error_report(buf); + ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX; } else @@ -807,10 +621,11 @@ serverinfo_max_nick_length: MAX_NICK_LEN } else if ($3 > NICKLEN) { - char buf[IRCD_BUFSIZE] = ""; + char buf[IRCD_BUFSIZE]; snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN); conf_error_report(buf); + ConfigServerInfo.max_nick_length = NICKLEN; } else @@ -829,10 +644,11 @@ serverinfo_max_topic_length: MAX_TOPIC_L } else if ($3 > TOPICLEN) { - char buf[IRCD_BUFSIZE] = ""; + char buf[IRCD_BUFSIZE]; snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN); conf_error_report(buf); + ConfigServerInfo.max_topic_length = TOPICLEN; } else @@ -845,10 +661,11 @@ serverinfo_hub: HUB '=' TBOOL ';' ConfigServerInfo.hub = yylval.number; }; + /*************************************************************************** - * admin section + * admin {} section ***************************************************************************/ -admin_entry: ADMIN '{' admin_items '}' ';' ; +admin_entry: ADMIN '{' admin_items '}' ';' ; admin_items: admin_items admin_item | admin_item; admin_item: admin_name | @@ -861,7 +678,7 @@ admin_name: NAME '=' QSTRING ';' if (conf_parser_ctx.pass != 2) break; - MyFree(ConfigAdminInfo.name); + xfree(ConfigAdminInfo.name); ConfigAdminInfo.name = xstrdup(yylval.string); }; @@ -870,7 +687,7 @@ admin_email: EMAIL '=' QSTRING ';' if (conf_parser_ctx.pass != 2) break; - MyFree(ConfigAdminInfo.email); + xfree(ConfigAdminInfo.email); ConfigAdminInfo.email = xstrdup(yylval.string); }; @@ -879,12 +696,13 @@ admin_description: DESCRIPTION '=' QSTRI if (conf_parser_ctx.pass != 2) break; - MyFree(ConfigAdminInfo.description); + xfree(ConfigAdminInfo.description); ConfigAdminInfo.description = xstrdup(yylval.string); }; + /*************************************************************************** - * motd section + * motd {} section ***************************************************************************/ motd_entry: MOTD { @@ -892,7 +710,7 @@ motd_entry: MOTD reset_block_state(); } '{' motd_items '}' ';' { - dlink_node *node = NULL; + dlink_node *node; if (conf_parser_ctx.pass != 2) break; @@ -919,8 +737,9 @@ motd_file: T_FILE '=' QSTRING ';' strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf)); }; + /*************************************************************************** - * pseudo section + * pseudo {} section ***************************************************************************/ pseudo_entry: T_PSEUDO { @@ -980,10 +799,11 @@ pseudo_target: T_TARGET '=' QSTRING ';' } }; + /*************************************************************************** - * section logging + * log {} section ***************************************************************************/ -logging_entry: T_LOG '{' logging_items '}' ';' ; +logging_entry: T_LOG '{' logging_items '}' ';' ; logging_items: logging_items logging_item | logging_item ; logging_item: logging_use_logging | logging_file_entry | @@ -1035,7 +855,7 @@ logging_file_type: TYPE { if (conf_parser_ctx.pass == 2) block_state.type.value = 0; -} '=' logging_file_type_items ';' ; +} '=' logging_file_type_items ';' ; logging_file_type_items: logging_file_type_items ',' logging_file_type_item | logging_file_type_item; logging_file_type_item: USER @@ -1074,7 +894,7 @@ logging_file_type_item: USER /*************************************************************************** - * section oper + * operator {} section ***************************************************************************/ oper_entry: OPERATOR { @@ -1085,40 +905,41 @@ oper_entry: OPERATOR block_state.flags.value |= CONF_FLAGS_ENCRYPTED; } '{' oper_items '}' ';' { - dlink_node *node = NULL; + dlink_node *node; if (conf_parser_ctx.pass != 2) break; if (!block_state.name.buf[0]) break; -#ifdef HAVE_LIBCRYPTO - if (!block_state.file.buf[0] && - !block_state.rpass.buf[0]) - break; -#else + if (!block_state.rpass.buf[0]) break; -#endif DLINK_FOREACH(node, block_state.mask.list.head) { - struct MaskItem *conf = NULL; struct split_nuh_item nuh; + char *s = node->data; + + if (EmptyString(s)) + continue; - nuh.nuhmask = node->data; + nuh.nuhmask = s; nuh.nickptr = NULL; nuh.userptr = block_state.user.buf; nuh.hostptr = block_state.host.buf; + nuh.nicksize = 0; nuh.usersize = sizeof(block_state.user.buf); nuh.hostsize = sizeof(block_state.host.buf); + split_nuh(&nuh); - conf = conf_make(CONF_OPER); - conf->name = xstrdup(block_state.name.buf); - conf->user = xstrdup(block_state.user.buf); - conf->host = xstrdup(block_state.host.buf); + struct MaskItem *conf = conf_make(CONF_OPER); + conf->addr = xcalloc(sizeof(*conf->addr)); + conf->name = xstrdup(block_state.name.buf); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); if (block_state.cert.buf[0]) conf->certfp = xstrdup(block_state.cert.buf); @@ -1132,7 +953,7 @@ oper_entry: OPERATOR conf->flags = block_state.flags.value; conf->modes = block_state.modes.value; conf->port = block_state.port.value; - conf->htype = parse_netmask(conf->host, &conf->addr, &conf->bits); + conf->htype = parse_netmask(conf->host, conf->addr, &conf->bits); conf_add_class_to_conf(conf, block_state.class.buf); } @@ -1146,8 +967,8 @@ oper_item: oper_name | oper_umodes | oper_class | oper_encrypted | - oper_ssl_certificate_fingerprint | - oper_ssl_connection_required | + oper_tls_certificate_fingerprint | + oper_tls_connection_required | oper_flags | error ';' ; @@ -1186,21 +1007,21 @@ oper_encrypted: ENCRYPTED '=' TBOOL ';' block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; }; -oper_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' +oper_tls_certificate_fingerprint: TLS_CERTIFICATE_FINGERPRINT '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); }; -oper_ssl_connection_required: SSL_CONNECTION_REQUIRED '=' TBOOL ';' +oper_tls_connection_required: TLS_CONNECTION_REQUIRED '=' TBOOL ';' { if (conf_parser_ctx.pass != 2) break; if (yylval.number) - block_state.flags.value |= CONF_FLAGS_SSL; + block_state.flags.value |= CONF_FLAGS_TLS; else - block_state.flags.value &= ~CONF_FLAGS_SSL; + block_state.flags.value &= ~CONF_FLAGS_TLS; }; oper_class: CLASS '=' QSTRING ';' @@ -1213,14 +1034,10 @@ oper_umodes: T_UMODES { if (conf_parser_ctx.pass == 2) block_state.modes.value = 0; -} '=' oper_umodes_items ';' ; +} '=' oper_umodes_items ';' ; oper_umodes_items: oper_umodes_items ',' oper_umodes_item | oper_umodes_item; -oper_umodes_item: T_BOTS -{ - if (conf_parser_ctx.pass == 2) - block_state.modes.value |= UMODE_BOTS; -} | T_CCONN +oper_umodes_item: T_CCONN { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_CCONN; @@ -1232,10 +1049,10 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_DEBUG; -} | T_FULL +} | T_FLOOD { if (conf_parser_ctx.pass == 2) - block_state.modes.value |= UMODE_FULL; + block_state.modes.value |= UMODE_FLOOD; } | HIDDEN { if (conf_parser_ctx.pass == 2) @@ -1260,10 +1077,6 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_REJ; -} | T_UNAUTH -{ - if (conf_parser_ctx.pass == 2) - block_state.modes.value |= UMODE_UNAUTH; } | T_SPY { if (conf_parser_ctx.pass == 2) @@ -1304,13 +1117,17 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_FARCONNECT; +} | EXPIRATION +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_EXPIRATION; }; oper_flags: IRCD_FLAGS { if (conf_parser_ctx.pass == 2) block_state.port.value = 0; -} '=' oper_flags_items ';'; +} '=' oper_flags_items ';'; oper_flags_items: oper_flags_items ',' oper_flags_item | oper_flags_item; oper_flags_item: KILL ':' REMOTE @@ -1369,6 +1186,10 @@ oper_flags_item: KILL ':' REMOTE { if (conf_parser_ctx.pass == 2) block_state.port.value |= OPER_FLAG_RESTART; +} | REHASH ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_REHASH_REMOTE; } | REHASH { if (conf_parser_ctx.pass == 2) @@ -1429,7 +1250,7 @@ oper_flags_item: KILL ':' REMOTE /*************************************************************************** - * section class + * class {} section ***************************************************************************/ class_entry: CLASS { @@ -1440,32 +1261,28 @@ class_entry: CLASS block_state.ping_freq.value = DEFAULT_PINGFREQUENCY; block_state.con_freq.value = DEFAULT_CONNECTFREQUENCY; - block_state.max_total.value = MAXIMUM_LINKS_DEFAULT; block_state.max_sendq.value = DEFAULT_SENDQ; block_state.max_recvq.value = DEFAULT_RECVQ; } '{' class_items '}' ';' { - struct ClassItem *class = NULL; - if (conf_parser_ctx.pass != 1) break; if (!block_state.class.buf[0]) break; - if (!(class = class_find(block_state.class.buf, 0))) + struct ClassItem *class = class_find(block_state.class.buf, false); + if (class == NULL) class = class_make(); - class->active = 1; - MyFree(class->name); + class->active = true; + xfree(class->name); class->name = xstrdup(block_state.class.buf); class->ping_freq = block_state.ping_freq.value; - class->max_perip = block_state.max_perip.value; + class->max_perip_local = block_state.max_perip_local.value; + class->max_perip_global = block_state.max_perip_global.value; class->con_freq = block_state.con_freq.value; class->max_total = block_state.max_total.value; - class->max_global = block_state.max_global.value; - class->max_local = block_state.max_local.value; - class->max_ident = block_state.max_ident.value; class->max_sendq = block_state.max_sendq.value; class->max_recvq = block_state.max_recvq.value; class->max_channels = block_state.max_channels.value; @@ -1481,11 +1298,14 @@ class_entry: CLASS class->min_idle = block_state.min_idle.value; class->max_idle = block_state.max_idle.value; - rebuild_cidr_list(class); - + bool diff = (class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value || + class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value); class->cidr_bitlen_ipv4 = block_state.cidr_bitlen_ipv4.value; class->cidr_bitlen_ipv6 = block_state.cidr_bitlen_ipv6.value; class->number_per_cidr = block_state.number_per_cidr.value; + + if (diff) + class_ip_limit_rebuild(class); }; class_items: class_items class_item | class_item; @@ -1494,14 +1314,13 @@ class_item: class_name | class_cidr_bitlen_ipv6 | class_ping_time | class_number_per_cidr | - class_number_per_ip | + class_number_per_ip_local | + class_number_per_ip_global | class_connectfreq | class_max_channels | class_max_number | - class_max_global | - class_max_local | - class_max_ident | - class_sendq | class_recvq | + class_sendq | + class_recvq | class_min_idle | class_max_idle | class_flags | @@ -1519,10 +1338,16 @@ class_ping_time: PING_TIME '=' timespec block_state.ping_freq.value = $3; }; -class_number_per_ip: NUMBER_PER_IP '=' NUMBER ';' +class_number_per_ip_local: NUMBER_PER_IP_LOCAL '=' NUMBER ';' +{ + if (conf_parser_ctx.pass == 1) + block_state.max_perip_local.value = $3; +}; + +class_number_per_ip_global: NUMBER_PER_IP_GLOBAL '=' NUMBER ';' { if (conf_parser_ctx.pass == 1) - block_state.max_perip.value = $3; + block_state.max_perip_global.value = $3; }; class_connectfreq: CONNECTFREQ '=' timespec ';' @@ -1543,24 +1368,6 @@ class_max_number: MAX_NUMBER '=' NUMBER block_state.max_total.value = $3; }; -class_max_global: MAX_GLOBAL '=' NUMBER ';' -{ - if (conf_parser_ctx.pass == 1) - block_state.max_global.value = $3; -}; - -class_max_local: MAX_LOCAL '=' NUMBER ';' -{ - if (conf_parser_ctx.pass == 1) - block_state.max_local.value = $3; -}; - -class_max_ident: MAX_IDENT '=' NUMBER ';' -{ - if (conf_parser_ctx.pass == 1) - block_state.max_ident.value = $3; -}; - class_sendq: SENDQ '=' sizespec ';' { if (conf_parser_ctx.pass == 1) @@ -1614,7 +1421,7 @@ class_flags: IRCD_FLAGS { if (conf_parser_ctx.pass == 1) block_state.flags.value &= CLASS_FLAGS_FAKE_IDLE; -} '=' class_flags_items ';'; +} '=' class_flags_items ';'; class_flags_items: class_flags_items ',' class_flags_item | class_flags_item; class_flags_item: RANDOM_IDLE @@ -1629,7 +1436,7 @@ class_flags_item: RANDOM_IDLE /*************************************************************************** - * section listen + * listen {} section ***************************************************************************/ listen_entry: LISTEN { @@ -1640,13 +1447,13 @@ listen_entry: LISTEN listen_flags: IRCD_FLAGS { block_state.flags.value = 0; -} '=' listen_flags_items ';'; +} '=' listen_flags_items ';'; listen_flags_items: listen_flags_items ',' listen_flags_item | listen_flags_item; -listen_flags_item: T_SSL +listen_flags_item: T_TLS { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= LISTENER_SSL; + block_state.flags.value |= LISTENER_TLS; } | HIDDEN { if (conf_parser_ctx.pass == 2) @@ -1655,6 +1462,14 @@ listen_flags_item: T_SSL { if (conf_parser_ctx.pass == 2) block_state.flags.value |= LISTENER_SERVER; +} | CLIENT +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= LISTENER_CLIENT; +} | DEFER +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= LISTENER_DEFER; }; listen_items: listen_items listen_item | listen_item; @@ -1668,10 +1483,10 @@ port_item: NUMBER { if (conf_parser_ctx.pass == 2) { -#ifndef HAVE_LIBCRYPTO - if (block_state.flags.value & LISTENER_SSL) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_TLS) { - conf_error_report("SSL not available - port closed"); + conf_error_report("TLS not available - port closed"); break; } #endif @@ -1681,10 +1496,10 @@ port_item: NUMBER { if (conf_parser_ctx.pass == 2) { -#ifndef HAVE_LIBCRYPTO - if (block_state.flags.value & LISTENER_SSL) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_TLS) { - conf_error_report("SSL not available - port closed"); + conf_error_report("TLS not available - port closed"); break; } #endif @@ -1706,8 +1521,9 @@ listen_host: HOST '=' QSTRING ';' strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf)); }; + /*************************************************************************** - * section auth + * auth {} section ***************************************************************************/ auth_entry: IRCD_AUTH { @@ -1715,28 +1531,33 @@ auth_entry: IRCD_AUTH reset_block_state(); } '{' auth_items '}' ';' { - dlink_node *node = NULL; + dlink_node *node; if (conf_parser_ctx.pass != 2) break; DLINK_FOREACH(node, block_state.mask.list.head) { - struct MaskItem *conf = NULL; struct split_nuh_item nuh; + char *s = node->data; + + if (EmptyString(s)) + continue; - nuh.nuhmask = node->data; + nuh.nuhmask = s; nuh.nickptr = NULL; nuh.userptr = block_state.user.buf; nuh.hostptr = block_state.host.buf; + nuh.nicksize = 0; nuh.usersize = sizeof(block_state.user.buf); nuh.hostsize = sizeof(block_state.host.buf); + split_nuh(&nuh); - conf = conf_make(CONF_CLIENT); - conf->user = xstrdup(block_state.user.buf); - conf->host = xstrdup(block_state.host.buf); + struct MaskItem *conf = conf_make(CONF_CLIENT); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); if (block_state.rpass.buf[0]) conf->passwd = xstrdup(block_state.rpass.buf); @@ -1744,7 +1565,7 @@ auth_entry: IRCD_AUTH conf->name = xstrdup(block_state.name.buf); conf->flags = block_state.flags.value; - conf->port = block_state.port.value; + conf->port = block_state.port.value; conf_add_class_to_conf(conf, block_state.class.buf); add_conf_by_address(CONF_CLIENT, conf); @@ -1795,14 +1616,10 @@ auth_flags: IRCD_FLAGS { if (conf_parser_ctx.pass == 2) block_state.flags.value &= (CONF_FLAGS_ENCRYPTED | CONF_FLAGS_SPOOF_IP); -} '=' auth_flags_items ';'; +} '=' auth_flags_items ';'; auth_flags_items: auth_flags_items ',' auth_flags_item | auth_flags_item; -auth_flags_item: SPOOF_NOTICE -{ - if (conf_parser_ctx.pass == 2) - block_state.flags.value |= CONF_FLAGS_SPOOF_NOTICE; -} | EXCEED_LIMIT +auth_flags_item: EXCEED_LIMIT { if (conf_parser_ctx.pass == 2) block_state.flags.value |= CONF_FLAGS_NOLIMIT; @@ -1874,7 +1691,7 @@ auth_redir_port: REDIRPORT '=' NUMBER '; /*************************************************************************** - * section resv + * resv {} section ***************************************************************************/ resv_entry: RESV { @@ -1888,7 +1705,7 @@ resv_entry: RESV if (conf_parser_ctx.pass != 2) break; - create_resv(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list); + resv_make(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list); }; resv_items: resv_items resv_item | resv_item; @@ -1914,7 +1731,7 @@ resv_exempt: EXEMPT '=' QSTRING ';' /*************************************************************************** - * section service + * service {} section ***************************************************************************/ service_entry: T_SERVICE '{' service_items '}' ';'; @@ -1926,15 +1743,16 @@ service_name: NAME '=' QSTRING ';' if (conf_parser_ctx.pass != 2) break; - if (valid_servname(yylval.string)) + if (server_valid_name(yylval.string) == true) { - struct MaskItem *conf = conf_make(CONF_SERVICE); - conf->name = xstrdup(yylval.string); + struct ServiceItem *service = service_make(); + service->name = xstrdup(yylval.string); } }; + /*************************************************************************** - * section shared, for sharing remote klines etc. + * shared {} section, for sharing remote klines etc. ***************************************************************************/ shared_entry: T_SHARED { @@ -1949,16 +1767,14 @@ shared_entry: T_SHARED block_state.flags.value = SHARED_ALL; } '{' shared_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; - conf = conf_make(CONF_ULINE); - conf->flags = block_state.flags.value; - conf->name = xstrdup(block_state.name.buf); - conf->user = xstrdup(block_state.user.buf); - conf->host = xstrdup(block_state.host.buf); + struct SharedItem *shared = shared_make(); + shared->type = block_state.flags.value; + shared->server = xstrdup(block_state.name.buf); + shared->user = xstrdup(block_state.user.buf); + shared->host = xstrdup(block_state.host.buf); }; shared_items: shared_items shared_item | shared_item; @@ -2038,8 +1854,9 @@ shared_type_item: KLINE block_state.flags.value = SHARED_ALL; }; + /*************************************************************************** - * section cluster + * cluster {} section ***************************************************************************/ cluster_entry: T_CLUSTER { @@ -2049,17 +1866,15 @@ cluster_entry: T_CLUSTER reset_block_state(); strlcpy(block_state.name.buf, "*", sizeof(block_state.name.buf)); - block_state.flags.value = SHARED_ALL; + block_state.flags.value = CLUSTER_ALL; } '{' cluster_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; - conf = conf_make(CONF_CLUSTER); - conf->flags = block_state.flags.value; - conf->name = xstrdup(block_state.name.buf); + struct ClusterItem *cluster = cluster_make(); + cluster->type = block_state.flags.value; + cluster->server = xstrdup(block_state.name.buf); }; cluster_items: cluster_items cluster_item | cluster_item; @@ -2081,47 +1896,48 @@ cluster_types: cluster_types ',' cluste cluster_type_item: KLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_KLINE; + block_state.flags.value |= CLUSTER_KLINE; } | UNKLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_UNKLINE; + block_state.flags.value |= CLUSTER_UNKLINE; } | T_DLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_DLINE; + block_state.flags.value |= CLUSTER_DLINE; } | T_UNDLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_UNDLINE; + block_state.flags.value |= CLUSTER_UNDLINE; } | XLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_XLINE; + block_state.flags.value |= CLUSTER_XLINE; } | T_UNXLINE { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_UNXLINE; + block_state.flags.value |= CLUSTER_UNXLINE; } | RESV { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_RESV; + block_state.flags.value |= CLUSTER_RESV; } | T_UNRESV { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_UNRESV; + block_state.flags.value |= CLUSTER_UNRESV; } | T_LOCOPS { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= SHARED_LOCOPS; + block_state.flags.value |= CLUSTER_LOCOPS; } | T_ALL { if (conf_parser_ctx.pass == 2) - block_state.flags.value = SHARED_ALL; + block_state.flags.value = CLUSTER_ALL; }; + /*************************************************************************** - * section connect + * connect {} section ***************************************************************************/ connect_entry: CONNECT { @@ -2132,9 +1948,9 @@ connect_entry: CONNECT reset_block_state(); block_state.aftype.value = AF_INET; block_state.port.value = PORTNUM; + block_state.timeout.value = CONNECTTIMEOUT; } '{' connect_items '}' ';' { - struct MaskItem *conf = NULL; struct addrinfo hints, *res; if (conf_parser_ctx.pass != 2) @@ -2148,12 +1964,17 @@ connect_entry: CONNECT !block_state.spass.buf[0]) break; + if (server_valid_name(block_state.name.buf) == false) + break; + if (has_wildcards(block_state.name.buf) || has_wildcards(block_state.host.buf)) break; - conf = conf_make(CONF_SERVER); + struct MaskItem *conf = conf_make(CONF_SERVER); + conf->addr = xcalloc(sizeof(*conf->addr)); conf->port = block_state.port.value; + conf->timeout = block_state.timeout.value; conf->flags = block_state.flags.value; conf->aftype = block_state.aftype.value; conf->host = xstrdup(block_state.host.buf); @@ -2179,32 +2000,34 @@ connect_entry: CONNECT hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; if (getaddrinfo(block_state.bind.buf, NULL, &hints, &res)) - ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", block_state.bind.buf); + ilog(LOG_TYPE_IRCD, "Invalid netmask for server bind(%s)", block_state.bind.buf); else { assert(res); - memcpy(&conf->bind, res->ai_addr, res->ai_addrlen); - conf->bind.ss.ss_family = res->ai_family; - conf->bind.ss_len = res->ai_addrlen; + conf->bind = xcalloc(sizeof(*conf->bind)); + + memcpy(conf->bind, res->ai_addr, res->ai_addrlen); + conf->bind->ss_len = res->ai_addrlen; freeaddrinfo(res); } } conf_add_class_to_conf(conf, block_state.class.buf); - lookup_confhost(conf); + conf_dns_lookup(conf); }; connect_items: connect_items connect_item | connect_item; connect_item: connect_name | connect_host | - connect_vhost | + connect_timeout | + connect_bind | connect_send_password | connect_accept_password | - connect_ssl_certificate_fingerprint | + connect_tls_certificate_fingerprint | connect_aftype | connect_port | - connect_ssl_cipher_list | + connect_tls_cipher_list | connect_flags | connect_hub_mask | connect_leaf_mask | @@ -2224,7 +2047,13 @@ connect_host: HOST '=' QSTRING ';' strlcpy(block_state.host.buf, yylval.string, sizeof(block_state.host.buf)); }; -connect_vhost: VHOST '=' QSTRING ';' +connect_timeout: TIMEOUT '=' timespec ';' +{ + if (conf_parser_ctx.pass == 2) + block_state.timeout.value = $3; +}; + +connect_bind: T_BIND '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) strlcpy(block_state.bind.buf, yylval.string, sizeof(block_state.bind.buf)); @@ -2235,9 +2064,9 @@ connect_send_password: SEND_PASSWORD '=' if (conf_parser_ctx.pass != 2) break; - if ($3[0] == ':') + if (*yylval.string == ':') conf_error_report("Server passwords cannot begin with a colon"); - else if (strchr($3, ' ')) + else if (strchr(yylval.string, ' ')) conf_error_report("Server passwords cannot contain spaces"); else strlcpy(block_state.spass.buf, yylval.string, sizeof(block_state.spass.buf)); @@ -2248,15 +2077,15 @@ connect_accept_password: ACCEPT_PASSWORD if (conf_parser_ctx.pass != 2) break; - if ($3[0] == ':') + if (*yylval.string == ':') conf_error_report("Server passwords cannot begin with a colon"); - else if (strchr($3, ' ')) + else if (strchr(yylval.string, ' ')) conf_error_report("Server passwords cannot contain spaces"); else strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -connect_ssl_certificate_fingerprint: SSL_CERTIFICATE_FINGERPRINT '=' QSTRING ';' +connect_tls_certificate_fingerprint: TLS_CERTIFICATE_FINGERPRINT '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); @@ -2281,17 +2110,17 @@ connect_aftype: AFTYPE '=' T_IPV4 ';' connect_flags: IRCD_FLAGS { block_state.flags.value &= CONF_FLAGS_ENCRYPTED; -} '=' connect_flags_items ';'; +} '=' connect_flags_items ';'; connect_flags_items: connect_flags_items ',' connect_flags_item | connect_flags_item; connect_flags_item: AUTOCONN { if (conf_parser_ctx.pass == 2) block_state.flags.value |= CONF_FLAGS_ALLOW_AUTO_CONN; -} | T_SSL +} | T_TLS { if (conf_parser_ctx.pass == 2) - block_state.flags.value |= CONF_FLAGS_SSL; + block_state.flags.value |= CONF_FLAGS_TLS; }; connect_encrypted: ENCRYPTED '=' TBOOL ';' @@ -2323,20 +2152,20 @@ connect_class: CLASS '=' QSTRING ';' strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); }; -connect_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +connect_tls_cipher_list: TLS_CIPHER_LIST '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO +#ifdef HAVE_TLS if (conf_parser_ctx.pass == 2) strlcpy(block_state.ciph.buf, yylval.string, sizeof(block_state.ciph.buf)); #else if (conf_parser_ctx.pass == 2) - conf_error_report("Ignoring connect::ciphers -- no OpenSSL support"); + conf_error_report("Ignoring connect::tls_cipher_list -- no TLS support"); #endif }; /*************************************************************************** - * section kill + * kill {} section ***************************************************************************/ kill_entry: KILL { @@ -2344,8 +2173,6 @@ kill_entry: KILL reset_block_state(); } '{' kill_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; @@ -2353,7 +2180,7 @@ kill_entry: KILL !block_state.host.buf[0]) break; - conf = conf_make(CONF_KLINE); + struct MaskItem *conf = conf_make(CONF_KLINE); conf->user = xstrdup(block_state.user.buf); conf->host = xstrdup(block_state.host.buf); @@ -2393,8 +2220,9 @@ kill_reason: REASON '=' QSTRING ';' strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section deny + * deny {} section ***************************************************************************/ deny_entry: DENY { @@ -2402,8 +2230,6 @@ deny_entry: DENY reset_block_state(); } '{' deny_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; @@ -2412,7 +2238,7 @@ deny_entry: DENY if (parse_netmask(block_state.addr.buf, NULL, NULL) != HM_HOST) { - conf = conf_make(CONF_DLINE); + struct MaskItem *conf = conf_make(CONF_DLINE); conf->host = xstrdup(block_state.addr.buf); if (block_state.rpass.buf[0]) @@ -2438,19 +2264,20 @@ deny_reason: REASON '=' QSTRING ';' strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section exempt + * exempt {} section ***************************************************************************/ exempt_entry: EXEMPT '{' exempt_items '}' ';'; -exempt_items: exempt_items exempt_item | exempt_item; -exempt_item: exempt_ip | error; +exempt_items: exempt_items exempt_item | exempt_item; +exempt_item: exempt_ip | error; exempt_ip: IP '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) { - if (yylval.string[0] && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) + if (*yylval.string && parse_netmask(yylval.string, NULL, NULL) != HM_HOST) { struct MaskItem *conf = conf_make(CONF_EXEMPT); conf->host = xstrdup(yylval.string); @@ -2461,7 +2288,7 @@ exempt_ip: IP '=' QSTRING ';' }; /*************************************************************************** - * section gecos + * gecos {} section ***************************************************************************/ gecos_entry: GECOS { @@ -2469,21 +2296,19 @@ gecos_entry: GECOS reset_block_state(); } '{' gecos_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; if (!block_state.name.buf[0]) break; - conf = conf_make(CONF_XLINE); - conf->name = xstrdup(block_state.name.buf); + struct GecosItem *gecos = gecos_make(); + gecos->mask = xstrdup(block_state.name.buf); if (block_state.rpass.buf[0]) - conf->reason = xstrdup(block_state.rpass.buf); + gecos->reason = xstrdup(block_state.rpass.buf); else - conf->reason = xstrdup(CONF_NOREASON); + gecos->reason = xstrdup(CONF_NOREASON); }; gecos_items: gecos_items gecos_item | gecos_item; @@ -2501,21 +2326,21 @@ gecos_reason: REASON '=' QSTRING ';' strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section general + * general {} section ***************************************************************************/ -general_entry: GENERAL - '{' general_items '}' ';'; +general_entry: GENERAL '{' general_items '}' ';'; general_items: general_items general_item | general_item; general_item: general_away_count | general_away_time | - general_ignore_bogus_ts | general_failed_oper_notice | general_anti_nick_flood | general_max_nick_time | general_max_nick_changes | general_max_accept | + general_whowas_history_length | general_anti_spam_exit_message_time | general_ts_warn_delta | general_ts_max_delta | @@ -2539,13 +2364,13 @@ general_item: general_away_count | general_caller_id_wait | general_opers_bypass_callerid | general_default_floodcount | + general_default_floodtime | general_min_nonwildcard | general_min_nonwildcard_simple | general_throttle_count | general_throttle_time | general_ping_cookie | general_disable_auth | - general_tkline_expire_notices | general_dline_min_cidr | general_dline_min_cidr6 | general_kline_min_cidr | @@ -2571,10 +2396,14 @@ general_max_watch: MAX_WATCH '=' NUMBER ConfigGeneral.max_watch = $3; }; +general_whowas_history_length: WHOWAS_HISTORY_LENGTH '=' NUMBER ';' +{ + ConfigGeneral.whowas_history_length = $3; +}; + general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';' { - if (conf_parser_ctx.pass == 2) - ConfigGeneral.cycle_on_host_change = yylval.number; + ConfigGeneral.cycle_on_host_change = yylval.number; }; general_dline_min_cidr: DLINE_MIN_CIDR '=' NUMBER ';' @@ -2597,21 +2426,11 @@ general_kline_min_cidr6: KLINE_MIN_CIDR6 ConfigGeneral.kline_min_cidr6 = $3; }; -general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';' -{ - ConfigGeneral.tkline_expire_notices = yylval.number; -}; - general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';' { ConfigGeneral.kill_chase_time_limit = $3; }; -general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';' -{ - ConfigGeneral.ignore_bogus_ts = yylval.number; -}; - general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';' { ConfigGeneral.failed_oper_notice = yylval.number; @@ -2649,8 +2468,7 @@ general_ts_warn_delta: TS_WARN_DELTA '=' general_ts_max_delta: TS_MAX_DELTA '=' timespec ';' { - if (conf_parser_ctx.pass == 2) - ConfigGeneral.ts_max_delta = $3; + ConfigGeneral.ts_max_delta = $3; }; general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' @@ -2690,18 +2508,12 @@ general_stats_u_oper_only: STATS_U_OPER_ general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';' { - ConfigGeneral.stats_k_oper_only = 2 * yylval.number; -} | STATS_K_OPER_ONLY '=' TMASKED ';' -{ - ConfigGeneral.stats_k_oper_only = 1; + ConfigGeneral.stats_k_oper_only = yylval.number; }; general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';' { - ConfigGeneral.stats_i_oper_only = 2 * yylval.number; -} | STATS_I_OPER_ONLY '=' TMASKED ';' -{ - ConfigGeneral.stats_i_oper_only = 1; + ConfigGeneral.stats_i_oper_only = yylval.number; }; general_pace_wait: PACE_WAIT '=' timespec ';' @@ -2767,13 +2579,10 @@ general_throttle_time: THROTTLE_TIME '=' general_oper_umodes: OPER_UMODES { ConfigGeneral.oper_umodes = 0; -} '=' umode_oitems ';' ; +} '=' umode_oitems ';' ; umode_oitems: umode_oitems ',' umode_oitem | umode_oitem; -umode_oitem: T_BOTS -{ - ConfigGeneral.oper_umodes |= UMODE_BOTS; -} | T_CCONN +umode_oitem: T_CCONN { ConfigGeneral.oper_umodes |= UMODE_CCONN; } | T_DEAF @@ -2782,9 +2591,9 @@ umode_oitem: T_BOTS } | T_DEBUG { ConfigGeneral.oper_umodes |= UMODE_DEBUG; -} | T_FULL +} | T_FLOOD { - ConfigGeneral.oper_umodes |= UMODE_FULL; + ConfigGeneral.oper_umodes |= UMODE_FLOOD; } | HIDDEN { ConfigGeneral.oper_umodes |= UMODE_HIDDEN; @@ -2803,9 +2612,6 @@ umode_oitem: T_BOTS } | T_REJ { ConfigGeneral.oper_umodes |= UMODE_REJ; -} | T_UNAUTH -{ - ConfigGeneral.oper_umodes |= UMODE_UNAUTH; } | T_SPY { ConfigGeneral.oper_umodes |= UMODE_SPY; @@ -2836,18 +2642,18 @@ umode_oitem: T_BOTS } | T_FARCONNECT { ConfigGeneral.oper_umodes |= UMODE_FARCONNECT; +} | EXPIRATION +{ + ConfigGeneral.oper_umodes |= UMODE_EXPIRATION; }; general_oper_only_umodes: OPER_ONLY_UMODES { ConfigGeneral.oper_only_umodes = 0; -} '=' umode_items ';' ; +} '=' umode_items ';' ; umode_items: umode_items ',' umode_item | umode_item; -umode_item: T_BOTS -{ - ConfigGeneral.oper_only_umodes |= UMODE_BOTS; -} | T_CCONN +umode_item: T_CCONN { ConfigGeneral.oper_only_umodes |= UMODE_CCONN; } | T_DEAF @@ -2856,9 +2662,9 @@ umode_item: T_BOTS } | T_DEBUG { ConfigGeneral.oper_only_umodes |= UMODE_DEBUG; -} | T_FULL +} | T_FLOOD { - ConfigGeneral.oper_only_umodes |= UMODE_FULL; + ConfigGeneral.oper_only_umodes |= UMODE_FLOOD; } | T_SKILL { ConfigGeneral.oper_only_umodes |= UMODE_SKILL; @@ -2871,9 +2677,6 @@ umode_item: T_BOTS } | T_REJ { ConfigGeneral.oper_only_umodes |= UMODE_REJ; -} | T_UNAUTH -{ - ConfigGeneral.oper_only_umodes |= UMODE_UNAUTH; } | T_SPY { ConfigGeneral.oper_only_umodes |= UMODE_SPY; @@ -2904,6 +2707,9 @@ umode_item: T_BOTS } | T_FARCONNECT { ConfigGeneral.oper_only_umodes |= UMODE_FARCONNECT; +} | EXPIRATION +{ + ConfigGeneral.oper_only_umodes |= UMODE_EXPIRATION; }; general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';' @@ -2921,26 +2727,40 @@ general_default_floodcount: DEFAULT_FLOO ConfigGeneral.default_floodcount = $3; }; +general_default_floodtime: DEFAULT_FLOODTIME '=' timespec ';' +{ + ConfigGeneral.default_floodtime = $3; +}; + /*************************************************************************** - * section channel + * channel {} section ***************************************************************************/ -channel_entry: CHANNEL - '{' channel_items '}' ';'; +channel_entry: CHANNEL '{' channel_items '}' ';'; channel_items: channel_items channel_item | channel_item; channel_item: channel_max_bans | + channel_max_bans_large | channel_invite_client_count | channel_invite_client_time | + channel_invite_delay_channel | + channel_invite_expire_time | channel_knock_client_count | channel_knock_client_time | channel_knock_delay_channel | channel_max_channels | + channel_max_invites | channel_default_join_flood_count | channel_default_join_flood_time | channel_disable_fake_channels | + channel_enable_extbans | error; +channel_enable_extbans: ENABLE_EXTBANS '=' TBOOL ';' +{ + ConfigChannel.enable_extbans = yylval.number; +}; + channel_disable_fake_channels: DISABLE_FAKE_CHANNELS '=' TBOOL ';' { ConfigChannel.disable_fake_channels = yylval.number; @@ -2956,6 +2776,16 @@ channel_invite_client_time: INVITE_CLIEN ConfigChannel.invite_client_time = $3; }; +channel_invite_delay_channel: INVITE_DELAY_CHANNEL '=' timespec ';' +{ + ConfigChannel.invite_delay_channel = $3; +}; + +channel_invite_expire_time: INVITE_EXPIRE_TIME '=' timespec ';' +{ + ConfigChannel.invite_expire_time = $3; +}; + channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';' { ConfigChannel.knock_client_count = $3; @@ -2976,11 +2806,21 @@ channel_max_channels: MAX_CHANNELS '=' N ConfigChannel.max_channels = $3; }; +channel_max_invites: MAX_INVITES '=' NUMBER ';' +{ + ConfigChannel.max_invites = $3; +}; + channel_max_bans: MAX_BANS '=' NUMBER ';' { ConfigChannel.max_bans = $3; }; +channel_max_bans_large: MAX_BANS_LARGE '=' NUMBER ';' +{ + ConfigChannel.max_bans_large = $3; +}; + channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';' { ConfigChannel.default_join_flood_count = yylval.number; @@ -2991,11 +2831,11 @@ channel_default_join_flood_time: DEFAULT ConfigChannel.default_join_flood_time = $3; }; + /*************************************************************************** - * section serverhide + * serverhide {} section ***************************************************************************/ -serverhide_entry: SERVERHIDE - '{' serverhide_items '}' ';'; +serverhide_entry: SERVERHIDE '{' serverhide_items '}' ';'; serverhide_items: serverhide_items serverhide_item | serverhide_item; serverhide_item: serverhide_flatten_links | @@ -3015,54 +2855,55 @@ serverhide_flatten_links: FLATTEN_LINKS ConfigServerHide.flatten_links = yylval.number; }; -serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' +serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';' { if (conf_parser_ctx.pass == 2) - ConfigServerHide.disable_remote_commands = yylval.number; + { + if ($3 > 0) + { + event_write_links_file.when = $3; + event_add(&event_write_links_file, NULL); + } + else + event_delete(&event_write_links_file); + + ConfigServerHide.flatten_links_delay = $3; + } }; -serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' +serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) - ConfigServerHide.hide_servers = yylval.number; + { + xfree(ConfigServerHide.flatten_links_file); + ConfigServerHide.flatten_links_file = xstrdup(yylval.string); + } }; -serverhide_hide_services: HIDE_SERVICES '=' TBOOL ';' +serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - ConfigServerHide.hide_services = yylval.number; + ConfigServerHide.disable_remote_commands = yylval.number; }; -serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' +serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - { - MyFree(ConfigServerHide.hidden_name); - ConfigServerHide.hidden_name = xstrdup(yylval.string); - } + ConfigServerHide.hide_servers = yylval.number; }; -serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';' +serverhide_hide_services: HIDE_SERVICES '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - { - if (($3 > 0) && ConfigServerHide.links_disabled == 1) - { - event_write_links_file.when = $3; - event_addish(&event_write_links_file, NULL); - ConfigServerHide.links_disabled = 0; - } - - ConfigServerHide.flatten_links_delay = $3; - } + ConfigServerHide.hide_services = yylval.number; }; -serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';' +serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) { - MyFree(ConfigServerHide.flatten_links_file); - ConfigServerHide.flatten_links_file = xstrdup(yylval.string); + xfree(ConfigServerHide.hidden_name); + ConfigServerHide.hidden_name = xstrdup(yylval.string); } };