--- ircd-hybrid/trunk/src/conf_parser.y 2013/01/24 19:26:51 1783 +++ ircd-hybrid/trunk/src/conf_parser.y 2020/10/31 19:05:15 9692 @@ -1,8 +1,7 @@ /* - * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd). - * conf_parser.y: Parses the ircd configuration file. + * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd) * - * Copyright (C) 2005 by the past and present ircd coders, and others. + * 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 @@ -16,90 +15,94 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA - * - * $Id$ */ -%{ +/*! \file conf_parser.y + * \brief Parses the ircd configuration file. + * \version $Id$ + */ -#define YY_NO_UNPUT -#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_ALL only */ #include "irc_string.h" -#include "sprintf_irc.h" #include "memory.h" #include "modules.h" -#include "s_serv.h" +#include "server.h" #include "hostmask.h" -#include "send.h" #include "listener.h" -#include "resv.h" -#include "numeric.h" -#include "s_user.h" - -#ifdef HAVE_LIBCRYPTO -#include -#include -#include -#include -#endif - -#include "rsa.h" +#include "user.h" +#include "motd.h" int yylex(void); static struct { - struct { + struct + { dlink_list list; } mask, leaf, hub; - struct { + struct + { char buf[IRCD_BUFSIZE]; } name, + nick, user, host, addr, bind, file, ciph, + cert, rpass, spass, - class; + whois, + class, + target, + prepend, + command; - struct { + struct + { unsigned int value; } flags, modes, 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, cidr_bitlen_ipv4, cidr_bitlen_ipv6, number_per_cidr; @@ -108,27 +111,18 @@ static struct static void reset_block_state(void) { - dlink_node *ptr = NULL, *ptr_next = NULL; - - DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.mask.list.head) - { - MyFree(ptr->data); - dlinkDelete(ptr, &block_state.mask.list); - free_dlink_node(ptr); - } - - DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.leaf.list.head) - { - MyFree(ptr->data); - dlinkDelete(ptr, &block_state.leaf.list); - free_dlink_node(ptr); - } + dlink_node *node, *node_next; + dlink_list *tab[] = { &block_state.mask.list, + &block_state.leaf.list, &block_state.hub.list, NULL }; - DLINK_FOREACH_SAFE(ptr, ptr_next, block_state.hub.list.head) + for (dlink_list **list = tab; *list; ++list) { - MyFree(ptr->data); - dlinkDelete(ptr, &block_state.hub.list); - free_dlink_node(ptr); + 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)); @@ -147,74 +141,86 @@ reset_block_state(void) %token ANTI_NICK_FLOOD %token ANTI_SPAM_EXIT_MESSAGE_TIME %token AUTOCONN +%token AWAY_COUNT +%token AWAY_TIME %token BYTES KBYTES MBYTES %token CALLER_ID_WAIT %token CAN_FLOOD %token CHANNEL -%token CIDR_BITLEN_IPV4 -%token CIDR_BITLEN_IPV6 +%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_SPLIT_SERVER_COUNT -%token DEFAULT_SPLIT_USER_COUNT +%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 %token DISABLE_AUTH %token DISABLE_FAKE_CHANNELS %token DISABLE_REMOTE_COMMANDS +%token DLINE_MIN_CIDR +%token DLINE_MIN_CIDR6 %token DOTS_IN_IDENT -%token EGDPOOL_PATH %token EMAIL +%token ENABLE_EXTBANS %token ENCRYPTED %token EXCEED_LIMIT %token EXEMPT +%token EXPIRATION %token FAILED_OPER_NOTICE -%token IRCD_FLAGS %token FLATTEN_LINKS +%token FLATTEN_LINKS_DELAY +%token FLATTEN_LINKS_FILE %token GECOS %token GENERAL -%token GLINE -%token GLINE_DURATION -%token GLINE_ENABLE -%token GLINE_EXEMPT -%token GLINE_REQUEST_DURATION -%token GLINE_MIN_CIDR -%token GLINE_MIN_CIDR6 -%token GLOBAL_KILL -%token IRCD_AUTH -%token NEED_IDENT -%token HAVENT_READ_CONF %token HIDDEN -%token HIDDEN_NAME +%token HIDDEN_NAME +%token HIDE_CHANS +%token HIDE_IDLE +%token HIDE_IDLE_FROM_OPERS %token HIDE_SERVER_IPS %token HIDE_SERVERS -%token HIDE_SPOOF_IPS +%token HIDE_SERVICES %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 +%token IRCD_SID +%token JOIN %token KILL -%token KILL_CHASE_TIME_LIMIT +%token KILL_CHASE_TIME_LIMIT %token KLINE %token KLINE_EXEMPT -%token KNOCK_DELAY +%token KLINE_MIN_CIDR +%token KLINE_MIN_CIDR6 +%token KNOCK_CLIENT_COUNT +%token KNOCK_CLIENT_TIME %token KNOCK_DELAY_CHANNEL %token LEAF_MASK -%token LINKS_DELAY %token LISTEN -%token T_LOG +%token MASK %token MAX_ACCEPT %token MAX_BANS -%token MAX_CHANS_PER_OPER -%token MAX_CHANS_PER_USER -%token MAX_GLOBAL -%token MAX_IDENT -%token MAX_LOCAL +%token MAX_BANS_LARGE +%token MAX_CHANNELS +%token MAX_IDLE +%token MAX_INVITES %token MAX_NICK_CHANGES %token MAX_NICK_LENGTH %token MAX_NICK_TIME @@ -222,36 +228,28 @@ reset_block_state(void) %token MAX_TARGETS %token MAX_TOPIC_LENGTH %token MAX_WATCH -%token MESSAGE_LOCALE +%token MIN_IDLE %token MIN_NONWILDCARD %token MIN_NONWILDCARD_SIMPLE -%token MIN_IDLE -%token MAX_IDLE -%token RANDOM_IDLE -%token HIDE_IDLE_FROM_OPERS %token MODULE %token MODULES +%token MOTD %token NAME +%token NEED_IDENT %token NEED_PASSWORD -%token NETWORK_DESC +%token NETWORK_DESCRIPTION %token NETWORK_NAME %token NICK -%token NICK_CHANGES -%token NO_CREATE_ON_SPLIT -%token NO_JOIN_ON_SPLIT %token NO_OPER_FLOOD %token NO_TILDE %token NUMBER %token NUMBER_PER_CIDR -%token NUMBER_PER_IP -%token OPERATOR -%token OPERS_BYPASS_CALLERID +%token NUMBER_PER_IP_GLOBAL +%token NUMBER_PER_IP_LOCAL %token OPER_ONLY_UMODES -%token OPER_PASS_RESV -%token OPER_SPY_T %token OPER_UMODES -%token JOIN_FLOOD_COUNT -%token JOIN_FLOOD_TIME +%token OPERATOR +%token OPERS_BYPASS_CALLERID %token PACE_WAIT %token PACE_WAIT_SIMPLE %token PASSWORD @@ -260,185 +258,166 @@ reset_block_state(void) %token PING_TIME %token PORT %token QSTRING -%token QUIET_ON_BAN +%token RANDOM_IDLE %token REASON %token REDIRPORT %token REDIRSERV -%token REGEX_T %token REHASH %token REMOTE %token REMOTEBAN -%token RESTRICT_CHANNELS -%token RSA_PRIVATE_KEY_FILE -%token RSA_PUBLIC_KEY_FILE -%token SSL_CERTIFICATE_FILE -%token SSL_DH_PARAM_FILE -%token T_SSL_CLIENT_METHOD -%token T_SSL_SERVER_METHOD -%token T_SSLV3 -%token T_TLSV1 %token RESV %token RESV_EXEMPT +%token RSA_PRIVATE_KEY_FILE %token SECONDS MINUTES HOURS DAYS WEEKS MONTHS YEARS -%token SENDQ %token SEND_PASSWORD +%token SENDQ %token SERVERHIDE %token SERVERINFO -%token IRCD_SID -%token TKLINE_EXPIRE_NOTICES -%token T_SHARED -%token T_CLUSTER -%token TYPE %token SHORT_MOTD %token SPOOF -%token SPOOF_NOTICE +%token SQUIT %token STATS_E_DISABLED %token STATS_I_OPER_ONLY %token STATS_K_OPER_ONLY +%token STATS_M_OPER_ONLY %token STATS_O_OPER_ONLY %token STATS_P_OPER_ONLY -%token TBOOL -%token TMASKED -%token TS_MAX_DELTA -%token TS_WARN_DELTA -%token TWODOTS +%token STATS_U_OPER_ONLY %token T_ALL -%token T_BOTS -%token T_SOFTCALLERID +%token T_BIND %token T_CALLERID %token T_CCONN -%token T_CCONN_FULL -%token T_SSL_CIPHER_LIST +%token T_COMMAND +%token T_CLUSTER %token T_DEAF %token T_DEBUG %token T_DLINE %token T_EXTERNAL -%token T_FULL +%token T_FARCONNECT +%token T_FILE +%token T_FLOOD +%token T_GLOBOPS %token T_INVISIBLE %token T_IPV4 %token T_IPV6 %token T_LOCOPS -%token T_MAX_CLIENTS +%token T_LOG %token T_NCHANGE -%token T_OPERWALL +%token T_NONONREG +%token T_OPME +%token T_PREPEND +%token T_PSEUDO %token T_RECVQ %token T_REJ +%token T_RESTART %token T_SERVER +%token T_SERVICE %token T_SERVNOTICE %token T_SET +%token T_SHARED +%token T_SIZE %token T_SKILL +%token T_SOFTCALLERID %token T_SPY -%token T_SSL +%token T_TARGET +%token T_TLS %token T_UMODES -%token T_UNAUTH %token T_UNDLINE %token T_UNLIMITED %token T_UNRESV %token T_UNXLINE -%token T_GLOBOPS %token T_WALLOP +%token T_WALLOPS %token T_WEBIRC -%token T_RESTART -%token T_SERVICE -%token T_SERVICES_NAME +%token TBOOL +%token THROTTLE_COUNT %token THROTTLE_TIME -%token TRUE_NO_OPER_FLOOD +%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 +%token TYPE %token UNKLINE -%token USER -%token USE_EGD %token USE_LOGGING +%token USER %token VHOST %token VHOST6 +%token WARN_NO_CONNECT_BLOCK +%token WHOIS +%token WHOWAS_HISTORY_LENGTH %token XLINE -%token WARN_NO_NLINE -%token T_SIZE -%token T_FILE +%token XLINE_EXEMPT -%type QSTRING -%type NUMBER -%type timespec -%type timespec_ -%type sizespec -%type sizespec_ +%type QSTRING +%type NUMBER +%type timespec +%type timespec_ +%type sizespec +%type sizespec_ %% -conf: +conf: | conf conf_item ; conf_item: admin_entry | logging_entry | oper_entry - | channel_entry - | class_entry + | channel_entry + | class_entry | listen_entry | auth_entry | serverinfo_entry - | serverhide_entry + | serverhide_entry | resv_entry | service_entry | shared_entry - | cluster_entry + | cluster_entry | connect_entry | kill_entry | deny_entry - | exempt_entry - | general_entry + | exempt_entry + | general_entry | gecos_entry | modules_entry + | motd_entry + | pseudo_entry | error ';' | error '}' ; timespec_: { $$ = 0; } | timespec; -timespec: NUMBER timespec_ - { - $$ = $1 + $2; - } - | NUMBER SECONDS timespec_ - { - $$ = $1 + $3; - } - | NUMBER MINUTES timespec_ - { - $$ = $1 * 60 + $3; - } - | NUMBER HOURS timespec_ - { - $$ = $1 * 60 * 60 + $3; - } - | NUMBER DAYS timespec_ - { - $$ = $1 * 60 * 60 * 24 + $3; - } - | NUMBER WEEKS timespec_ - { - $$ = $1 * 60 * 60 * 24 * 7 + $3; - } - | NUMBER MONTHS timespec_ - { - $$ = $1 * 60 * 60 * 24 * 7 * 4 + $3; - } - | NUMBER YEARS timespec_ - { - $$ = $1 * 60 * 60 * 24 * 365 + $3; - } - ; - -sizespec_: { $$ = 0; } | sizespec; -sizespec: NUMBER sizespec_ { $$ = $1 + $2; } - | NUMBER BYTES sizespec_ { $$ = $1 + $3; } - | NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } - | NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; } - ; +timespec: NUMBER timespec_ { $$ = $1 + $2; } | + NUMBER SECONDS timespec_ { $$ = $1 + $3; } | + NUMBER MINUTES timespec_ { $$ = $1 * 60 + $3; } | + NUMBER HOURS timespec_ { $$ = $1 * 60 * 60 + $3; } | + NUMBER DAYS timespec_ { $$ = $1 * 60 * 60 * 24 + $3; } | + NUMBER WEEKS timespec_ { $$ = $1 * 60 * 60 * 24 * 7 + $3; } | + NUMBER MONTHS timespec_ { $$ = $1 * 60 * 60 * 24 * 7 * 4 + $3; } | + NUMBER YEARS timespec_ { $$ = $1 * 60 * 60 * 24 * 365 + $3; } + ; + +sizespec_: { $$ = 0; } | sizespec; +sizespec: NUMBER sizespec_ { $$ = $1 + $2; } | + NUMBER BYTES sizespec_ { $$ = $1 + $3; } | + NUMBER KBYTES sizespec_ { $$ = $1 * 1024 + $3; } | + NUMBER MBYTES sizespec_ { $$ = $1 * 1024 * 1024 + $3; } + ; /*************************************************************************** - * 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 ';' ; @@ -456,217 +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_max_clients | serverinfo_max_nick_length | - serverinfo_max_topic_length | serverinfo_ssl_dh_param_file | - serverinfo_rsa_private_key_file | serverinfo_vhost6 | - serverinfo_sid | serverinfo_ssl_certificate_file | - serverinfo_ssl_client_method | serverinfo_ssl_server_method | - serverinfo_ssl_cipher_list | - error ';' ; - - -serverinfo_ssl_client_method: T_SSL_CLIENT_METHOD '=' client_method_types ';' ; -serverinfo_ssl_server_method: T_SSL_SERVER_METHOD '=' server_method_types ';' ; - -client_method_types: client_method_types ',' client_method_type_item | client_method_type_item; -client_method_type_item: T_SSLV3 -{ -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) - SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv3); -#endif -} | T_TLSV1 +serverinfo_item: serverinfo_name | + serverinfo_hub | + serverinfo_description | + serverinfo_network_name | + serverinfo_network_description | + serverinfo_default_max_clients | + serverinfo_max_nick_length | + serverinfo_max_topic_length | + serverinfo_tls_dh_param_file | + serverinfo_tls_supported_groups | + serverinfo_rsa_private_key_file | + serverinfo_sid | + serverinfo_tls_certificate_file | + serverinfo_tls_cipher_list | + serverinfo_tls_cipher_suites | + serverinfo_tls_message_digest_algorithm | + error ';' ; + + +serverinfo_tls_certificate_file: TLS_CERTIFICATE_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.client_ctx) - SSL_CTX_clear_options(ServerInfo.client_ctx, SSL_OP_NO_TLSv1); -#endif + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.tls_certificate_file); + ConfigServerInfo.tls_certificate_file = xstrdup(yylval.string); + } }; -server_method_types: server_method_types ',' server_method_type_item | server_method_type_item; -server_method_type_item: T_SSLV3 -{ -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) - SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv3); -#endif -} | T_TLSV1 +serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) - SSL_CTX_clear_options(ServerInfo.server_ctx, SSL_OP_NO_TLSv1); -#endif + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.rsa_private_key_file); + ConfigServerInfo.rsa_private_key_file = xstrdup(yylval.string); + } }; -serverinfo_ssl_certificate_file: SSL_CERTIFICATE_FILE '=' QSTRING ';' +serverinfo_tls_dh_param_file: TLS_DH_PARAM_FILE '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + if (conf_parser_ctx.pass == 2) { - if (!ServerInfo.rsa_private_key_file) - { - conf_error_report("No rsa_private_key_file specified, SSL disabled"); - break; - } - - if (SSL_CTX_use_certificate_file(ServerInfo.server_ctx, yylval.string, - SSL_FILETYPE_PEM) <= 0 || - SSL_CTX_use_certificate_file(ServerInfo.client_ctx, yylval.string, - SSL_FILETYPE_PEM) <= 0) - { - report_crypto_errors(); - conf_error_report("Could not open/read certificate file"); - break; - } - - if (SSL_CTX_use_PrivateKey_file(ServerInfo.server_ctx, ServerInfo.rsa_private_key_file, - SSL_FILETYPE_PEM) <= 0 || - SSL_CTX_use_PrivateKey_file(ServerInfo.client_ctx, ServerInfo.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(ServerInfo.server_ctx) || - !SSL_CTX_check_private_key(ServerInfo.client_ctx)) - { - report_crypto_errors(); - conf_error_report("Could not read RSA private key"); - break; - } + xfree(ConfigServerInfo.tls_dh_param_file); + ConfigServerInfo.tls_dh_param_file = xstrdup(yylval.string); } -#endif }; -serverinfo_rsa_private_key_file: RSA_PRIVATE_KEY_FILE '=' QSTRING ';' +serverinfo_tls_cipher_list: TLS_CIPHER_LIST '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 1) + if (conf_parser_ctx.pass == 2) { - BIO *file; - - if (ServerInfo.rsa_private_key) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; - } - - if (ServerInfo.rsa_private_key_file) - { - MyFree(ServerInfo.rsa_private_key_file); - ServerInfo.rsa_private_key_file = NULL; - } - - ServerInfo.rsa_private_key_file = xstrdup(yylval.string); - - if ((file = BIO_new_file(yylval.string, "r")) == NULL) - { - conf_error_report("File open failed, ignoring"); - break; - } - - ServerInfo.rsa_private_key = PEM_read_bio_RSAPrivateKey(file, NULL, 0, NULL); - - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - - if (ServerInfo.rsa_private_key == NULL) - { - conf_error_report("Couldn't extract key, ignoring"); - break; - } - - if (!RSA_check_key(ServerInfo.rsa_private_key)) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; - - conf_error_report("Invalid key, ignoring"); - break; - } - - /* require 2048 bit (256 byte) key */ - if (RSA_size(ServerInfo.rsa_private_key) != 256) - { - RSA_free(ServerInfo.rsa_private_key); - ServerInfo.rsa_private_key = NULL; - - conf_error_report("Not a 2048 bit key, ignoring"); - } + xfree(ConfigServerInfo.tls_cipher_list); + ConfigServerInfo.tls_cipher_list = xstrdup(yylval.string); } -#endif }; -serverinfo_ssl_dh_param_file: SSL_DH_PARAM_FILE '=' QSTRING ';' +serverinfo_tls_cipher_suites: TLS_CIPHER_SUITES '=' QSTRING ';' { -/* TBD - XXX: error reporting */ -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) + 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(ServerInfo.server_ctx, dh); - - DH_free(dh); - } - } + xfree(ConfigServerInfo.tls_cipher_suites); + ConfigServerInfo.tls_cipher_suites = xstrdup(yylval.string); } -#endif }; -serverinfo_ssl_cipher_list: T_SSL_CIPHER_LIST '=' QSTRING ';' +serverinfo_tls_message_digest_algorithm: TLS_MESSAGE_DIGEST_ALGORITHM '=' QSTRING ';' { -#ifdef HAVE_LIBCRYPTO - if (conf_parser_ctx.pass == 2 && ServerInfo.server_ctx) - SSL_CTX_set_cipher_list(ServerInfo.server_ctx, yylval.string); -#endif + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.tls_message_digest_algorithm); + ConfigServerInfo.tls_message_digest_algorithm = xstrdup(yylval.string); + } +} + +serverinfo_tls_supported_groups: TLS_SUPPORTED_GROUPS '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerInfo.tls_supported_groups); + ConfigServerInfo.tls_supported_groups = xstrdup(yylval.string); + } }; -serverinfo_name: NAME '=' QSTRING ';' +serverinfo_name: NAME '=' QSTRING ';' { - /* this isn't rehashable */ - if (conf_parser_ctx.pass == 2 && !ServerInfo.name) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && ConfigServerInfo.name == NULL) { - if (valid_servname(yylval.string)) - ServerInfo.name = xstrdup(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 ';' +serverinfo_sid: IRCD_SID '=' QSTRING ';' { - /* this isn't rehashable */ - if (conf_parser_ctx.pass == 2 && !ServerInfo.sid) + /* This isn't rehashable */ + if (conf_parser_ctx.pass == 2 && ConfigServerInfo.sid == NULL) { if (valid_sid(yylval.string)) - ServerInfo.sid = xstrdup(yylval.string); + ConfigServerInfo.sid = xstrdup(yylval.string); else { conf_error_report("Ignoring serverinfo::sid -- invalid SID. Aborting."); - exit(0); + exit(EXIT_FAILURE); } } }; @@ -675,8 +557,9 @@ serverinfo_description: DESCRIPTION '=' { if (conf_parser_ctx.pass == 2) { - MyFree(ServerInfo.description); - ServerInfo.description = xstrdup(yylval.string); + xfree(ConfigServerInfo.description); + ConfigServerInfo.description = xstrdup(yylval.string); + strlcpy(me.info, ConfigServerInfo.description, sizeof(me.info)); } }; @@ -684,106 +567,46 @@ serverinfo_network_name: NETWORK_NAME '= { if (conf_parser_ctx.pass == 2) { - char *p; - - if ((p = strchr(yylval.string, ' ')) != NULL) - p = '\0'; - - MyFree(ServerInfo.network_name); - ServerInfo.network_name = xstrdup(yylval.string); - } -}; - -serverinfo_network_desc: NETWORK_DESC '=' QSTRING ';' -{ - if (conf_parser_ctx.pass == 2) - { - MyFree(ServerInfo.network_desc); - ServerInfo.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; + char *p = strchr(yylval.string, ' '); - if (getaddrinfo(yylval.string, NULL, &hints, &res)) - ilog(LOG_TYPE_IRCD, "Invalid netmask for server vhost(%s)", yylval.string); - else - { - assert(res != NULL); + if (p) + *p = '\0'; - memcpy(&ServerInfo.ip, res->ai_addr, res->ai_addrlen); - ServerInfo.ip.ss.ss_family = res->ai_family; - ServerInfo.ip.ss_len = res->ai_addrlen; - freeaddrinfo(res); - - ServerInfo.specific_ipv4_vhost = 1; - } + xfree(ConfigServerInfo.network_name); + ConfigServerInfo.network_name = xstrdup(yylval.string); } }; -serverinfo_vhost6: VHOST6 '=' QSTRING ';' +serverinfo_network_description: NETWORK_DESCRIPTION '=' QSTRING ';' { -#ifdef IPV6 - 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 != NULL); - - memcpy(&ServerInfo.ip6, res->ai_addr, res->ai_addrlen); - ServerInfo.ip6.ss.ss_family = res->ai_family; - ServerInfo.ip6.ss_len = res->ai_addrlen; - freeaddrinfo(res); + if (conf_parser_ctx.pass != 2) + break; - ServerInfo.specific_ipv6_vhost = 1; - } - } -#endif + xfree(ConfigServerInfo.network_description); + ConfigServerInfo.network_description = xstrdup(yylval.string); }; -serverinfo_max_clients: T_MAX_CLIENTS '=' NUMBER ';' +serverinfo_default_max_clients: DEFAULT_MAX_CLIENTS '=' NUMBER ';' { 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); - ServerInfo.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]; - 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); - ServerInfo.max_clients = MAXCLIENTS_MAX; + + ConfigServerInfo.default_max_clients = MAXCLIENTS_MAX; } else - ServerInfo.max_clients = $3; + ConfigServerInfo.default_max_clients = $3; }; serverinfo_max_nick_length: MAX_NICK_LENGTH '=' NUMBER ';' @@ -794,7 +617,7 @@ serverinfo_max_nick_length: MAX_NICK_LEN if ($3 < 9) { conf_error_report("max_nick_length too low, setting to 9"); - ServerInfo.max_nick_length = 9; + ConfigServerInfo.max_nick_length = 9; } else if ($3 > NICKLEN) { @@ -802,10 +625,11 @@ serverinfo_max_nick_length: MAX_NICK_LEN snprintf(buf, sizeof(buf), "max_nick_length too high, setting to %d", NICKLEN); conf_error_report(buf); - ServerInfo.max_nick_length = NICKLEN; + + ConfigServerInfo.max_nick_length = NICKLEN; } else - ServerInfo.max_nick_length = $3; + ConfigServerInfo.max_nick_length = $3; }; serverinfo_max_topic_length: MAX_TOPIC_LENGTH '=' NUMBER ';' @@ -816,7 +640,7 @@ serverinfo_max_topic_length: MAX_TOPIC_L if ($3 < 80) { conf_error_report("max_topic_length too low, setting to 80"); - ServerInfo.max_topic_length = 80; + ConfigServerInfo.max_topic_length = 80; } else if ($3 > TOPICLEN) { @@ -824,67 +648,171 @@ serverinfo_max_topic_length: MAX_TOPIC_L snprintf(buf, sizeof(buf), "max_topic_length too high, setting to %d", TOPICLEN); conf_error_report(buf); - ServerInfo.max_topic_length = TOPICLEN; + + ConfigServerInfo.max_topic_length = TOPICLEN; } else - ServerInfo.max_topic_length = $3; + ConfigServerInfo.max_topic_length = $3; }; -serverinfo_hub: HUB '=' TBOOL ';' +serverinfo_hub: HUB '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - ServerInfo.hub = yylval.number; + 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 | admin_description | - admin_email | error ';' ; +admin_item: admin_name | + admin_description | + admin_email | + error ';' ; -admin_name: NAME '=' QSTRING ';' +admin_name: NAME '=' QSTRING ';' { - if (conf_parser_ctx.pass == 2) - { - MyFree(AdminInfo.name); - AdminInfo.name = xstrdup(yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.name); + ConfigAdminInfo.name = xstrdup(yylval.string); }; admin_email: EMAIL '=' QSTRING ';' { - if (conf_parser_ctx.pass == 2) - { - MyFree(AdminInfo.email); - AdminInfo.email = xstrdup(yylval.string); - } + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.email); + ConfigAdminInfo.email = xstrdup(yylval.string); }; admin_description: DESCRIPTION '=' QSTRING ';' { + if (conf_parser_ctx.pass != 2) + break; + + xfree(ConfigAdminInfo.description); + ConfigAdminInfo.description = xstrdup(yylval.string); +}; + + +/*************************************************************************** + * motd {} section + ***************************************************************************/ +motd_entry: MOTD +{ + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} '{' motd_items '}' ';' +{ + dlink_node *node; + + if (conf_parser_ctx.pass != 2) + break; + + if (!block_state.file.buf[0]) + break; + + DLINK_FOREACH(node, block_state.mask.list.head) + motd_add(node->data, block_state.file.buf); +}; + +motd_items: motd_items motd_item | motd_item; +motd_item: motd_mask | motd_file | error ';' ; + +motd_mask: MASK '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); +}; + +motd_file: T_FILE '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf)); +}; + + +/*************************************************************************** + * pseudo {} section + ***************************************************************************/ +pseudo_entry: T_PSEUDO +{ + if (conf_parser_ctx.pass == 2) + reset_block_state(); +} '{' pseudo_items '}' ';' +{ + if (conf_parser_ctx.pass != 2) + break; + + if (!block_state.command.buf[0] || + !block_state.name.buf[0] || + !block_state.nick.buf[0] || + !block_state.host.buf[0]) + break; + + pseudo_register(block_state.name.buf, block_state.nick.buf, block_state.host.buf, + block_state.prepend.buf, block_state.command.buf); +}; + +pseudo_items: pseudo_items pseudo_item | pseudo_item; +pseudo_item: pseudo_command | pseudo_prepend | pseudo_name | pseudo_target | error ';' ; + +pseudo_command: T_COMMAND '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.command.buf, yylval.string, sizeof(block_state.command.buf)); +}; + +pseudo_name: NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); +}; + +pseudo_prepend: T_PREPEND '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.prepend.buf, yylval.string, sizeof(block_state.prepend.buf)); +}; + +pseudo_target: T_TARGET '=' QSTRING ';' +{ if (conf_parser_ctx.pass == 2) { - MyFree(AdminInfo.description); - AdminInfo.description = xstrdup(yylval.string); + struct split_nuh_item nuh; + + nuh.nuhmask = yylval.string; + nuh.nickptr = NULL; + nuh.userptr = block_state.nick.buf; + nuh.hostptr = block_state.host.buf; + nuh.nicksize = 0; + nuh.usersize = sizeof(block_state.nick.buf); + nuh.hostsize = sizeof(block_state.host.buf); + + split_nuh(&nuh); } }; + /*************************************************************************** - * 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 | - error ';' ; +logging_item: logging_use_logging | logging_file_entry | + error ';' ; logging_use_logging: USE_LOGGING '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - ConfigLoggingEntry.use_logging = yylval.number; + ConfigLog.use_logging = yylval.number; }; logging_file_entry: @@ -897,7 +825,7 @@ logging_file_entry: break; if (block_state.type.value && block_state.file.buf[0]) - log_add_file(block_state.type.value, block_state.size.value, + log_set_file(block_state.type.value, block_state.size.value, block_state.file.buf); }; @@ -927,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 @@ -938,10 +866,14 @@ logging_file_type_item: USER { if (conf_parser_ctx.pass == 2) block_state.type.value = LOG_TYPE_OPER; -} | GLINE +} | XLINE { if (conf_parser_ctx.pass == 2) - block_state.type.value = LOG_TYPE_GLINE; + block_state.type.value = LOG_TYPE_XLINE; +} | RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.type.value = LOG_TYPE_RESV; } | T_DLINE { if (conf_parser_ctx.pass == 2) @@ -962,9 +894,9 @@ logging_file_type_item: USER /*************************************************************************** - * section oper + * operator {} section ***************************************************************************/ -oper_entry: OPERATOR +oper_entry: OPERATOR { if (conf_parser_ctx.pass != 2) break; @@ -973,78 +905,72 @@ oper_entry: OPERATOR block_state.flags.value |= CONF_FLAGS_ENCRYPTED; } '{' oper_items '}' ';' { - dlink_node *ptr = 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(ptr, block_state.mask.list.head) + 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 = ptr->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); if (block_state.rpass.buf[0]) conf->passwd = xstrdup(block_state.rpass.buf); + if (block_state.whois.buf[0]) + conf->whois = xstrdup(block_state.whois.buf); + 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); - -#ifdef HAVE_LIBCRYPTO - if (block_state.file.buf[0]) - { - BIO *file = NULL; - RSA *pkey = NULL; - - if ((file = BIO_new_file(block_state.file.buf, "r")) == NULL) - { - conf_error_report("Ignoring rsa_public_key_file -- file doesn't exist"); - break; - } - - if ((pkey = PEM_read_bio_RSA_PUBKEY(file, NULL, 0, NULL)) == NULL) - conf_error_report("Ignoring rsa_public_key_file -- Key invalid; check key syntax."); - - conf->rsa_public_key = pkey; - BIO_set_close(file, BIO_CLOSE); - BIO_free(file); - } -#endif /* HAVE_LIBCRYPTO */ } }; oper_items: oper_items oper_item | oper_item; -oper_item: oper_name | oper_user | oper_password | - oper_umodes | oper_class | oper_encrypted | - oper_rsa_public_key_file | oper_flags | error ';' ; +oper_item: oper_name | + oper_user | + oper_password | + oper_whois | + oper_umodes | + oper_class | + oper_encrypted | + oper_tls_certificate_fingerprint | + oper_tls_connection_required | + oper_flags | + error ';' ; oper_name: NAME '=' QSTRING ';' { @@ -1064,21 +990,38 @@ oper_password: PASSWORD '=' QSTRING ';' strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -oper_encrypted: ENCRYPTED '=' TBOOL ';' +oper_whois: WHOIS '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) - { - if (yylval.number) - block_state.flags.value |= CONF_FLAGS_ENCRYPTED; - else - block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; - } + strlcpy(block_state.whois.buf, yylval.string, sizeof(block_state.whois.buf)); +}; + +oper_encrypted: ENCRYPTED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass != 2) + break; + + if (yylval.number) + block_state.flags.value |= CONF_FLAGS_ENCRYPTED; + else + block_state.flags.value &= ~CONF_FLAGS_ENCRYPTED; }; -oper_rsa_public_key_file: RSA_PUBLIC_KEY_FILE '=' QSTRING ';' +oper_tls_certificate_fingerprint: TLS_CERTIFICATE_FINGERPRINT '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) - strlcpy(block_state.file.buf, yylval.string, sizeof(block_state.file.buf)); + strlcpy(block_state.cert.buf, yylval.string, sizeof(block_state.cert.buf)); +}; + +oper_tls_connection_required: TLS_CONNECTION_REQUIRED '=' TBOOL ';' +{ + if (conf_parser_ctx.pass != 2) + break; + + if (yylval.number) + block_state.flags.value |= CONF_FLAGS_TLS; + else + block_state.flags.value &= ~CONF_FLAGS_TLS; }; oper_class: CLASS '=' QSTRING ';' @@ -1091,21 +1034,13 @@ 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; -} | T_CCONN_FULL -{ - if (conf_parser_ctx.pass == 2) - block_state.modes.value |= UMODE_CCONN_FULL; } | T_DEAF { if (conf_parser_ctx.pass == 2) @@ -1114,14 +1049,22 @@ 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) block_state.modes.value |= UMODE_HIDDEN; +} | HIDE_CHANS +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_HIDECHANS; +} | HIDE_IDLE +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_HIDEIDLE; } | T_SKILL { if (conf_parser_ctx.pass == 2) @@ -1134,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) @@ -1146,10 +1085,6 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - if (conf_parser_ctx.pass == 2) - block_state.modes.value |= UMODE_OPERWALL; } | T_SERVNOTICE { if (conf_parser_ctx.pass == 2) @@ -1174,27 +1109,55 @@ oper_umodes_item: T_BOTS { if (conf_parser_ctx.pass == 2) block_state.modes.value |= UMODE_LOCOPS; +} | T_NONONREG +{ + if (conf_parser_ctx.pass == 2) + block_state.modes.value |= UMODE_REGONLY; +} | T_FARCONNECT +{ + 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: GLOBAL_KILL +oper_flags_item: KILL ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_KILL_REMOTE; +} | KILL +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_KILL; +} | CONNECT ':' REMOTE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_CONNECT_REMOTE; +} | CONNECT { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_GLOBAL_KILL; -} | REMOTE + block_state.port.value |= OPER_FLAG_CONNECT; +} | SQUIT ':' REMOTE { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_REMOTE; + block_state.port.value |= OPER_FLAG_SQUIT_REMOTE; +} | SQUIT +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_SQUIT; } | KLINE { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_K; + block_state.port.value |= OPER_FLAG_KLINE; } | UNKLINE { if (conf_parser_ctx.pass == 2) @@ -1210,11 +1173,11 @@ oper_flags_item: GLOBAL_KILL } | XLINE { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_X; -} | GLINE + block_state.port.value |= OPER_FLAG_XLINE; +} | T_UNXLINE { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_GLINE; + block_state.port.value |= OPER_FLAG_UNXLINE; } | DIE { if (conf_parser_ctx.pass == 2) @@ -1223,6 +1186,10 @@ oper_flags_item: GLOBAL_KILL { 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) @@ -1231,22 +1198,18 @@ oper_flags_item: GLOBAL_KILL { if (conf_parser_ctx.pass == 2) block_state.port.value |= OPER_FLAG_ADMIN; -} | NICK_CHANGES -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_N; -} | T_OPERWALL -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_OPERWALL; } | T_GLOBOPS { if (conf_parser_ctx.pass == 2) block_state.port.value |= OPER_FLAG_GLOBOPS; -} | OPER_SPY_T +} | T_WALLOPS +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_WALLOPS; +} | T_LOCOPS { if (conf_parser_ctx.pass == 2) - block_state.port.value |= OPER_FLAG_OPER_SPY; + block_state.port.value |= OPER_FLAG_LOCOPS; } | REMOTEBAN { if (conf_parser_ctx.pass == 2) @@ -1259,11 +1222,35 @@ oper_flags_item: GLOBAL_KILL { if (conf_parser_ctx.pass == 2) block_state.port.value |= OPER_FLAG_MODULE; +} | T_OPME +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_OPME; +} | NICK ':' RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_NICK_RESV; +} | JOIN ':' RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_JOIN_RESV; +} | RESV +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_RESV; +} | T_UNRESV +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_UNRESV; +} | CLOSE +{ + if (conf_parser_ctx.pass == 2) + block_state.port.value |= OPER_FLAG_CLOSE; }; /*************************************************************************** - * section class + * class {} section ***************************************************************************/ class_entry: CLASS { @@ -1274,68 +1261,72 @@ 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->flags = block_state.flags.value; 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->min_idle = block_state.min_idle.value; - class->max_idle = block_state.max_idle.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; - if (class->number_per_cidr && block_state.number_per_cidr.value) - if ((class->cidr_bitlen_ipv4 && block_state.cidr_bitlen_ipv4.value) || - (class->cidr_bitlen_ipv6 && block_state.cidr_bitlen_ipv6.value)) - if ((class->cidr_bitlen_ipv4 != block_state.cidr_bitlen_ipv4.value) || - (class->cidr_bitlen_ipv6 != block_state.cidr_bitlen_ipv6.value)) - rebuild_cidr_list(class); + if (block_state.min_idle.value > block_state.max_idle.value) + { + block_state.min_idle.value = 0; + block_state.max_idle.value = 0; + block_state.flags.value &= ~CLASS_FLAGS_FAKE_IDLE; + } + class->flags = block_state.flags.value; + class->min_idle = block_state.min_idle.value; + class->max_idle = block_state.max_idle.value; + + 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; class_item: class_name | - class_cidr_bitlen_ipv4 | class_cidr_bitlen_ipv6 | + class_cidr_bitlen_ipv4 | + class_cidr_bitlen_ipv6 | class_ping_time | - class_number_per_cidr | - class_number_per_ip | + class_number_per_cidr | + 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 | - error ';' ; + error ';' ; -class_name: NAME '=' QSTRING ';' +class_name: NAME '=' QSTRING ';' { if (conf_parser_ctx.pass == 1) strlcpy(block_state.class.buf, yylval.string, sizeof(block_state.class.buf)); @@ -1347,40 +1338,34 @@ 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.value = $3; + block_state.max_perip_local.value = $3; }; -class_connectfreq: CONNECTFREQ '=' timespec ';' +class_number_per_ip_global: NUMBER_PER_IP_GLOBAL '=' NUMBER ';' { if (conf_parser_ctx.pass == 1) - block_state.con_freq.value = $3; + block_state.max_perip_global.value = $3; }; -class_max_number: MAX_NUMBER '=' NUMBER ';' -{ - if (conf_parser_ctx.pass == 1) - block_state.max_total.value = $3; -}; - -class_max_global: MAX_GLOBAL '=' NUMBER ';' +class_connectfreq: CONNECTFREQ '=' timespec ';' { if (conf_parser_ctx.pass == 1) - block_state.max_global.value = $3; + block_state.con_freq.value = $3; }; -class_max_local: MAX_LOCAL '=' NUMBER ';' +class_max_channels: MAX_CHANNELS '=' NUMBER ';' { if (conf_parser_ctx.pass == 1) - block_state.max_local.value = $3; + block_state.max_channels.value = $3; }; -class_max_ident: MAX_IDENT '=' NUMBER ';' +class_max_number: MAX_NUMBER '=' NUMBER ';' { if (conf_parser_ctx.pass == 1) - block_state.max_ident.value = $3; + block_state.max_total.value = $3; }; class_sendq: SENDQ '=' sizespec ';' @@ -1416,21 +1401,27 @@ class_number_per_cidr: NUMBER_PER_CIDR ' class_min_idle: MIN_IDLE '=' timespec ';' { - if (conf_parser_ctx.pass == 1) - block_state.min_idle.value = $3; + if (conf_parser_ctx.pass != 1) + break; + + block_state.min_idle.value = $3; + block_state.flags.value |= CLASS_FLAGS_FAKE_IDLE; }; class_max_idle: MAX_IDLE '=' timespec ';' { - if (conf_parser_ctx.pass == 1) - block_state.max_idle.value = $3; + if (conf_parser_ctx.pass != 1) + break; + + block_state.max_idle.value = $3; + block_state.flags.value |= CLASS_FLAGS_FAKE_IDLE; }; class_flags: IRCD_FLAGS { if (conf_parser_ctx.pass == 1) - block_state.flags.value = 0; -} '=' class_flags_items ';'; + block_state.flags.value &= CLASS_FLAGS_FAKE_IDLE; +} '=' class_flags_items ';'; class_flags_items: class_flags_items ',' class_flags_item | class_flags_item; class_flags_item: RANDOM_IDLE @@ -1445,7 +1436,7 @@ class_flags_item: RANDOM_IDLE /*************************************************************************** - * section listen + * listen {} section ***************************************************************************/ listen_entry: LISTEN { @@ -1456,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) @@ -1471,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; @@ -1484,33 +1483,29 @@ port_item: NUMBER { if (conf_parser_ctx.pass == 2) { - if (block_state.flags.value & LISTENER_SSL) -#ifdef HAVE_LIBCRYPTO - if (!ServerInfo.server_ctx) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_TLS) + { + conf_error_report("TLS not available - port closed"); + break; + } #endif - { - conf_error_report("SSL not available - port closed"); - break; - } - add_listener($1, block_state.addr.buf, block_state.flags.value); + listener_add($1, block_state.addr.buf, block_state.flags.value); } } | NUMBER TWODOTS NUMBER { if (conf_parser_ctx.pass == 2) { - int i; - - if (block_state.flags.value & LISTENER_SSL) -#ifdef HAVE_LIBCRYPTO - if (!ServerInfo.server_ctx) +#ifndef HAVE_TLS + if (block_state.flags.value & LISTENER_TLS) + { + conf_error_report("TLS not available - port closed"); + break; + } #endif - { - conf_error_report("SSL not available - port closed"); - break; - } - for (i = $1; i <= $3; ++i) - add_listener(i, block_state.addr.buf, block_state.flags.value); + for (int i = $1; i <= $3; ++i) + listener_add(i, block_state.addr.buf, block_state.flags.value); } }; @@ -1526,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 { @@ -1535,46 +1531,57 @@ auth_entry: IRCD_AUTH reset_block_state(); } '{' auth_items '}' ';' { - dlink_node *ptr = NULL; + dlink_node *node; if (conf_parser_ctx.pass != 2) break; - DLINK_FOREACH(ptr, block_state.mask.list.head) + DLINK_FOREACH(node, block_state.mask.list.head) { - struct MaskItem *conf = NULL; struct split_nuh_item nuh; + char *s = node->data; - nuh.nuhmask = ptr->data; + if (EmptyString(s)) + continue; + + 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(collapse(block_state.user.buf)); - conf->host = xstrdup(collapse(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); if (block_state.name.buf[0]) - conf->passwd = xstrdup(block_state.name.buf); + 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); } -}; +}; auth_items: auth_items auth_item | auth_item; -auth_item: auth_user | auth_passwd | auth_class | auth_flags | - auth_spoof | auth_redir_serv | auth_redir_port | - auth_encrypted | error ';' ; +auth_item: auth_user | + auth_passwd | + auth_class | + auth_flags | + auth_spoof | + auth_redir_serv | + auth_redir_port | + auth_encrypted | + error ';' ; auth_user: USER '=' QSTRING ';' { @@ -1608,15 +1615,11 @@ auth_encrypted: ENCRYPTED '=' TBOOL ';' auth_flags: IRCD_FLAGS { if (conf_parser_ctx.pass == 2) - block_state.flags.value &= CONF_FLAGS_ENCRYPTED; -} '=' auth_flags_items ';'; + block_state.flags.value &= (CONF_FLAGS_ENCRYPTED | CONF_FLAGS_SPOOF_IP); +} '=' 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; @@ -1624,6 +1627,10 @@ auth_flags_item: SPOOF_NOTICE { if (conf_parser_ctx.pass == 2) block_state.flags.value |= CONF_FLAGS_EXEMPTKLINE; +} | XLINE_EXEMPT +{ + if (conf_parser_ctx.pass == 2) + block_state.flags.value |= CONF_FLAGS_EXEMPTXLINE; } | NEED_IDENT { if (conf_parser_ctx.pass == 2) @@ -1636,10 +1643,6 @@ auth_flags_item: SPOOF_NOTICE { if (conf_parser_ctx.pass == 2) block_state.flags.value |= CONF_FLAGS_NO_TILDE; -} | GLINE_EXEMPT -{ - if (conf_parser_ctx.pass == 2) - block_state.flags.value |= CONF_FLAGS_EXEMPTGLINE; } | RESV_EXEMPT { if (conf_parser_ctx.pass == 2) @@ -1654,12 +1657,12 @@ auth_flags_item: SPOOF_NOTICE block_state.flags.value |= CONF_FLAGS_NEED_PASSWORD; }; -auth_spoof: SPOOF '=' QSTRING ';' +auth_spoof: SPOOF '=' QSTRING ';' { if (conf_parser_ctx.pass != 2) break; - if (strlen(yylval.string) <= HOSTLEN && valid_hostname(yylval.string)) + if (valid_hostname(yylval.string)) { strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); block_state.flags.value |= CONF_FLAGS_SPOOF_IP; @@ -1688,7 +1691,7 @@ auth_redir_port: REDIRPORT '=' NUMBER '; /*************************************************************************** - * section resv + * resv {} section ***************************************************************************/ resv_entry: RESV { @@ -1697,34 +1700,38 @@ resv_entry: RESV reset_block_state(); strlcpy(block_state.rpass.buf, CONF_NOREASON, sizeof(block_state.rpass.buf)); -} '{' resv_items '}' ';'; +} '{' resv_items '}' ';' +{ + if (conf_parser_ctx.pass != 2) + break; + + resv_make(block_state.name.buf, block_state.rpass.buf, &block_state.mask.list); +}; -resv_items: resv_items resv_item | resv_item; -resv_item: resv_creason | resv_channel | resv_nick | error ';' ; +resv_items: resv_items resv_item | resv_item; +resv_item: resv_mask | resv_reason | resv_exempt | error ';' ; -resv_creason: REASON '=' QSTRING ';' +resv_mask: MASK '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) - strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); + strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -resv_channel: CHANNEL '=' QSTRING ';' +resv_reason: REASON '=' QSTRING ';' { - if (conf_parser_ctx.pass != 2) - break; - - if (IsChanPrefix(*yylval.string)) - create_channel_resv(yylval.string, block_state.rpass.buf, 1); + if (conf_parser_ctx.pass == 2) + strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; -resv_nick: NICK '=' QSTRING ';' +resv_exempt: EXEMPT '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) - create_nick_resv(yylval.string, block_state.rpass.buf, 1); + dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.mask.list); }; + /*************************************************************************** - * section service + * service {} section ***************************************************************************/ service_entry: T_SERVICE '{' service_items '}' ';'; @@ -1733,18 +1740,19 @@ service_item: service_name | error; service_name: NAME '=' QSTRING ';' { - if (conf_parser_ctx.pass == 2) + if (conf_parser_ctx.pass != 2) + break; + + if (server_valid_name(yylval.string) == true) { - if (valid_servname(yylval.string)) - { - 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 { @@ -1759,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->user = 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; @@ -1848,8 +1854,9 @@ shared_type_item: KLINE block_state.flags.value = SHARED_ALL; }; + /*************************************************************************** - * section cluster + * cluster {} section ***************************************************************************/ cluster_entry: T_CLUSTER { @@ -1859,21 +1866,19 @@ 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; -cluster_item: cluster_name | cluster_type | error ';' ; +cluster_items: cluster_items cluster_item | cluster_item; +cluster_item: cluster_name | cluster_type | error ';' ; cluster_name: NAME '=' QSTRING ';' { @@ -1887,63 +1892,65 @@ cluster_type: TYPE block_state.flags.value = 0; } '=' cluster_types ';' ; -cluster_types: cluster_types ',' cluster_type_item | cluster_type_item; +cluster_types: cluster_types ',' cluster_type_item | cluster_type_item; 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 +connect_entry: CONNECT { if (conf_parser_ctx.pass != 2) break; 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) @@ -1953,23 +1960,33 @@ connect_entry: CONNECT !block_state.host.buf[0]) break; - if (!(block_state.rpass.buf[0] || - block_state.spass.buf[0])) + if (!block_state.rpass.buf[0] || + !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); conf->name = xstrdup(block_state.name.buf); conf->passwd = xstrdup(block_state.rpass.buf); conf->spasswd = xstrdup(block_state.spass.buf); - conf->cipher_list = xstrdup(block_state.ciph.buf); + + if (block_state.cert.buf[0]) + conf->certfp = xstrdup(block_state.cert.buf); + + if (block_state.ciph.buf[0]) + conf->cipher_list = xstrdup(block_state.ciph.buf); dlinkMoveList(&block_state.leaf.list, &conf->leaf_list); dlinkMoveList(&block_state.hub.list, &conf->hub_list); @@ -1983,28 +2000,39 @@ 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 != NULL); + assert(res); + + conf->bind = xcalloc(sizeof(*conf->bind)); - memcpy(&conf->bind, res->ai_addr, res->ai_addrlen); - conf->bind.ss.ss_family = res->ai_family; - conf->bind.ss_len = res->ai_addrlen; + 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_send_password | connect_accept_password | - connect_aftype | connect_port | connect_ssl_cipher_list | - connect_flags | connect_hub_mask | connect_leaf_mask | - connect_class | connect_encrypted | +connect_item: connect_name | + connect_host | + connect_timeout | + connect_bind | + connect_send_password | + connect_accept_password | + connect_tls_certificate_fingerprint | + connect_aftype | + connect_port | + connect_tls_cipher_list | + connect_flags | + connect_hub_mask | + connect_leaf_mask | + connect_class | + connect_encrypted | error ';' ; connect_name: NAME '=' QSTRING ';' @@ -2013,26 +2041,32 @@ connect_name: NAME '=' QSTRING ';' strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -connect_host: HOST '=' QSTRING ';' +connect_host: HOST '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) 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)); }; - + connect_send_password: SEND_PASSWORD '=' QSTRING ';' { 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, ' ') != NULL) + 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)); @@ -2043,14 +2077,20 @@ 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, ' ') != NULL) + 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_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)); +}; + connect_port: PORT '=' NUMBER ';' { if (conf_parser_ctx.pass == 2) @@ -2063,26 +2103,24 @@ connect_aftype: AFTYPE '=' T_IPV4 ';' block_state.aftype.value = AF_INET; } | AFTYPE '=' T_IPV6 ';' { -#ifdef IPV6 if (conf_parser_ctx.pass == 2) block_state.aftype.value = AF_INET6; -#endif }; 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 ';' @@ -2096,13 +2134,13 @@ connect_encrypted: ENCRYPTED '=' TBOOL ' } }; -connect_hub_mask: HUB_MASK '=' QSTRING ';' +connect_hub_mask: HUB_MASK '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.hub.list); }; -connect_leaf_mask: LEAF_MASK '=' QSTRING ';' +connect_leaf_mask: LEAF_MASK '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) dlinkAdd(xstrdup(yylval.string), make_dlink_node(), &block_state.leaf.list); @@ -2114,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 { @@ -2135,8 +2173,6 @@ kill_entry: KILL reset_block_state(); } '{' kill_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; @@ -2144,68 +2180,19 @@ kill_entry: KILL !block_state.host.buf[0]) break; + struct MaskItem *conf = conf_make(CONF_KLINE); + conf->user = xstrdup(block_state.user.buf); + conf->host = xstrdup(block_state.host.buf); - if (block_state.port.value == 1) - { -#ifdef HAVE_LIBPCRE - void *exp_user = NULL; - void *exp_host = NULL; - const char *errptr = NULL; - - if (!(exp_user = ircd_pcre_compile(block_state.user.buf, &errptr)) || - !(exp_host = ircd_pcre_compile(block_state.host.buf, &errptr))) - { - ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: %s", - errptr); - break; - } - - conf = conf_make(CONF_RKLINE); - conf->regexuser = exp_user; - conf->regexhost = exp_host; - - conf->user = xstrdup(block_state.user.buf); - conf->host = xstrdup(block_state.host.buf); - - if (block_state.rpass.buf[0]) - conf->reason = xstrdup(block_state.rpass.buf); - else - conf->reason = xstrdup(CONF_NOREASON); -#else - ilog(LOG_TYPE_IRCD, "Failed to add regular expression based K-Line: no PCRE support"); - break; -#endif - } + if (block_state.rpass.buf[0]) + conf->reason = xstrdup(block_state.rpass.buf); else - { - conf = conf_make(CONF_KLINE); - - conf->user = xstrdup(block_state.user.buf); - conf->host = xstrdup(block_state.host.buf); - - if (block_state.rpass.buf[0]) - conf->reason = xstrdup(block_state.rpass.buf); - else - conf->reason = xstrdup(CONF_NOREASON); - add_conf_by_address(CONF_KLINE, conf); - } -}; - -kill_type: TYPE -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value = 0; -} '=' kill_type_items ';'; - -kill_type_items: kill_type_items ',' kill_type_item | kill_type_item; -kill_type_item: REGEX_T -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value = 1; + conf->reason = xstrdup(CONF_NOREASON); + add_conf_by_address(CONF_KLINE, conf); }; kill_items: kill_items kill_item | kill_item; -kill_item: kill_user | kill_reason | kill_type | error; +kill_item: kill_user | kill_reason | error; kill_user: USER '=' QSTRING ';' { @@ -2227,23 +2214,22 @@ kill_user: USER '=' QSTRING ';' } }; -kill_reason: REASON '=' QSTRING ';' +kill_reason: REASON '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) strlcpy(block_state.rpass.buf, yylval.string, sizeof(block_state.rpass.buf)); }; + /*************************************************************************** - * section deny + * deny {} section ***************************************************************************/ -deny_entry: DENY +deny_entry: DENY { if (conf_parser_ctx.pass == 2) reset_block_state(); } '{' deny_items '}' ';' { - struct MaskItem *conf = NULL; - if (conf_parser_ctx.pass != 2) break; @@ -2252,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]) @@ -2261,7 +2247,7 @@ deny_entry: DENY conf->reason = xstrdup(CONF_NOREASON); add_conf_by_address(CONF_DLINE, conf); } -}; +}; deny_items: deny_items deny_item | deny_item; deny_item: deny_ip | deny_reason | error; @@ -2272,25 +2258,26 @@ deny_ip: IP '=' QSTRING ';' strlcpy(block_state.addr.buf, yylval.string, sizeof(block_state.addr.buf)); }; -deny_reason: REASON '=' QSTRING ';' +deny_reason: REASON '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) 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); @@ -2301,7 +2288,7 @@ exempt_ip: IP '=' QSTRING ';' }; /*************************************************************************** - * section gecos + * gecos {} section ***************************************************************************/ gecos_entry: GECOS { @@ -2309,612 +2296,557 @@ 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; - if (block_state.port.value == 1) - { -#ifdef HAVE_LIBPCRE - void *exp_p = NULL; - const char *errptr = NULL; - - if (!(exp_p = ircd_pcre_compile(block_state.name.buf, &errptr))) - { - ilog(LOG_TYPE_IRCD, "Failed to add regular expression based X-Line: %s", - errptr); - break; - } - - conf = conf_make(CONF_RXLINE); - conf->regexuser = exp_p; -#else - conf_error_report("Failed to add regular expression based X-Line: no PCRE support"); - break; -#endif - } - else - 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_flags: TYPE -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value = 0; -} '=' gecos_flags_items ';'; - -gecos_flags_items: gecos_flags_items ',' gecos_flags_item | gecos_flags_item; -gecos_flags_item: REGEX_T -{ - if (conf_parser_ctx.pass == 2) - block_state.port.value = 1; + gecos->reason = xstrdup(CONF_NOREASON); }; gecos_items: gecos_items gecos_item | gecos_item; -gecos_item: gecos_name | gecos_reason | gecos_flags | error; +gecos_item: gecos_name | gecos_reason | error; -gecos_name: NAME '=' QSTRING ';' +gecos_name: NAME '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) strlcpy(block_state.name.buf, yylval.string, sizeof(block_state.name.buf)); }; -gecos_reason: REASON '=' QSTRING ';' +gecos_reason: REASON '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) 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_hide_spoof_ips | general_ignore_bogus_ts | - general_failed_oper_notice | general_anti_nick_flood | - general_max_nick_time | general_max_nick_changes | - general_max_accept | general_anti_spam_exit_message_time | - general_ts_warn_delta | general_ts_max_delta | +general_item: general_away_count | + general_away_time | + 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 | general_kill_chase_time_limit | general_invisible_on_connect | - general_warn_no_nline | general_dots_in_ident | - general_stats_o_oper_only | general_stats_k_oper_only | - general_pace_wait | general_stats_i_oper_only | - general_pace_wait_simple | general_stats_P_oper_only | - general_short_motd | general_no_oper_flood | - general_true_no_oper_flood | general_oper_pass_resv | - general_message_locale | - general_oper_only_umodes | general_max_targets | - general_use_egd | general_egdpool_path | - general_oper_umodes | general_caller_id_wait | - general_opers_bypass_callerid | general_default_floodcount | - general_min_nonwildcard | general_min_nonwildcard_simple | - general_disable_remote_commands | - general_throttle_time | general_havent_read_conf | + general_warn_no_connect_block | + general_dots_in_ident | + general_stats_i_oper_only | + general_stats_k_oper_only | + general_stats_m_oper_only | + general_stats_o_oper_only | + general_stats_P_oper_only | + general_stats_u_oper_only | + general_pace_wait | + general_pace_wait_simple | + general_short_motd | + general_no_oper_flood | + general_oper_only_umodes | + general_max_targets | + general_oper_umodes | + 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_gline_enable | - general_gline_duration | general_gline_request_duration | - general_gline_min_cidr | - general_gline_min_cidr6 | - general_stats_e_disabled | - general_max_watch | general_services_name | - error; - + general_disable_auth | + general_dline_min_cidr | + general_dline_min_cidr6 | + general_kline_min_cidr | + general_kline_min_cidr6 | + general_stats_e_disabled | + general_max_watch | + general_cycle_on_host_change | + error; -general_max_watch: MAX_WATCH '=' NUMBER ';' -{ - ConfigFileEntry.max_watch = $3; -}; -general_gline_enable: GLINE_ENABLE '=' TBOOL ';' +general_away_count: AWAY_COUNT '=' NUMBER ';' { - if (conf_parser_ctx.pass == 2) - ConfigFileEntry.glines = yylval.number; + ConfigGeneral.away_count = $3; }; -general_gline_duration: GLINE_DURATION '=' timespec ';' +general_away_time: AWAY_TIME '=' timespec ';' { - if (conf_parser_ctx.pass == 2) - ConfigFileEntry.gline_time = $3; + ConfigGeneral.away_time = $3; }; -general_gline_request_duration: GLINE_REQUEST_DURATION '=' timespec ';' +general_max_watch: MAX_WATCH '=' NUMBER ';' { - if (conf_parser_ctx.pass == 2) - ConfigFileEntry.gline_request_time = $3; + ConfigGeneral.max_watch = $3; }; -general_gline_min_cidr: GLINE_MIN_CIDR '=' NUMBER ';' +general_whowas_history_length: WHOWAS_HISTORY_LENGTH '=' NUMBER ';' { - ConfigFileEntry.gline_min_cidr = $3; + ConfigGeneral.whowas_history_length = $3; }; -general_gline_min_cidr6: GLINE_MIN_CIDR6 '=' NUMBER ';' +general_cycle_on_host_change: CYCLE_ON_HOST_CHANGE '=' TBOOL ';' { - ConfigFileEntry.gline_min_cidr6 = $3; + ConfigGeneral.cycle_on_host_change = yylval.number; }; -general_tkline_expire_notices: TKLINE_EXPIRE_NOTICES '=' TBOOL ';' +general_dline_min_cidr: DLINE_MIN_CIDR '=' NUMBER ';' { - ConfigFileEntry.tkline_expire_notices = yylval.number; + ConfigGeneral.dline_min_cidr = $3; }; -general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';' +general_dline_min_cidr6: DLINE_MIN_CIDR6 '=' NUMBER ';' { - ConfigFileEntry.kill_chase_time_limit = $3; + ConfigGeneral.dline_min_cidr6 = $3; }; -general_hide_spoof_ips: HIDE_SPOOF_IPS '=' TBOOL ';' +general_kline_min_cidr: KLINE_MIN_CIDR '=' NUMBER ';' { - ConfigFileEntry.hide_spoof_ips = yylval.number; + ConfigGeneral.kline_min_cidr = $3; }; -general_ignore_bogus_ts: IGNORE_BOGUS_TS '=' TBOOL ';' +general_kline_min_cidr6: KLINE_MIN_CIDR6 '=' NUMBER ';' { - ConfigFileEntry.ignore_bogus_ts = yylval.number; + ConfigGeneral.kline_min_cidr6 = $3; }; -general_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' +general_kill_chase_time_limit: KILL_CHASE_TIME_LIMIT '=' timespec ';' { - ConfigFileEntry.disable_remote = yylval.number; + ConfigGeneral.kill_chase_time_limit = $3; }; general_failed_oper_notice: FAILED_OPER_NOTICE '=' TBOOL ';' { - ConfigFileEntry.failed_oper_notice = yylval.number; + ConfigGeneral.failed_oper_notice = yylval.number; }; general_anti_nick_flood: ANTI_NICK_FLOOD '=' TBOOL ';' { - ConfigFileEntry.anti_nick_flood = yylval.number; + ConfigGeneral.anti_nick_flood = yylval.number; }; general_max_nick_time: MAX_NICK_TIME '=' timespec ';' { - ConfigFileEntry.max_nick_time = $3; + ConfigGeneral.max_nick_time = $3; }; general_max_nick_changes: MAX_NICK_CHANGES '=' NUMBER ';' { - ConfigFileEntry.max_nick_changes = $3; + ConfigGeneral.max_nick_changes = $3; }; general_max_accept: MAX_ACCEPT '=' NUMBER ';' { - ConfigFileEntry.max_accept = $3; + ConfigGeneral.max_accept = $3; }; general_anti_spam_exit_message_time: ANTI_SPAM_EXIT_MESSAGE_TIME '=' timespec ';' { - ConfigFileEntry.anti_spam_exit_message_time = $3; + ConfigGeneral.anti_spam_exit_message_time = $3; }; general_ts_warn_delta: TS_WARN_DELTA '=' timespec ';' { - ConfigFileEntry.ts_warn_delta = $3; + ConfigGeneral.ts_warn_delta = $3; }; general_ts_max_delta: TS_MAX_DELTA '=' timespec ';' { - if (conf_parser_ctx.pass == 2) - ConfigFileEntry.ts_max_delta = $3; + ConfigGeneral.ts_max_delta = $3; }; -general_havent_read_conf: HAVENT_READ_CONF '=' NUMBER ';' +general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' { - if (($3 > 0) && conf_parser_ctx.pass == 1) - { - ilog(LOG_TYPE_IRCD, "You haven't read your config file properly."); - ilog(LOG_TYPE_IRCD, "There is a line in the example conf that will kill your server if not removed."); - ilog(LOG_TYPE_IRCD, "Consider actually reading/editing the conf file, and removing this line."); - exit(0); - } + ConfigGeneral.invisible_on_connect = yylval.number; }; -general_invisible_on_connect: INVISIBLE_ON_CONNECT '=' TBOOL ';' +general_warn_no_connect_block: WARN_NO_CONNECT_BLOCK '=' TBOOL ';' { - ConfigFileEntry.invisible_on_connect = yylval.number; + ConfigGeneral.warn_no_connect_block = yylval.number; }; -general_warn_no_nline: WARN_NO_NLINE '=' TBOOL ';' +general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';' { - ConfigFileEntry.warn_no_nline = yylval.number; + ConfigGeneral.stats_e_disabled = yylval.number; }; -general_stats_e_disabled: STATS_E_DISABLED '=' TBOOL ';' +general_stats_m_oper_only: STATS_M_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_e_disabled = yylval.number; + ConfigGeneral.stats_m_oper_only = yylval.number; }; general_stats_o_oper_only: STATS_O_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_o_oper_only = yylval.number; + ConfigGeneral.stats_o_oper_only = yylval.number; }; general_stats_P_oper_only: STATS_P_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_P_oper_only = yylval.number; + ConfigGeneral.stats_P_oper_only = yylval.number; }; -general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';' +general_stats_u_oper_only: STATS_U_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_k_oper_only = 2 * yylval.number; -} | STATS_K_OPER_ONLY '=' TMASKED ';' + ConfigGeneral.stats_u_oper_only = yylval.number; +}; + +general_stats_k_oper_only: STATS_K_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_k_oper_only = 1; + ConfigGeneral.stats_k_oper_only = yylval.number; }; general_stats_i_oper_only: STATS_I_OPER_ONLY '=' TBOOL ';' { - ConfigFileEntry.stats_i_oper_only = 2 * yylval.number; -} | STATS_I_OPER_ONLY '=' TMASKED ';' -{ - ConfigFileEntry.stats_i_oper_only = 1; + ConfigGeneral.stats_i_oper_only = yylval.number; }; general_pace_wait: PACE_WAIT '=' timespec ';' { - ConfigFileEntry.pace_wait = $3; + ConfigGeneral.pace_wait = $3; }; general_caller_id_wait: CALLER_ID_WAIT '=' timespec ';' { - ConfigFileEntry.caller_id_wait = $3; + ConfigGeneral.caller_id_wait = $3; }; general_opers_bypass_callerid: OPERS_BYPASS_CALLERID '=' TBOOL ';' { - ConfigFileEntry.opers_bypass_callerid = yylval.number; + ConfigGeneral.opers_bypass_callerid = yylval.number; }; general_pace_wait_simple: PACE_WAIT_SIMPLE '=' timespec ';' { - ConfigFileEntry.pace_wait_simple = $3; + ConfigGeneral.pace_wait_simple = $3; }; general_short_motd: SHORT_MOTD '=' TBOOL ';' { - ConfigFileEntry.short_motd = yylval.number; -}; - -general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';' -{ - ConfigFileEntry.no_oper_flood = yylval.number; + ConfigGeneral.short_motd = yylval.number; }; -general_true_no_oper_flood: TRUE_NO_OPER_FLOOD '=' TBOOL ';' -{ - ConfigFileEntry.true_no_oper_flood = yylval.number; -}; - -general_oper_pass_resv: OPER_PASS_RESV '=' TBOOL ';' -{ - ConfigFileEntry.oper_pass_resv = yylval.number; -}; - -general_message_locale: MESSAGE_LOCALE '=' QSTRING ';' +general_no_oper_flood: NO_OPER_FLOOD '=' TBOOL ';' { - if (conf_parser_ctx.pass == 2) - { - if (strlen(yylval.string) > LOCALE_LENGTH-2) - yylval.string[LOCALE_LENGTH-1] = '\0'; - - set_locale(yylval.string); - } + ConfigGeneral.no_oper_flood = yylval.number; }; general_dots_in_ident: DOTS_IN_IDENT '=' NUMBER ';' { - ConfigFileEntry.dots_in_ident = $3; + ConfigGeneral.dots_in_ident = $3; }; general_max_targets: MAX_TARGETS '=' NUMBER ';' { - ConfigFileEntry.max_targets = $3; + ConfigGeneral.max_targets = $3; }; -general_use_egd: USE_EGD '=' TBOOL ';' -{ - ConfigFileEntry.use_egd = yylval.number; -}; - -general_egdpool_path: EGDPOOL_PATH '=' QSTRING ';' -{ - if (conf_parser_ctx.pass == 2) - { - MyFree(ConfigFileEntry.egdpool_path); - ConfigFileEntry.egdpool_path = xstrdup(yylval.string); - } -}; - -general_services_name: T_SERVICES_NAME '=' QSTRING ';' +general_ping_cookie: PING_COOKIE '=' TBOOL ';' { - if (conf_parser_ctx.pass == 2 && valid_servname(yylval.string)) - { - MyFree(ConfigFileEntry.service_name); - ConfigFileEntry.service_name = xstrdup(yylval.string); - } + ConfigGeneral.ping_cookie = yylval.number; }; -general_ping_cookie: PING_COOKIE '=' TBOOL ';' +general_disable_auth: DISABLE_AUTH '=' TBOOL ';' { - ConfigFileEntry.ping_cookie = yylval.number; + ConfigGeneral.disable_auth = yylval.number; }; -general_disable_auth: DISABLE_AUTH '=' TBOOL ';' +general_throttle_count: THROTTLE_COUNT '=' NUMBER ';' { - ConfigFileEntry.disable_auth = yylval.number; + ConfigGeneral.throttle_count = $3; }; general_throttle_time: THROTTLE_TIME '=' timespec ';' { - ConfigFileEntry.throttle_time = yylval.number; + ConfigGeneral.throttle_time = $3; }; general_oper_umodes: OPER_UMODES { - ConfigFileEntry.oper_umodes = 0; -} '=' umode_oitems ';' ; + ConfigGeneral.oper_umodes = 0; +} '=' umode_oitems ';' ; umode_oitems: umode_oitems ',' umode_oitem | umode_oitem; -umode_oitem: T_BOTS -{ - ConfigFileEntry.oper_umodes |= UMODE_BOTS; -} | T_CCONN -{ - ConfigFileEntry.oper_umodes |= UMODE_CCONN; -} | T_CCONN_FULL +umode_oitem: T_CCONN { - ConfigFileEntry.oper_umodes |= UMODE_CCONN_FULL; + ConfigGeneral.oper_umodes |= UMODE_CCONN; } | T_DEAF { - ConfigFileEntry.oper_umodes |= UMODE_DEAF; + ConfigGeneral.oper_umodes |= UMODE_DEAF; } | T_DEBUG { - ConfigFileEntry.oper_umodes |= UMODE_DEBUG; -} | T_FULL + ConfigGeneral.oper_umodes |= UMODE_DEBUG; +} | T_FLOOD { - ConfigFileEntry.oper_umodes |= UMODE_FULL; + ConfigGeneral.oper_umodes |= UMODE_FLOOD; } | HIDDEN { - ConfigFileEntry.oper_umodes |= UMODE_HIDDEN; + ConfigGeneral.oper_umodes |= UMODE_HIDDEN; +} | HIDE_CHANS +{ + ConfigGeneral.oper_umodes |= UMODE_HIDECHANS; +} | HIDE_IDLE +{ + ConfigGeneral.oper_umodes |= UMODE_HIDEIDLE; } | T_SKILL { - ConfigFileEntry.oper_umodes |= UMODE_SKILL; + ConfigGeneral.oper_umodes |= UMODE_SKILL; } | T_NCHANGE { - ConfigFileEntry.oper_umodes |= UMODE_NCHANGE; + ConfigGeneral.oper_umodes |= UMODE_NCHANGE; } | T_REJ { - ConfigFileEntry.oper_umodes |= UMODE_REJ; -} | T_UNAUTH -{ - ConfigFileEntry.oper_umodes |= UMODE_UNAUTH; + ConfigGeneral.oper_umodes |= UMODE_REJ; } | T_SPY { - ConfigFileEntry.oper_umodes |= UMODE_SPY; + ConfigGeneral.oper_umodes |= UMODE_SPY; } | T_EXTERNAL { - ConfigFileEntry.oper_umodes |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - ConfigFileEntry.oper_umodes |= UMODE_OPERWALL; + ConfigGeneral.oper_umodes |= UMODE_EXTERNAL; } | T_SERVNOTICE { - ConfigFileEntry.oper_umodes |= UMODE_SERVNOTICE; + ConfigGeneral.oper_umodes |= UMODE_SERVNOTICE; } | T_INVISIBLE { - ConfigFileEntry.oper_umodes |= UMODE_INVISIBLE; + ConfigGeneral.oper_umodes |= UMODE_INVISIBLE; } | T_WALLOP { - ConfigFileEntry.oper_umodes |= UMODE_WALLOP; + ConfigGeneral.oper_umodes |= UMODE_WALLOP; } | T_SOFTCALLERID { - ConfigFileEntry.oper_umodes |= UMODE_SOFTCALLERID; + ConfigGeneral.oper_umodes |= UMODE_SOFTCALLERID; } | T_CALLERID { - ConfigFileEntry.oper_umodes |= UMODE_CALLERID; + ConfigGeneral.oper_umodes |= UMODE_CALLERID; } | T_LOCOPS { - ConfigFileEntry.oper_umodes |= UMODE_LOCOPS; + ConfigGeneral.oper_umodes |= UMODE_LOCOPS; +} | T_NONONREG +{ + ConfigGeneral.oper_umodes |= UMODE_REGONLY; +} | T_FARCONNECT +{ + ConfigGeneral.oper_umodes |= UMODE_FARCONNECT; +} | EXPIRATION +{ + ConfigGeneral.oper_umodes |= UMODE_EXPIRATION; }; -general_oper_only_umodes: OPER_ONLY_UMODES +general_oper_only_umodes: OPER_ONLY_UMODES { - ConfigFileEntry.oper_only_umodes = 0; -} '=' umode_items ';' ; + ConfigGeneral.oper_only_umodes = 0; +} '=' umode_items ';' ; -umode_items: umode_items ',' umode_item | umode_item; -umode_item: T_BOTS -{ - ConfigFileEntry.oper_only_umodes |= UMODE_BOTS; -} | T_CCONN +umode_items: umode_items ',' umode_item | umode_item; +umode_item: T_CCONN { - ConfigFileEntry.oper_only_umodes |= UMODE_CCONN; -} | T_CCONN_FULL -{ - ConfigFileEntry.oper_only_umodes |= UMODE_CCONN_FULL; + ConfigGeneral.oper_only_umodes |= UMODE_CCONN; } | T_DEAF { - ConfigFileEntry.oper_only_umodes |= UMODE_DEAF; + ConfigGeneral.oper_only_umodes |= UMODE_DEAF; } | T_DEBUG { - ConfigFileEntry.oper_only_umodes |= UMODE_DEBUG; -} | T_FULL -{ - ConfigFileEntry.oper_only_umodes |= UMODE_FULL; + ConfigGeneral.oper_only_umodes |= UMODE_DEBUG; +} | T_FLOOD +{ + ConfigGeneral.oper_only_umodes |= UMODE_FLOOD; } | T_SKILL { - ConfigFileEntry.oper_only_umodes |= UMODE_SKILL; + ConfigGeneral.oper_only_umodes |= UMODE_SKILL; } | HIDDEN { - ConfigFileEntry.oper_only_umodes |= UMODE_HIDDEN; + ConfigGeneral.oper_only_umodes |= UMODE_HIDDEN; } | T_NCHANGE { - ConfigFileEntry.oper_only_umodes |= UMODE_NCHANGE; + ConfigGeneral.oper_only_umodes |= UMODE_NCHANGE; } | T_REJ { - ConfigFileEntry.oper_only_umodes |= UMODE_REJ; -} | T_UNAUTH -{ - ConfigFileEntry.oper_only_umodes |= UMODE_UNAUTH; + ConfigGeneral.oper_only_umodes |= UMODE_REJ; } | T_SPY { - ConfigFileEntry.oper_only_umodes |= UMODE_SPY; + ConfigGeneral.oper_only_umodes |= UMODE_SPY; } | T_EXTERNAL { - ConfigFileEntry.oper_only_umodes |= UMODE_EXTERNAL; -} | T_OPERWALL -{ - ConfigFileEntry.oper_only_umodes |= UMODE_OPERWALL; + ConfigGeneral.oper_only_umodes |= UMODE_EXTERNAL; } | T_SERVNOTICE { - ConfigFileEntry.oper_only_umodes |= UMODE_SERVNOTICE; + ConfigGeneral.oper_only_umodes |= UMODE_SERVNOTICE; } | T_INVISIBLE { - ConfigFileEntry.oper_only_umodes |= UMODE_INVISIBLE; + ConfigGeneral.oper_only_umodes |= UMODE_INVISIBLE; } | T_WALLOP { - ConfigFileEntry.oper_only_umodes |= UMODE_WALLOP; + ConfigGeneral.oper_only_umodes |= UMODE_WALLOP; } | T_SOFTCALLERID { - ConfigFileEntry.oper_only_umodes |= UMODE_SOFTCALLERID; + ConfigGeneral.oper_only_umodes |= UMODE_SOFTCALLERID; } | T_CALLERID { - ConfigFileEntry.oper_only_umodes |= UMODE_CALLERID; + ConfigGeneral.oper_only_umodes |= UMODE_CALLERID; } | T_LOCOPS { - ConfigFileEntry.oper_only_umodes |= UMODE_LOCOPS; + ConfigGeneral.oper_only_umodes |= UMODE_LOCOPS; +} | T_NONONREG +{ + ConfigGeneral.oper_only_umodes |= UMODE_REGONLY; +} | T_FARCONNECT +{ + ConfigGeneral.oper_only_umodes |= UMODE_FARCONNECT; +} | EXPIRATION +{ + ConfigGeneral.oper_only_umodes |= UMODE_EXPIRATION; }; general_min_nonwildcard: MIN_NONWILDCARD '=' NUMBER ';' { - ConfigFileEntry.min_nonwildcard = $3; + ConfigGeneral.min_nonwildcard = $3; }; general_min_nonwildcard_simple: MIN_NONWILDCARD_SIMPLE '=' NUMBER ';' { - ConfigFileEntry.min_nonwildcard_simple = $3; + ConfigGeneral.min_nonwildcard_simple = $3; }; general_default_floodcount: DEFAULT_FLOODCOUNT '=' NUMBER ';' { - ConfigFileEntry.default_floodcount = $3; + 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_knock_delay | channel_knock_delay_channel | - channel_max_chans_per_user | channel_max_chans_per_oper | - channel_quiet_on_ban | channel_default_split_user_count | - channel_default_split_server_count | - channel_no_create_on_split | channel_restrict_channels | - channel_no_join_on_split | - channel_jflood_count | channel_jflood_time | - channel_disable_fake_channels | error; + 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; }; -channel_restrict_channels: RESTRICT_CHANNELS '=' TBOOL ';' +channel_invite_client_count: INVITE_CLIENT_COUNT '=' NUMBER ';' { - ConfigChannel.restrict_channels = yylval.number; + ConfigChannel.invite_client_count = $3; }; -channel_knock_delay: KNOCK_DELAY '=' timespec ';' +channel_invite_client_time: INVITE_CLIENT_TIME '=' timespec ';' { - ConfigChannel.knock_delay = $3; + ConfigChannel.invite_client_time = $3; }; -channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';' +channel_invite_delay_channel: INVITE_DELAY_CHANNEL '=' timespec ';' { - ConfigChannel.knock_delay_channel = $3; + ConfigChannel.invite_delay_channel = $3; }; -channel_max_chans_per_user: MAX_CHANS_PER_USER '=' NUMBER ';' +channel_invite_expire_time: INVITE_EXPIRE_TIME '=' timespec ';' { - ConfigChannel.max_chans_per_user = $3; + ConfigChannel.invite_expire_time = $3; }; -channel_max_chans_per_oper: MAX_CHANS_PER_OPER '=' NUMBER ';' +channel_knock_client_count: KNOCK_CLIENT_COUNT '=' NUMBER ';' { - ConfigChannel.max_chans_per_oper = $3; + ConfigChannel.knock_client_count = $3; }; -channel_quiet_on_ban: QUIET_ON_BAN '=' TBOOL ';' +channel_knock_client_time: KNOCK_CLIENT_TIME '=' timespec ';' { - ConfigChannel.quiet_on_ban = yylval.number; + ConfigChannel.knock_client_time = $3; }; -channel_max_bans: MAX_BANS '=' NUMBER ';' +channel_knock_delay_channel: KNOCK_DELAY_CHANNEL '=' timespec ';' { - ConfigChannel.max_bans = $3; + ConfigChannel.knock_delay_channel = $3; }; -channel_default_split_user_count: DEFAULT_SPLIT_USER_COUNT '=' NUMBER ';' +channel_max_channels: MAX_CHANNELS '=' NUMBER ';' { - ConfigChannel.default_split_user_count = $3; + ConfigChannel.max_channels = $3; }; -channel_default_split_server_count: DEFAULT_SPLIT_SERVER_COUNT '=' NUMBER ';' +channel_max_invites: MAX_INVITES '=' NUMBER ';' { - ConfigChannel.default_split_server_count = $3; + ConfigChannel.max_invites = $3; }; -channel_no_create_on_split: NO_CREATE_ON_SPLIT '=' TBOOL ';' +channel_max_bans: MAX_BANS '=' NUMBER ';' { - ConfigChannel.no_create_on_split = yylval.number; + ConfigChannel.max_bans = $3; }; -channel_no_join_on_split: NO_JOIN_ON_SPLIT '=' TBOOL ';' +channel_max_bans_large: MAX_BANS_LARGE '=' NUMBER ';' { - ConfigChannel.no_join_on_split = yylval.number; + ConfigChannel.max_bans_large = $3; }; -channel_jflood_count: JOIN_FLOOD_COUNT '=' NUMBER ';' +channel_default_join_flood_count: DEFAULT_JOIN_FLOOD_COUNT '=' NUMBER ';' { - GlobalSetOptions.joinfloodcount = yylval.number; + ConfigChannel.default_join_flood_count = yylval.number; }; -channel_jflood_time: JOIN_FLOOD_TIME '=' timespec ';' +channel_default_join_flood_time: DEFAULT_JOIN_FLOOD_TIME '=' timespec ';' { - GlobalSetOptions.joinfloodtime = yylval.number; + 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 | serverhide_hide_servers | - serverhide_links_delay | - serverhide_hidden | serverhide_hidden_name | - serverhide_hide_server_ips | +serverhide_item: serverhide_flatten_links | + serverhide_flatten_links_delay | + serverhide_flatten_links_file | + serverhide_disable_remote_commands | + serverhide_hide_servers | + serverhide_hide_services | + serverhide_hidden | + serverhide_hidden_name | + serverhide_hide_server_ips | error; serverhide_flatten_links: FLATTEN_LINKS '=' TBOOL ';' @@ -2923,32 +2855,55 @@ serverhide_flatten_links: FLATTEN_LINKS ConfigServerHide.flatten_links = yylval.number; }; -serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' +serverhide_flatten_links_delay: FLATTEN_LINKS_DELAY '=' timespec ';' { if (conf_parser_ctx.pass == 2) - ConfigServerHide.hide_servers = 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_hidden_name: HIDDEN_NAME '=' QSTRING ';' +serverhide_flatten_links_file: FLATTEN_LINKS_FILE '=' QSTRING ';' { if (conf_parser_ctx.pass == 2) { - MyFree(ConfigServerHide.hidden_name); - ConfigServerHide.hidden_name = xstrdup(yylval.string); + xfree(ConfigServerHide.flatten_links_file); + ConfigServerHide.flatten_links_file = xstrdup(yylval.string); } }; -serverhide_links_delay: LINKS_DELAY '=' timespec ';' +serverhide_disable_remote_commands: DISABLE_REMOTE_COMMANDS '=' TBOOL ';' { if (conf_parser_ctx.pass == 2) - { - if (($3 > 0) && ConfigServerHide.links_disabled == 1) - { - eventAddIsh("write_links_file", write_links_file, NULL, $3); - ConfigServerHide.links_disabled = 0; - } + ConfigServerHide.disable_remote_commands = yylval.number; +}; - ConfigServerHide.links_delay = $3; +serverhide_hide_servers: HIDE_SERVERS '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_servers = yylval.number; +}; + +serverhide_hide_services: HIDE_SERVICES '=' TBOOL ';' +{ + if (conf_parser_ctx.pass == 2) + ConfigServerHide.hide_services = yylval.number; +}; + +serverhide_hidden_name: HIDDEN_NAME '=' QSTRING ';' +{ + if (conf_parser_ctx.pass == 2) + { + xfree(ConfigServerHide.hidden_name); + ConfigServerHide.hidden_name = xstrdup(yylval.string); } };