rb_dictionary *nd_dict = NULL;
-enum
-{
- D_LINED,
- K_LINED
-};
-
rb_dlink_list dead_list;
#ifdef DEBUG_EXITED_CLIENTS
static rb_dlink_list dead_remote_list;
if (client_p->localClient->connids.head)
s_assert(MyConnect(client_p));
+ if (!MyConnect(client_p))
+ return;
+
RB_DLINK_FOREACH_SAFE(ptr, ptr2, client_p->localClient->connids.head)
connid_put(RB_POINTER_TO_UINT(ptr->data));
}
}
SetUnknown(client_p);
- strcpy(client_p->username, "unknown");
+ rb_strlcpy(client_p->username, "unknown", sizeof(client_p->username));
return client_p;
}
rb_free(client_p->localClient->auth_user);
rb_free(client_p->localClient->challenge);
rb_free(client_p->localClient->fullcaps);
- rb_free(client_p->localClient->opername);
rb_free(client_p->localClient->mangledhost);
- if (client_p->localClient->privset)
- privilegeset_unref(client_p->localClient->privset);
if (IsSSL(client_p))
ssld_decrement_clicount(client_p->localClient->ssl_ctl);
+ rb_free(client_p->localClient->cipher_string);
+
if (IsCapable(client_p, CAP_ZIP))
ssld_decrement_clicount(client_p->localClient->z_ctl);
+ rb_free(client_p->localClient->zipstats);
+
if (client_p->localClient->ws_ctl != NULL)
wsockd_decrement_clicount(client_p->localClient->ws_ctl);
client_p->localClient = NULL;
}
-void
+static void
free_client(struct Client *client_p)
{
s_assert(NULL != client_p);
}
}
-static void
+void
notify_banned_client(struct Client *client_p, struct ConfItem *aconf, int ban)
{
static const char conn_closed[] = "Connection closed";
check_xlines();
}
-/* check_klines_event()
- *
- * inputs -
- * outputs -
- * side effects - check_klines() is called, kline_queued unset
- */
-void
-check_klines_event(void *unused)
-{
- kline_queued = false;
- check_klines();
-}
-
/* check_klines
*
* inputs -
}
}
+
+/* check_one_kline()
+ *
+ * This process needs to be kept in sync with find_kline() aka find_conf_by_address().
+ *
+ * inputs - pointer to kline to check
+ * outputs -
+ * side effects - all clients will be checked against given kline
+ */
+void
+check_one_kline(struct ConfItem *kline)
+{
+ struct Client *client_p;
+ rb_dlink_node *ptr;
+ rb_dlink_node *next_ptr;
+ int masktype;
+ int bits;
+ struct rb_sockaddr_storage sockaddr;
+ struct sockaddr_in ip4;
+
+ masktype = parse_netmask(kline->host, (struct sockaddr_storage *)&sockaddr, &bits);
+
+ RB_DLINK_FOREACH_SAFE(ptr, next_ptr, lclient_list.head)
+ {
+ int matched = 0;
+
+ client_p = ptr->data;
+
+ if(IsMe(client_p) || !IsPerson(client_p))
+ continue;
+
+ if(!match(kline->user, client_p->username))
+ continue;
+
+ /* match one kline */
+ switch (masktype) {
+ case HM_IPV4:
+ case HM_IPV6:
+ if (IsConfDoSpoofIp(client_p->localClient->att_conf) &&
+ IsConfKlineSpoof(client_p->localClient->att_conf))
+ continue;
+ if (client_p->localClient->ip.ss_family == AF_INET6 && sockaddr.ss_family == AF_INET &&
+ rb_ipv4_from_ipv6((struct sockaddr_in6 *)&client_p->localClient->ip, &ip4)
+ && comp_with_mask_sock((struct sockaddr *)&ip4, (struct sockaddr *)&sockaddr, bits))
+ matched = 1;
+ else if (client_p->localClient->ip.ss_family == sockaddr.ss_family &&
+ comp_with_mask_sock((struct sockaddr *)&client_p->localClient->ip,
+ (struct sockaddr *)&sockaddr, bits))
+ matched = 1;
+ break;
+ case HM_HOST:
+ if (match(kline->host, client_p->orighost))
+ matched = 1;
+ if (IsConfDoSpoofIp(client_p->localClient->att_conf) &&
+ IsConfKlineSpoof(client_p->localClient->att_conf))
+ continue;
+ if (match(kline->host, client_p->sockhost))
+ matched = 1;
+ break;
+ }
+
+ if (!matched)
+ continue;
+
+ if(IsExemptKline(client_p))
+ {
+ sendto_realops_snomask(SNO_GENERAL, L_NETWIDE,
+ "KLINE over-ruled for %s, client is kline_exempt [%s@%s]",
+ get_client_name(client_p, HIDE_IP),
+ kline->user, kline->host);
+ continue;
+ }
+
+ sendto_realops_snomask(SNO_GENERAL, L_ALL,
+ "KLINE active for %s",
+ get_client_name(client_p, HIDE_IP));
+
+ notify_banned_client(client_p, kline, K_LINED);
+ }
+}
+
+
/* check_dlines()
*
* inputs -
*/
static int
-exit_unknown_client(struct Client *client_p, struct Client *source_p, struct Client *from,
- const char *comment)
+exit_unknown_client(struct Client *client_p, /* The local client originating the
+ * exit or NULL, if this exit is
+ * generated by this server for
+ * internal reasons.
+ * This will not get any of the
+ * generated messages. */
+ struct Client *source_p, /* Client exiting */
+ struct Client *from, /* Client firing off this Exit,
+ * never NULL! */
+ const char *comment)
{
- authd_abort_client(client_p);
+ authd_abort_client(source_p);
rb_dlinkDelete(&source_p->localClient->tnode, &unknown_list);
if(!IsIOError(source_p))
del_from_id_hash(source_p->id, source_p);
del_from_hostname_hash(source_p->host, source_p);
- del_from_client_hash(source_p->name, source_p);
+ if (!IsAnyServer(source_p))
+ del_from_client_hash(source_p->name, source_p);
remove_client_from_list(source_p);
SetDead(source_p);
rb_dlinkAddAlloc(source_p, &dead_list);
snprintf(newcomment, sizeof(newcomment), "by %s: %s",
from->name, comment);
- if(source_p->serv != NULL)
- remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
+ remove_dependents(client_p, source_p, from, IsPerson(from) ? newcomment : comment, comment1);
- if(source_p->servptr && source_p->servptr->serv)
- rb_dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
- else
- s_assert(0);
+ rb_dlinkDelete(&source_p->lnode, &source_p->servptr->serv->servers);
rb_dlinkFindDestroy(source_p, &global_serv_list);
target_p = source_p->from;
del_from_client_hash(source_p->name, source_p);
remove_client_from_list(source_p);
+
scache_split(source_p->serv->nameinfo);
SetDead(source_p);
const char *comment /* Reason for the exit */
)
{
+ int ret = -1;
+
hook_data_client_exit hdata;
if(IsClosing(source_p))
return -1;
{
/* Local clients of various types */
if(IsPerson(source_p))
- return exit_local_client(client_p, source_p, from, comment);
+ ret = exit_local_client(client_p, source_p, from, comment);
else if(IsServer(source_p))
- return exit_local_server(client_p, source_p, from, comment);
+ ret = exit_local_server(client_p, source_p, from, comment);
/* IsUnknown || IsConnecting || IsHandShake */
else if(!IsReject(source_p))
- return exit_unknown_client(client_p, source_p, from, comment);
+ ret = exit_unknown_client(client_p, source_p, from, comment);
}
else
{
/* Remotes */
if(IsPerson(source_p))
- return exit_remote_client(client_p, source_p, from, comment);
+ ret = exit_remote_client(client_p, source_p, from, comment);
else if(IsServer(source_p))
- return exit_remote_server(client_p, source_p, from, comment);
+ ret = exit_remote_server(client_p, source_p, from, comment);
}
- return -1;
+ call_hook(h_after_client_exit, NULL);
+
+ return ret;
}
/*
{
if(user->away)
rb_free((char *) user->away);
+ rb_free(user->opername);
+ if (user->privset)
+ privilegeset_unref(user->privset);
/*
* sanity check
*/