diff --git a/include/reject.h b/include/reject.h index 2ca378fe..5ed02342 100644 --- a/include/reject.h +++ b/include/reject.h @@ -28,7 +28,7 @@ #define DELAYED_EXIT_TIME 10 void init_reject(void); -int check_reject(rb_fde_t *F, struct sockaddr *addr); +int check_reject(rb_fde_t *F, struct sockaddr *addr, bool ssl); void add_reject(struct Client *, const char *mask1, const char *mask2, struct ConfItem *aconf, const char *reason); int is_reject_ip(struct sockaddr *addr); void flush_reject(void); diff --git a/ircd/listener.c b/ircd/listener.c index 80947af8..02b6dabd 100644 --- a/ircd/listener.c +++ b/ircd/listener.c @@ -581,13 +581,19 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi static time_t last_oper_notice = 0; int len; + static const char *allinuse = "ERROR :All connections in use\r\n"; static const char *toofast = "ERROR :Reconnecting too fast, throttled.\r\n"; - static const unsigned char sslerrcode[] = { + static const unsigned char ssldeniederrcode[] = { // SSLv3.0 Fatal Alert: Access Denied 0x15, 0x03, 0x00, 0x00, 0x02, 0x02, 0x31 }; + static const unsigned char sslinternalerrcode[] = { + // SSLv3.0 Fatal Alert: Internal Error + 0x15, 0x03, 0x00, 0x00, 0x02, 0x02, 0x50 + }; + if(listener->ssl && (!ircd_ssl_ok || !get_ssld_count())) { rb_close(F); @@ -608,7 +614,11 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi last_oper_notice = rb_current_time(); } - rb_write(F, "ERROR :All connections in use\r\n", 31); + if(listener->ssl) + rb_write(F, sslinternalerrcode, sizeof(sslinternalerrcode)); + else + rb_write(F, allinuse, strlen(allinuse)); + rb_close(F); return 0; } @@ -625,7 +635,7 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi if(listener->ssl) { - rb_write(F, sslerrcode, sizeof(sslerrcode)); + rb_write(F, ssldeniederrcode, sizeof(ssldeniederrcode)); } else if(ConfigFileEntry.dline_with_reason) { @@ -648,7 +658,7 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi return 0; } - if(check_reject(F, addr)) { + if(check_reject(F, addr, listener->ssl)) { /* Reject the connection without closing the socket * because it is now on the delay_exit list. */ return 0; @@ -656,7 +666,11 @@ accept_precallback(rb_fde_t *F, struct sockaddr *addr, rb_socklen_t addrlen, voi if(throttle_add(addr)) { - rb_write(F, toofast, strlen(toofast)); + if(listener->ssl) + rb_write(F, ssldeniederrcode, sizeof(ssldeniederrcode)); + else + rb_write(F, toofast, strlen(toofast)); + rb_close(F); return 0; } diff --git a/ircd/reject.c b/ircd/reject.c index 801af5ff..767dc087 100644 --- a/ircd/reject.c +++ b/ircd/reject.c @@ -58,6 +58,7 @@ typedef struct _delay_data rb_fde_t *F; struct ConfItem *aconf; const char *reason; + bool ssl; } delay_t; typedef struct _throttle @@ -92,28 +93,39 @@ reject_exit(void *unused) delay_t *ddata; static const char *errbuf = "ERROR :Closing Link: (*** Banned (cache))\r\n"; + static const unsigned char ssldeniederrcode[] = { + // SSLv3.0 Fatal Alert: Access Denied + 0x15, 0x03, 0x00, 0x00, 0x02, 0x02, 0x31 + }; + RB_DLINK_FOREACH_SAFE(ptr, ptr_next, delay_exit.head) { ddata = ptr->data; - *dynamic_reason = '\0'; - - if (ddata->aconf) + if (ddata->ssl) { - snprintf(dynamic_reason, sizeof dynamic_reason, form_str(ERR_YOUREBANNEDCREEP) "\r\n", - me.name, "*", get_user_ban_reason(ddata->aconf)); - rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); - - deref_conf(ddata->aconf); + rb_write(ddata->F, ssldeniederrcode, sizeof(ssldeniederrcode)); } - else if (ddata->reason) + else { - snprintf(dynamic_reason, sizeof dynamic_reason, ":%s 465 %s :%s\r\n", - me.name, "*", ddata->reason); - rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); + *dynamic_reason = '\0'; + + if (ddata->aconf) + snprintf(dynamic_reason, sizeof dynamic_reason, form_str(ERR_YOUREBANNEDCREEP) "\r\n", + me.name, "*", get_user_ban_reason(ddata->aconf)); + else if (ddata->reason) + snprintf(dynamic_reason, sizeof dynamic_reason, ":%s 465 %s :%s\r\n", + me.name, "*", ddata->reason); + + if (*dynamic_reason) + rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); + + rb_write(ddata->F, errbuf, strlen(errbuf)); } - rb_write(ddata->F, errbuf, strlen(errbuf)); + if (ddata->aconf) + deref_conf(ddata->aconf); + rb_close(ddata->F); rb_free(ddata); } @@ -228,7 +240,7 @@ add_reject(struct Client *client_p, const char *mask1, const char *mask2, struct } int -check_reject(rb_fde_t *F, struct sockaddr *addr) +check_reject(rb_fde_t *F, struct sockaddr *addr, bool ssl) { rb_patricia_node_t *pnode; reject_t *rdata; @@ -276,6 +288,7 @@ check_reject(rb_fde_t *F, struct sockaddr *addr) ddata->reason = NULL; } ddata->F = F; + ddata->ssl = ssl; rb_dlinkAdd(ddata, &ddata->node, &delay_exit); return 1; }