| 56 |
|
#include "motd.h" |
| 57 |
|
|
| 58 |
|
|
| 59 |
– |
struct config_channel_entry ConfigChannel; |
| 60 |
– |
struct config_server_hide ConfigServerHide; |
| 61 |
– |
struct config_file_entry ConfigFileEntry; |
| 62 |
– |
struct logging_entry ConfigLoggingEntry = { .use_logging = 1 }; |
| 63 |
– |
struct server_info ServerInfo; |
| 64 |
– |
struct admin_info AdminInfo; |
| 65 |
– |
|
| 59 |
|
/* general conf items link list root, other than k lines etc. */ |
| 60 |
|
dlink_list service_items = { NULL, NULL, 0 }; |
| 61 |
|
dlink_list server_items = { NULL, NULL, 0 }; |
| 64 |
|
dlink_list uconf_items = { NULL, NULL, 0 }; |
| 65 |
|
dlink_list xconf_items = { NULL, NULL, 0 }; |
| 66 |
|
dlink_list nresv_items = { NULL, NULL, 0 }; |
| 67 |
< |
dlink_list cresv_items = { NULL, NULL, 0 }; |
| 67 |
> |
dlink_list cresv_items = { NULL, NULL, 0 }; |
| 68 |
|
|
| 69 |
|
extern unsigned int lineno; |
| 70 |
|
extern char linebuf[]; |
| 71 |
|
extern char conffilebuf[IRCD_BUFSIZE]; |
| 72 |
|
extern int yyparse(); /* defined in y.tab.c */ |
| 73 |
|
|
| 81 |
– |
struct conf_parser_context conf_parser_ctx = { 0, 0, NULL }; |
| 82 |
– |
|
| 74 |
|
/* internally defined functions */ |
| 75 |
|
static void read_conf(FILE *); |
| 76 |
|
static void clear_out_old_conf(void); |
| 93 |
|
struct ip_entry |
| 94 |
|
{ |
| 95 |
|
struct irc_ssaddr ip; |
| 96 |
< |
unsigned int count; |
| 97 |
< |
time_t last_attempt; |
| 96 |
> |
unsigned int count; /**< Number of registered users using this IP */ |
| 97 |
> |
unsigned int connection_count; /**< Number of connections from this IP in the last throttle_time duration */ |
| 98 |
> |
time_t last_attempt; /**< The last time someone connected from this IP */ |
| 99 |
|
struct ip_entry *next; |
| 100 |
|
}; |
| 101 |
|
|
| 146 |
|
struct MaskItem * |
| 147 |
|
conf_make(enum maskitem_type type) |
| 148 |
|
{ |
| 149 |
< |
struct MaskItem *conf = MyMalloc(sizeof(*conf)); |
| 149 |
> |
struct MaskItem *conf = MyCalloc(sizeof(*conf)); |
| 150 |
|
dlink_list *list = NULL; |
| 151 |
|
|
| 152 |
|
conf->type = type; |
| 395 |
|
* setting a_limit_reached if any limit is reached. |
| 396 |
|
* - Dianora |
| 397 |
|
*/ |
| 398 |
< |
if (class->max_total != 0 && class->ref_count >= class->max_total) |
| 398 |
> |
if (class->max_total && class->ref_count >= class->max_total) |
| 399 |
|
a_limit_reached = 1; |
| 400 |
< |
else if (class->max_perip != 0 && ip_found->count > class->max_perip) |
| 400 |
> |
else if (class->max_perip && ip_found->count > class->max_perip) |
| 401 |
|
a_limit_reached = 1; |
| 402 |
< |
else if (class->max_local != 0 && local >= class->max_local) |
| 402 |
> |
else if (class->max_local && local >= class->max_local) |
| 403 |
|
a_limit_reached = 1; |
| 404 |
< |
else if (class->max_global != 0 && global >= class->max_global) |
| 404 |
> |
else if (class->max_global && global >= class->max_global) |
| 405 |
|
a_limit_reached = 1; |
| 406 |
< |
else if (class->max_ident != 0 && ident >= class->max_ident && |
| 406 |
> |
else if (class->max_ident && ident >= class->max_ident && |
| 407 |
|
client_p->username[0] != '~') |
| 408 |
|
a_limit_reached = 1; |
| 409 |
|
|
| 479 |
|
garbage_collect_ip_entries(); |
| 480 |
|
|
| 481 |
|
newptr = mp_pool_get(ip_entry_pool); |
| 482 |
< |
memset(newptr, 0, sizeof(*newptr)); |
| 482 |
> |
|
| 483 |
|
ip_entries_count++; |
| 484 |
|
memcpy(&newptr->ip, ip_in, sizeof(struct irc_ssaddr)); |
| 485 |
|
|
| 596 |
|
count_ip_hash(unsigned int *number_ips_stored, uint64_t *mem_ips_stored) |
| 597 |
|
{ |
| 598 |
|
struct ip_entry *ptr; |
| 607 |
– |
int i; |
| 599 |
|
|
| 600 |
|
*number_ips_stored = 0; |
| 601 |
|
*mem_ips_stored = 0; |
| 602 |
|
|
| 603 |
< |
for (i = 0; i < IP_HASH_SIZE; i++) |
| 603 |
> |
for (unsigned int i = 0; i < IP_HASH_SIZE; ++i) |
| 604 |
|
{ |
| 605 |
|
for (ptr = ip_hash_table[i]; ptr; ptr = ptr->next) |
| 606 |
|
{ |
| 622 |
|
struct ip_entry *ptr; |
| 623 |
|
struct ip_entry *last_ptr; |
| 624 |
|
struct ip_entry *next_ptr; |
| 634 |
– |
int i; |
| 625 |
|
|
| 626 |
< |
for (i = 0; i < IP_HASH_SIZE; i++) |
| 626 |
> |
for (unsigned int i = 0; i < IP_HASH_SIZE; ++i) |
| 627 |
|
{ |
| 628 |
|
last_ptr = NULL; |
| 629 |
|
|
| 773 |
|
|
| 774 |
|
if (conf->type == type) |
| 775 |
|
{ |
| 776 |
< |
if (conf->name && (irccmp(conf->name, name) == 0 || |
| 776 |
> |
if (conf->name && (!irccmp(conf->name, name) || |
| 777 |
|
!match(conf->name, name))) |
| 778 |
|
return conf; |
| 779 |
|
} |
| 1038 |
|
strlcpy(me.info, ServerInfo.description, sizeof(me.info)); |
| 1039 |
|
|
| 1040 |
|
load_conf_modules(); |
| 1041 |
< |
|
| 1052 |
< |
rehashed_klines = 1; |
| 1041 |
> |
check_conf_klines(); |
| 1042 |
|
|
| 1043 |
|
return 0; |
| 1044 |
|
} |
| 1061 |
|
assert(class_default == class_get_list()->tail->data); |
| 1062 |
|
|
| 1063 |
|
#ifdef HAVE_LIBCRYPTO |
| 1064 |
+ |
ServerInfo.message_digest_algorithm = EVP_sha256(); |
| 1065 |
|
ServerInfo.rsa_private_key = NULL; |
| 1066 |
|
ServerInfo.rsa_private_key_file = NULL; |
| 1067 |
|
#endif |
| 1093 |
|
ConfigLoggingEntry.use_logging = 1; |
| 1094 |
|
|
| 1095 |
|
ConfigChannel.disable_fake_channels = 0; |
| 1096 |
< |
ConfigChannel.knock_delay = 300; |
| 1096 |
> |
ConfigChannel.invite_client_count = 10; |
| 1097 |
> |
ConfigChannel.invite_client_time = 300; |
| 1098 |
> |
ConfigChannel.knock_client_count = 1; |
| 1099 |
> |
ConfigChannel.knock_client_time = 300; |
| 1100 |
|
ConfigChannel.knock_delay_channel = 60; |
| 1101 |
< |
ConfigChannel.max_chans_per_user = 25; |
| 1109 |
< |
ConfigChannel.max_chans_per_oper = 50; |
| 1101 |
> |
ConfigChannel.max_channels = 25; |
| 1102 |
|
ConfigChannel.max_bans = 25; |
| 1103 |
|
ConfigChannel.default_split_user_count = 0; |
| 1104 |
|
ConfigChannel.default_split_server_count = 0; |
| 1140 |
|
ConfigFileEntry.anti_spam_exit_message_time = 0; |
| 1141 |
|
ConfigFileEntry.ts_warn_delta = TS_WARN_DELTA_DEFAULT; |
| 1142 |
|
ConfigFileEntry.ts_max_delta = TS_MAX_DELTA_DEFAULT; |
| 1143 |
< |
ConfigFileEntry.warn_no_nline = 1; |
| 1143 |
> |
ConfigFileEntry.warn_no_connect_block = 1; |
| 1144 |
> |
ConfigFileEntry.stats_e_disabled = 0; |
| 1145 |
|
ConfigFileEntry.stats_o_oper_only = 0; |
| 1146 |
< |
ConfigFileEntry.stats_k_oper_only = 1; /* masked */ |
| 1147 |
< |
ConfigFileEntry.stats_i_oper_only = 1; /* masked */ |
| 1146 |
> |
ConfigFileEntry.stats_k_oper_only = 1; /* 1 = masked */ |
| 1147 |
> |
ConfigFileEntry.stats_i_oper_only = 1; /* 1 = masked */ |
| 1148 |
|
ConfigFileEntry.stats_P_oper_only = 0; |
| 1149 |
|
ConfigFileEntry.stats_u_oper_only = 0; |
| 1150 |
|
ConfigFileEntry.caller_id_wait = 60; |
| 1158 |
|
ConfigFileEntry.oper_pass_resv = 1; |
| 1159 |
|
ConfigFileEntry.max_targets = MAX_TARGETS_DEFAULT; |
| 1160 |
|
ConfigFileEntry.oper_only_umodes = UMODE_DEBUG; |
| 1161 |
< |
ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | |
| 1162 |
< |
UMODE_OPERWALL | UMODE_WALLOP; |
| 1163 |
< |
ConfigFileEntry.use_egd = 0; |
| 1171 |
< |
ConfigFileEntry.egdpool_path = NULL; |
| 1172 |
< |
ConfigFileEntry.throttle_time = 10; |
| 1161 |
> |
ConfigFileEntry.oper_umodes = UMODE_BOTS | UMODE_LOCOPS | UMODE_SERVNOTICE | UMODE_WALLOP; |
| 1162 |
> |
ConfigFileEntry.throttle_count = 1; |
| 1163 |
> |
ConfigFileEntry.throttle_time = 1; |
| 1164 |
|
} |
| 1165 |
|
|
| 1166 |
|
static void |
| 1195 |
|
{ |
| 1196 |
|
lineno = 0; |
| 1197 |
|
|
| 1198 |
< |
set_default_conf(); /* Set default values prior to conf parsing */ |
| 1198 |
> |
set_default_conf(); /* Set default values prior to conf parsing */ |
| 1199 |
|
conf_parser_ctx.pass = 1; |
| 1200 |
< |
yyparse(); /* pick up the classes first */ |
| 1200 |
> |
yyparse(); /* Pick up the classes first */ |
| 1201 |
|
|
| 1202 |
|
rewind(file); |
| 1203 |
|
|
| 1204 |
|
conf_parser_ctx.pass = 2; |
| 1205 |
< |
yyparse(); /* Load the values from the conf */ |
| 1206 |
< |
validate_conf(); /* Check to make sure some values are still okay. */ |
| 1207 |
< |
/* Some global values are also loaded here. */ |
| 1208 |
< |
class_delete_marked(); /* Make sure classes are valid */ |
| 1205 |
> |
yyparse(); /* Load the values from the conf */ |
| 1206 |
> |
validate_conf(); /* Check to make sure some values are still okay. */ |
| 1207 |
> |
/* Some global values are also loaded here. */ |
| 1208 |
> |
class_delete_marked(); /* Delete unused classes that are marked for deletion */ |
| 1209 |
|
} |
| 1210 |
|
|
| 1211 |
|
/* lookup_confhost() |
| 1218 |
|
{ |
| 1219 |
|
struct addrinfo hints, *res; |
| 1220 |
|
|
| 1221 |
< |
/* Do name lookup now on hostnames given and store the |
| 1221 |
> |
/* |
| 1222 |
> |
* Do name lookup now on hostnames given and store the |
| 1223 |
|
* ip numbers in conf structure. |
| 1224 |
|
*/ |
| 1225 |
|
memset(&hints, 0, sizeof(hints)); |
| 1255 |
|
int |
| 1256 |
|
conf_connect_allowed(struct irc_ssaddr *addr, int aftype) |
| 1257 |
|
{ |
| 1258 |
< |
struct ip_entry *ip_found; |
| 1258 |
> |
struct ip_entry *ip_found = NULL; |
| 1259 |
|
struct MaskItem *conf = find_dline_conf(addr, aftype); |
| 1260 |
|
|
| 1261 |
|
/* DLINE exempt also gets you out of static limits/pacing... */ |
| 1267 |
|
|
| 1268 |
|
ip_found = find_or_add_ip(addr); |
| 1269 |
|
|
| 1270 |
< |
if ((CurrentTime - ip_found->last_attempt) < |
| 1279 |
< |
ConfigFileEntry.throttle_time) |
| 1270 |
> |
if ((CurrentTime - ip_found->last_attempt) < ConfigFileEntry.throttle_time) |
| 1271 |
|
{ |
| 1272 |
< |
ip_found->last_attempt = CurrentTime; |
| 1273 |
< |
return TOO_FAST; |
| 1272 |
> |
if (ip_found->connection_count >= ConfigFileEntry.throttle_count) |
| 1273 |
> |
return TOO_FAST; |
| 1274 |
> |
|
| 1275 |
> |
++ip_found->connection_count; |
| 1276 |
|
} |
| 1277 |
+ |
else |
| 1278 |
+ |
ip_found->connection_count = 1; |
| 1279 |
|
|
| 1280 |
|
ip_found->last_attempt = CurrentTime; |
| 1281 |
|
return 0; |
| 1349 |
|
{ OPER_FLAG_DIE, 'D' }, |
| 1350 |
|
{ OPER_FLAG_GLINE, 'G' }, |
| 1351 |
|
{ OPER_FLAG_REHASH, 'H' }, |
| 1352 |
< |
{ OPER_FLAG_K, 'K' }, |
| 1358 |
< |
{ OPER_FLAG_OPERWALL, 'L' }, |
| 1352 |
> |
{ OPER_FLAG_KLINE, 'K' }, |
| 1353 |
|
{ OPER_FLAG_KILL, 'N' }, |
| 1354 |
|
{ OPER_FLAG_KILL_REMOTE, 'O' }, |
| 1355 |
|
{ OPER_FLAG_CONNECT, 'P' }, |
| 1427 |
|
void |
| 1428 |
|
read_conf_files(int cold) |
| 1429 |
|
{ |
| 1430 |
< |
const char *filename; |
| 1431 |
< |
char chanmodes[IRCD_BUFSIZE]; |
| 1432 |
< |
char chanlimit[IRCD_BUFSIZE]; |
| 1430 |
> |
const char *filename = NULL; |
| 1431 |
> |
char chanmodes[IRCD_BUFSIZE] = ""; |
| 1432 |
> |
char chanlimit[IRCD_BUFSIZE] = ""; |
| 1433 |
|
|
| 1434 |
|
conf_parser_ctx.boot = cold; |
| 1435 |
|
filename = ConfigFileEntry.configfile; |
| 1476 |
|
add_isupport("CHANTYPES", "#", -1); |
| 1477 |
|
|
| 1478 |
|
snprintf(chanlimit, sizeof(chanlimit), "#:%d", |
| 1479 |
< |
ConfigChannel.max_chans_per_user); |
| 1479 |
> |
ConfigChannel.max_channels); |
| 1480 |
|
add_isupport("CHANLIMIT", chanlimit, -1); |
| 1481 |
< |
snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,imnprstORS"); |
| 1482 |
< |
add_isupport("CHANNELLEN", NULL, LOCAL_CHANNELLEN); |
| 1481 |
> |
snprintf(chanmodes, sizeof(chanmodes), "%s", "beI,k,l,cimnprstMORS"); |
| 1482 |
> |
add_isupport("CHANNELLEN", NULL, CHANNELLEN); |
| 1483 |
|
add_isupport("TOPICLEN", NULL, ServerInfo.max_topic_length); |
| 1484 |
|
add_isupport("CHANMODES", chanmodes, -1); |
| 1485 |
|
|
| 1557 |
|
ServerInfo.network_name = NULL; |
| 1558 |
|
MyFree(ServerInfo.network_desc); |
| 1559 |
|
ServerInfo.network_desc = NULL; |
| 1566 |
– |
MyFree(ConfigFileEntry.egdpool_path); |
| 1567 |
– |
ConfigFileEntry.egdpool_path = NULL; |
| 1560 |
|
#ifdef HAVE_LIBCRYPTO |
| 1561 |
|
if (ServerInfo.rsa_private_key) |
| 1562 |
|
{ |
| 1566 |
|
|
| 1567 |
|
MyFree(ServerInfo.rsa_private_key_file); |
| 1568 |
|
ServerInfo.rsa_private_key_file = NULL; |
| 1577 |
– |
|
| 1578 |
– |
if (ServerInfo.server_ctx) |
| 1579 |
– |
SSL_CTX_set_options(ServerInfo.server_ctx, SSL_OP_NO_SSLv2| |
| 1580 |
– |
SSL_OP_NO_SSLv3| |
| 1581 |
– |
SSL_OP_NO_TLSv1); |
| 1582 |
– |
if (ServerInfo.client_ctx) |
| 1583 |
– |
SSL_CTX_set_options(ServerInfo.client_ctx, SSL_OP_NO_SSLv2| |
| 1584 |
– |
SSL_OP_NO_SSLv3| |
| 1585 |
– |
SSL_OP_NO_TLSv1); |
| 1569 |
|
#endif |
| 1570 |
|
|
| 1571 |
|
/* clean out AdminInfo */ |
| 1718 |
|
{ |
| 1719 |
|
const unsigned char *p = (const unsigned char *)data; |
| 1720 |
|
unsigned char tmpch = '\0'; |
| 1721 |
< |
int nonwild = 0; |
| 1721 |
> |
unsigned int nonwild = 0; |
| 1722 |
|
|
| 1723 |
|
while ((tmpch = *p++)) |
| 1724 |
|
{ |
| 1725 |
< |
if (tmpch == '\\') |
| 1725 |
> |
if (tmpch == '\\' && *p) |
| 1726 |
|
{ |
| 1727 |
|
++p; |
| 1728 |
|
if (++nonwild >= ConfigFileEntry.min_nonwildcard_simple) |
| 1749 |
|
int |
| 1750 |
|
valid_wild_card(struct Client *source_p, int warn, int count, ...) |
| 1751 |
|
{ |
| 1752 |
< |
char tmpch; |
| 1753 |
< |
int nonwild = 0; |
| 1752 |
> |
unsigned char tmpch = '\0'; |
| 1753 |
> |
unsigned int nonwild = 0; |
| 1754 |
|
va_list args; |
| 1755 |
|
|
| 1756 |
|
/* |
| 1769 |
|
|
| 1770 |
|
while (count--) |
| 1771 |
|
{ |
| 1772 |
< |
const char *p = va_arg(args, const char *); |
| 1772 |
> |
const unsigned char *p = va_arg(args, const unsigned char *); |
| 1773 |
|
if (p == NULL) |
| 1774 |
|
continue; |
| 1775 |
|
|
| 1792 |
|
|
| 1793 |
|
if (warn) |
| 1794 |
|
sendto_one_notice(source_p, &me, |
| 1795 |
< |
":Please include at least %d non-wildcard characters with the mask", |
| 1795 |
> |
":Please include at least %u non-wildcard characters with the mask", |
| 1796 |
|
ConfigFileEntry.min_nonwildcard); |
| 1797 |
|
va_end(args); |
| 1798 |
|
return 0; |
| 1835 |
|
char **target_server, char **reason) |
| 1836 |
|
{ |
| 1837 |
|
int found_tkline_time=0; |
| 1838 |
< |
static char def_reason[] = "No Reason"; |
| 1838 |
> |
static char def_reason[] = CONF_NOREASON; |
| 1839 |
|
static char user[USERLEN*4+1]; |
| 1840 |
|
static char host[HOSTLEN*4+1]; |
| 1841 |
|
|
| 2001 |
|
/* Okay to use source_p as the first param, because source_p == client_p */ |
| 2002 |
|
if ((target_p = |
| 2003 |
|
find_chasing(source_p, user_host_or_nick)) == NULL) |
| 2004 |
< |
return 0; |
| 2004 |
> |
return 0; /* find_chasing sends ERR_NOSUCHNICK */ |
| 2005 |
|
|
| 2006 |
|
if (IsExemptKline(target_p)) |
| 2007 |
|
{ |
| 2087 |
|
int capab, int cluster_type, const char *pattern, ...) |
| 2088 |
|
{ |
| 2089 |
|
va_list args; |
| 2090 |
< |
char buffer[IRCD_BUFSIZE]; |
| 2090 |
> |
char buffer[IRCD_BUFSIZE] = ""; |
| 2091 |
|
const dlink_node *ptr = NULL; |
| 2092 |
|
|
| 2093 |
|
va_start(args, pattern); |
| 2148 |
|
{ |
| 2149 |
|
*p = '\0'; |
| 2150 |
|
|
| 2151 |
< |
if (iptr->nickptr && *iptr->nuhmask != '\0') |
| 2151 |
> |
if (iptr->nickptr && *iptr->nuhmask) |
| 2152 |
|
strlcpy(iptr->nickptr, iptr->nuhmask, iptr->nicksize); |
| 2153 |
|
|
| 2154 |
|
if ((q = strchr(++p, '@'))) |
| 2155 |
|
{ |
| 2156 |
|
*q++ = '\0'; |
| 2157 |
|
|
| 2158 |
< |
if (*p != '\0') |
| 2158 |
> |
if (*p) |
| 2159 |
|
strlcpy(iptr->userptr, p, iptr->usersize); |
| 2160 |
|
|
| 2161 |
< |
if (*q != '\0') |
| 2161 |
> |
if (*q) |
| 2162 |
|
strlcpy(iptr->hostptr, q, iptr->hostsize); |
| 2163 |
|
} |
| 2164 |
|
else |
| 2165 |
|
{ |
| 2166 |
< |
if (*p != '\0') |
| 2166 |
> |
if (*p) |
| 2167 |
|
strlcpy(iptr->userptr, p, iptr->usersize); |
| 2168 |
|
} |
| 2169 |
|
} |
| 2175 |
|
/* if found a @ */ |
| 2176 |
|
*p++ = '\0'; |
| 2177 |
|
|
| 2178 |
< |
if (*iptr->nuhmask != '\0') |
| 2178 |
> |
if (*iptr->nuhmask) |
| 2179 |
|
strlcpy(iptr->userptr, iptr->nuhmask, iptr->usersize); |
| 2180 |
|
|
| 2181 |
< |
if (*p != '\0') |
| 2181 |
> |
if (*p) |
| 2182 |
|
strlcpy(iptr->hostptr, p, iptr->hostsize); |
| 2183 |
|
} |
| 2184 |
|
else |