diff --git a/include/defaults.h b/include/defaults.h index 1a443937..a194f732 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -51,6 +51,7 @@ #define CLIENT_FLOOD_MIN 10 #define LINKS_DELAY_DEFAULT 300 #define MAX_TARGETS_DEFAULT 4 /* default for max_targets */ +#define MAX_TARGETS 512 /* hard limit for max_targets */ #define IDENT_TIMEOUT 10 #define MIN_JOIN_LEAVE_TIME 60 #define MAX_JOIN_LEAVE_COUNT 25 diff --git a/include/ircd_defs.h b/include/ircd_defs.h index b84dfaa9..b2596260 100644 --- a/include/ircd_defs.h +++ b/include/ircd_defs.h @@ -84,7 +84,10 @@ #endif -#define NICKLEN 30 +#define NICKLEN (30+1) /* Make the default 31, NICKLEN buffers + * are to include the trailing \0 + * This makes the functional nicklen max 30 + */ #define DEFAULT_NICKLEN 9 #define HOSTLEN 63 /* Length of hostname. Updated to */ /* comply with RFC1123 */ diff --git a/libratbox/src/linebuf.c b/libratbox/src/linebuf.c index f86ba536..cee7da67 100644 --- a/libratbox/src/linebuf.c +++ b/libratbox/src/linebuf.c @@ -244,6 +244,8 @@ rb_linebuf_copy_line(rb_buf_head_t * bufhead, rb_buf_line_t * bufline, char *dat /* This is the ~overflow case..This doesn't happen often.. */ if(cpylen > (BUF_DATA_SIZE - bufline->len - 1)) { + size_t old_len = bufline->len; + cpylen = BUF_DATA_SIZE - bufline->len - 1; memcpy(bufch, ch, cpylen); bufline->buf[BUF_DATA_SIZE - 1] = '\0'; @@ -256,7 +258,7 @@ rb_linebuf_copy_line(rb_buf_head_t * bufhead, rb_buf_line_t * bufline, char *dat } bufline->terminated = true; bufline->len = BUF_DATA_SIZE - 1; - bufhead->len += BUF_DATA_SIZE - 1; + bufhead->len += bufline->len - old_len; return clen; } @@ -319,13 +321,15 @@ rb_linebuf_copy_raw(rb_buf_head_t * bufhead, rb_buf_line_t * bufline, char *data /* This is the overflow case..This doesn't happen often.. */ if(cpylen > (BUF_DATA_SIZE - bufline->len - 1)) { + size_t old_len = bufline->len; + clen = BUF_DATA_SIZE - (ssize_t)bufline->len - 1; memcpy(bufch, ch, (size_t)clen); bufline->buf[BUF_DATA_SIZE - 1] = '\0'; bufch = bufline->buf + BUF_DATA_SIZE - 2; bufline->terminated = true; bufline->len = BUF_DATA_SIZE - 1; - bufhead->len += BUF_DATA_SIZE - 1; + bufhead->len += bufline->len - old_len; return clen; } @@ -889,4 +893,3 @@ unsigned int rb_linebuf_numlines(rb_buf_head_t *bufhead) } - diff --git a/libratbox/src/openssl.c b/libratbox/src/openssl.c index 7d567820..2cd9910e 100644 --- a/libratbox/src/openssl.c +++ b/libratbox/src/openssl.c @@ -133,6 +133,7 @@ rb_ssl_timeout(rb_fde_t *F, void *notused) static void rb_ssl_info_callback(SSL * ssl, int where, int ret) { + /* this shouldn't happen anymore with renegotiation disabled */ if(where & SSL_CB_HANDSHAKE_START) { rb_fde_t *F = SSL_get_ex_data(ssl, libratbox_index); @@ -369,8 +370,12 @@ rb_init_ssl(void) { int ret = 1; char libratbox_data[] = "libratbox data"; +#if OPENSSL_VERSION_NUMBER < 0x10100000L SSL_load_error_strings(); SSL_library_init(); +#else + OPENSSL_init_ssl(0, NULL); +#endif libratbox_index = SSL_get_ex_new_index(0, libratbox_data, NULL, NULL, NULL); return ret; @@ -405,7 +410,7 @@ rb_setup_ssl_client(const char *ssl_cipher_list, const char *cert, const char *k sctx = rb_malloc(sizeof(rb_ssl_ctx)); sctx->refcount = 1; - sctx->ssl_ctx = SSL_CTX_new(SSLv23_client_method()); + sctx->ssl_ctx = SSL_CTX_new(TLS_client_method()); SSL_CTX_set_options(sctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION); if(sctx->ssl_ctx == NULL) @@ -458,7 +463,7 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c long tls_opts; sctx = rb_malloc(sizeof(rb_ssl_ctx)); sctx->refcount = 1; - sctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method()); + sctx->ssl_ctx = SSL_CTX_new(TLS_server_method()); if(sctx->ssl_ctx == NULL) { rb_lib_log("rb_init_openssl: Unable to initialize OpenSSL server context: %s", @@ -468,8 +473,9 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c } tls_opts = SSL_CTX_get_options(sctx->ssl_ctx); + /* Disable SSLv2, make the client use our settings */ - tls_opts |= SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE; + tls_opts |= SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION | SSL_OP_CIPHER_SERVER_PREFERENCE | SSL_OP_NO_RENEGOTIATION; switch(tls_min_ver) { case RB_TLS_VER_SSL3: /* we default to SSLv3..sadly */ @@ -554,7 +560,7 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c goto cleanup;; } - +#if OPENSSL_VERSION_NUMBER < 0x30000000L if(dhfile != NULL) { /* DH parameters aren't necessary, but they are nice..if they didn't pass one..that is their problem */ @@ -587,9 +593,13 @@ rb_setup_ssl_server(const char *cacert, const char *cert, const char *keyfile, c dhfile, ERR_error_string(err, NULL)); goto cleanup; } - } + } +#else + SSL_CTX_set_dh_auto(sctx->ssl_ctx, 1); +#endif + -#if OPENSSL_VERSION_NUMBER >= 0x0090800fL +#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL) && (OPENSSL_VERSION_NUMBER < 0x30000000L) #ifndef OPENSSL_NO_ECDH if(named_curve != NULL) @@ -847,11 +857,16 @@ rb_get_random(void *buf, size_t length) int rb_get_pseudo_random(void *buf, size_t length) { +#if OPENSSL_VERSION_NUMBER < 0x10100000L int ret; ret = RAND_pseudo_bytes(buf, (int)length); + if(ret < 0) return 0; return 1; +#else + return rb_get_random(buf, length); +#endif } const char * @@ -899,11 +914,20 @@ rb_supports_ssl(void) return true; } + +#if OPENSSL_VERSION_NUMBER < 0x10100000L +# define rb_ssl_version_num() (long)SSLeay() +# define rb_ssl_version_str() SSLeay_version(SSLEAY_VERSION) +#else +# define rb_ssl_version_num() (long)OpenSSL_version_num() +# define rb_ssl_version_str() OpenSSL_version(OPENSSL_VERSION) +#endif + void rb_get_ssl_info(char *buf, size_t len) { snprintf(buf, len, "Using SSL: %s compiled: 0x%lx, library 0x%lx", - SSLeay_version(SSLEAY_VERSION), (long)OPENSSL_VERSION_NUMBER, SSLeay()); + rb_ssl_version_str(), (long)OPENSSL_VERSION_NUMBER, rb_ssl_version_num()); } #endif /* HAVE_OPESSL */ diff --git a/modules/core/m_message.c b/modules/core/m_message.c index 82a25f7f..24987e06 100644 --- a/modules/core/m_message.c +++ b/modules/core/m_message.c @@ -110,7 +110,7 @@ static int flood_attack_channel(int p_or_n, struct Client *source_p, struct Chan static struct Client *find_userhost(const char *, const char *, int *); -static struct entity targets[512]; +static struct entity targets[MAX_TARGETS]; static int ntargets = 0; static bool duplicate_ptr(void *); @@ -257,6 +257,8 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p, char *p, *nick, *target_list; struct Channel *chptr = NULL; struct Client *target_p; + const int max_targets = (ConfigFileEntry.max_targets > MAX_TARGETS) ? + MAX_TARGETS : ConfigFileEntry.max_targets; target_list = LOCAL_COPY(nicks_channels); @@ -280,7 +282,7 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p, { if(!duplicate_ptr(chptr)) { - if(ntargets >= ConfigFileEntry.max_targets) + if(ntargets >= max_targets) { sendto_one_numeric(source_p, s_RPL(ERR_TOOMANYTARGETS), nick); return (1); @@ -307,7 +309,7 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p, { if(!duplicate_ptr(target_p)) { - if(ntargets >= ConfigFileEntry.max_targets) + if(ntargets >= max_targets) { sendto_one_numeric(source_p, s_RPL(ERR_TOOMANYTARGETS), nick); return (1); @@ -362,7 +364,7 @@ build_target_list(int p_or_n, const char *command, struct Client *client_p, if(!duplicate_ptr(chptr)) { - if(ntargets >= ConfigFileEntry.max_targets) + if(ntargets >= max_targets) { sendto_one_numeric(source_p, s_RPL(ERR_TOOMANYTARGETS), nick); return (1); diff --git a/modules/core/m_mode.c b/modules/core/m_mode.c index ca53b1a7..06401c8b 100644 --- a/modules/core/m_mode.c +++ b/modules/core/m_mode.c @@ -889,6 +889,9 @@ chm_ban(struct Client *source_p, struct Channel *chptr, else mask = pretty_mask(raw_mask); + if(mask == NULL) + return; + /* we'd have problems parsing this, hyb6 does it too */ if(strlen(mask) > (MODEBUFLEN - 2)) return; diff --git a/modules/m_cap.c b/modules/m_cap.c index cae7bd01..f6989d89 100644 --- a/modules/m_cap.c +++ b/modules/m_cap.c @@ -109,10 +109,8 @@ clicap_compare(const char *name, struct clicap *cap) * Ouputs: Cap entry if found, NULL otherwise. */ static struct clicap * -clicap_find(const char *data, int *negate, int *finished, char **p) +clicap_find(const char *data, int *negate, int *finished, char *buf, size_t bufsz, char **p) { - char buf[IRCD_BUFSIZE]; -// static char *p = NULL; struct clicap *cap; char *s; @@ -120,7 +118,7 @@ clicap_find(const char *data, int *negate, int *finished, char **p) if(data != NULL) { - rb_strlcpy(buf, data, sizeof(buf)); + rb_strlcpy(buf, data, bufsz); *p = buf; } @@ -270,14 +268,15 @@ static void cap_ack(struct Client *source_p, const char *arg) { struct clicap *cap; + char clicap_buf[IRCD_BUFSIZE]; int capadd = 0, capdel = 0; int finished = 0, negate; char *p = NULL; if(EmptyString(arg)) return; - for(cap = clicap_find(arg, &negate, &finished, &p); cap; - cap = clicap_find(NULL, &negate, &finished, &p)) + for(cap = clicap_find(arg, &negate, &finished, clicap_buf, sizeof(clicap_buf), &p); cap; + cap = clicap_find(NULL, &negate, &finished, clicap_buf, sizeof(clicap_buf), &p)) { /* sent an ACK for something they havent REQd */ if(!IsCapable(source_p, cap->cap_serv)) @@ -352,6 +351,7 @@ cap_req(struct Client *source_p, const char *arg) { char buf[IRCD_BUFSIZE]; char pbuf[2][IRCD_BUFSIZE]; + char clicap_buf[IRCD_BUFSIZE]; char *p = NULL; struct clicap *cap; int buflen, plen; @@ -371,8 +371,8 @@ cap_req(struct Client *source_p, const char *arg) pbuf[0][0] = '\0'; plen = 0; - for(cap = clicap_find(arg, &negate, &finished, &p); cap; - cap = clicap_find(NULL, &negate, &finished, &p)) + for(cap = clicap_find(arg, &negate, &finished, clicap_buf, sizeof(clicap_buf), &p); cap; + cap = clicap_find(NULL, &negate, &finished, clicap_buf, sizeof(clicap_buf), &p)) { /* filled the first array, but cant send it in case the * request fails. one REQ should never fill more than two diff --git a/modules/m_dline.c b/modules/m_dline.c index f69f0e58..75348ed7 100644 --- a/modules/m_dline.c +++ b/modules/m_dline.c @@ -202,22 +202,10 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha } host = LOCAL_COPY(aconf->host); - remove_dline(aconf); - - if(!(aconf->flags & CONF_FLAGS_TEMPORARY)) - { - bandb_del(BANDB_DLINE, host, NULL); - - sendto_one_notice(source_p, ":D-Line for [%s] is removed", host); - sendto_realops_flags(UMODE_ALL, L_ALL, "%s has removed the D-Line for: [%s]", - get_oper_name(source_p), host); - - } - else + if(aconf->flags & CONF_FLAGS_TEMPORARY) { - rb_dlink_list *list; - list = &temp_dlines[aconf->port]; - rb_dlinkFindDestroy(aconf, list); + rb_dlinkFindDestroy(aconf, &temp_dlines[aconf->port]); + remove_dline(aconf); sendto_one_notice(source_p, ":Un-dlined [%s] from temporary D-lines", host); sendto_realops_flags(UMODE_ALL, L_ALL, "%s has removed the temporary D-Line for: [%s]", @@ -225,6 +213,12 @@ mo_undline(struct Client *client_p, struct Client *source_p, int parc, const cha return 0; } + remove_dline(aconf); + bandb_del(BANDB_DLINE, host, NULL); + sendto_one_notice(source_p, ":D-Line for [%s] is removed", host); + sendto_realops_flags(UMODE_ALL, L_ALL, "%s has removed the D-Line for: [%s]", + get_oper_name(source_p), host); + ilog(L_KLINE, "UD %s %s", get_oper_name(source_p), host); return 0; @@ -235,10 +229,12 @@ valid_dline(struct Client *source_p, const char *dlhost) { char cidr_form_host[HOSTLEN + 1]; int bits; + int ty; rb_strlcpy(cidr_form_host, dlhost, sizeof(cidr_form_host)); - if(!parse_netmask(dlhost, NULL, &bits)) + ty = parse_netmask(dlhost, NULL, &bits); + if(!ty || ty == HM_HOST) { sendto_one_notice(source_p, ":Invalid D-Line"); return 0; diff --git a/src/hostmask.c b/src/hostmask.c index 7e18217f..9648400d 100644 --- a/src/hostmask.c +++ b/src/hostmask.c @@ -689,6 +689,6 @@ show_iline_prefix(struct Client *sptr, struct ConfItem *aconf, const char *name) if(MyOper(sptr) && IsConfExemptLimits(aconf)) *prefix_ptr++ = '>'; *prefix_ptr = '\0'; - strncpy(prefix_ptr, name, USERLEN); + rb_strlcpy(prefix_ptr, name, USERLEN + 1); return (prefix_of_host); } diff --git a/src/match.c b/src/match.c index 2f53eef4..75ad4dba 100644 --- a/src/match.c +++ b/src/match.c @@ -380,7 +380,7 @@ match_ips(const char *s1, const char *s2) *len++ = '\0'; cidrlen = atoi(len); - if(cidrlen <= 0) + if(cidrlen < 0) return 0; #ifdef RB_IPV6 @@ -410,6 +410,8 @@ match_ips(const char *s1, const char *s2) return 0; if(rb_inet_pton(aftype, mask, maskptr) <= 0) return 0; + if(cidrlen == 0) + return 1; if(comp_with_mask(ipptr, maskptr, cidrlen)) return 1; else diff --git a/src/newconf.c b/src/newconf.c index b76a2cca..087142db 100644 --- a/src/newconf.c +++ b/src/newconf.c @@ -939,11 +939,11 @@ conf_set_serverinfo_nicklen(confentry_t * entry, conf_t * conf, struct conf_item if(ServerInfo.nicklen <= 0) { nicklen = entry->number; - if(nicklen > NICKLEN) + if(nicklen > NICKLEN - 1) { conf_report_error_nl ("serverinfo::nicklen -- Nicklen cannot exceed %u(set to %u) - modify #define NICKLEN in include/ircd_defs.h to increase and recompile", - NICKLEN, nicklen); + NICKLEN - 1, nicklen); } else if(nicklen < 9) { @@ -1751,6 +1751,21 @@ conf_set_general_hide_error_messages(confentry_t * entry, conf_t * conf, struct entry->filename, entry->line); } +static void +conf_set_general_max_targets(confentry_t * entry, conf_t * conf, struct conf_items *item) +{ + int max_targets = entry->number; + + if(max_targets > MAX_TARGETS) + { + conf_report_warning_nl("general::max_targets %d at %s:%d exceeds maximum %d; clamping.", + max_targets, entry->filename, entry->line, MAX_TARGETS); + max_targets = MAX_TARGETS; + } + + ConfigFileEntry.max_targets = max_targets; +} + static void conf_set_general_oper_only_umodes(confentry_t * entry, conf_t * conf, struct conf_items *item) { @@ -2617,7 +2632,7 @@ static struct conf_items conf_general_table[] = { "max_monitor", CF_INT, NULL, 0, &ConfigFileEntry.max_monitor }, { "max_nick_time", CF_TIME, NULL, 0, &ConfigFileEntry.max_nick_time }, { "max_nick_changes", CF_INT, NULL, 0, &ConfigFileEntry.max_nick_changes }, - { "max_targets", CF_INT, NULL, 0, &ConfigFileEntry.max_targets }, + { "max_targets", CF_INT, conf_set_general_max_targets, 0, NULL }, { "min_nonwildcard", CF_INT, NULL, 0, &ConfigFileEntry.min_nonwildcard }, { "nick_delay", CF_TIME, NULL, 0, &ConfigFileEntry.nick_delay }, { "no_oper_flood", CF_YESNO, NULL, 0, &ConfigFileEntry.no_oper_flood }, diff --git a/src/reject.c b/src/reject.c index cebbeea8..5d079dba 100644 --- a/src/reject.c +++ b/src/reject.c @@ -289,7 +289,11 @@ remove_reject(const char *ip) static void delete_ipline(struct ConfItem *aconf, rb_patricia_tree_t * t) { - rb_patricia_remove(t, aconf->pnode); + if(aconf->pnode != NULL) + { + rb_patricia_remove(t, aconf->pnode); + aconf->pnode = NULL; + } if(!aconf->clients) { free_conf(aconf); diff --git a/src/s_conf.c b/src/s_conf.c index 586f3c26..9cbe69d1 100644 --- a/src/s_conf.c +++ b/src/s_conf.c @@ -944,6 +944,13 @@ add_temp_kline(struct ConfItem *aconf) void add_temp_dline(struct ConfItem *aconf) { + if(!add_dline(aconf)) + { + ilog(L_MAIN, "Invalid Dline %s ignored", aconf->host); + free_conf(aconf); + return; + } + if(aconf->hold >= rb_current_time() + (10080 * 60)) { rb_dlinkAddAlloc(aconf, &temp_dlines[TEMP_WEEK]); @@ -966,7 +973,6 @@ add_temp_dline(struct ConfItem *aconf) } aconf->flags |= CONF_FLAGS_TEMPORARY; - add_dline(aconf); } /* expire_tkline() diff --git a/ssld/ssld.c b/ssld/ssld.c index be3f62fa..3060170d 100644 --- a/ssld/ssld.c +++ b/ssld/ssld.c @@ -592,11 +592,14 @@ conn_mod_read_cb(rb_fde_t *fd, void *data) } + /* renegotiation is disabled in libratbox unconditionally, so this code isn't needed anymore */ +#if 0 if((rb_ssl_handshake_count(conn->mod_fd) > 1) && (rb_current_time() - rb_ssl_last_handshake(conn->mod_fd)) < 1200) { close_conn(conn, WAIT_PLAIN, "TLS error: Enjoying shaking my hand off?"); return; } +#endif if(length < 0) {