ircd/listener: return a fatal TLS alert for early rejected TLS clients
This is in furtherance of commit 3fdf26aa19
which added
functionality to reply with a TLS record layer alert for D-Lined TLS
clients. It turns out that there are other plaintext error messages
in this same function that should receive the same treatment.
Also move another error string to a variable and use a compile-time
optimised-out strlen for it too, to use the same approach as an
existing error string.
Finally, use a different alert (internal_error) for the case where
IRCd is simply unable to accept more connections.
This commit is contained in:
parent
c1b01bf5ec
commit
642c73dddb
3 changed files with 48 additions and 21 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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->ssl)
|
||||
{
|
||||
rb_write(ddata->F, ssldeniederrcode, sizeof(ssldeniederrcode));
|
||||
}
|
||||
else
|
||||
{
|
||||
*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));
|
||||
}
|
||||
|
||||
if (ddata->aconf)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else if (ddata->reason)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
rb_write(ddata->F, errbuf, strlen(errbuf));
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue