]> jfr.im git - solanum.git/blobdiff - ircd/client.c
Add a comment explaining match_arrange_stars
[solanum.git] / ircd / client.c
index 9ec5c6cc759414fa464462a10985daefab82e1a7..a11873991a2f40d98b043b7a71a67429f2e49aac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  charybdis: an advanced ircd.
+ *  Solanum: a slightly advanced ircd
  *  client.c: Controls clients.
  *
  *  Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
@@ -80,12 +80,6 @@ static uint32_t current_connid = 0;
 
 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;
@@ -306,17 +300,18 @@ free_local_client(struct Client *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);
 
@@ -324,7 +319,7 @@ free_local_client(struct Client *client_p)
        client_p->localClient = NULL;
 }
 
-void
+static void
 free_client(struct Client *client_p)
 {
        s_assert(NULL != client_p);
@@ -483,7 +478,7 @@ check_unknowns_list(rb_dlink_list * list)
        }
 }
 
-static void
+void
 notify_banned_client(struct Client *client_p, struct ConfItem *aconf, int ban)
 {
        static const char conn_closed[] = "Connection closed";
@@ -528,19 +523,6 @@ check_banned_lines(void)
        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       -
@@ -583,6 +565,88 @@ check_klines(void)
        }
 }
 
+
+/* 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       -
@@ -1083,7 +1147,7 @@ free_exited_clients(void *unused)
                                                target_p->name, (unsigned int) target_p->status,
                                                (unsigned long long)target_p->flags,  target_p->handler);
                                        sendto_realops_snomask(SNO_GENERAL, L_ALL,
-                                               "Please report this to the charybdis developers!");
+                                               "Please report this to the solanum developers!");
                                        found++;
                                }
                        }
@@ -1227,7 +1291,7 @@ exit_aborted_clients(void *unused)
                                        abt->client->name, (unsigned int) abt->client->status,
                                        (unsigned long long)abt->client->flags, abt->client->handler);
                                sendto_realops_snomask(SNO_GENERAL, L_ALL,
-                                       "Please report this to the charybdis developers!");
+                                       "Please report this to the solanum developers!");
                                continue;
                        }
                }
@@ -1379,7 +1443,8 @@ exit_unknown_client(struct Client *client_p, /* The local client originating the
                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);
@@ -1408,13 +1473,9 @@ exit_remote_server(struct Client *client_p, struct Client *source_p, struct Clie
                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;
@@ -1432,6 +1493,7 @@ exit_remote_server(struct Client *client_p, struct Client *source_p, struct Clie
 
        del_from_client_hash(source_p->name, source_p);
        remove_client_from_list(source_p);
+
        scache_split(source_p->serv->nameinfo);
 
        SetDead(source_p);
@@ -1624,6 +1686,8 @@ exit_client(struct Client *client_p,      /* The local client originating the
            const char *comment /* Reason for the exit */
        )
 {
+       int ret = -1;
+
        hook_data_client_exit hdata;
        if(IsClosing(source_p))
                return -1;
@@ -1644,23 +1708,25 @@ exit_client(struct Client *client_p,    /* The local client originating the
        {
                /* 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;
 }
 
 /*
@@ -1767,11 +1833,11 @@ show_ip(struct Client *source_p, struct Client *target_p)
                 * to local opers.
                 */
                if(!ConfigFileEntry.hide_spoof_ips &&
-                  (source_p == NULL || MyOper(source_p)))
+                  (source_p == NULL || (MyConnect(source_p) && HasPrivilege(source_p, "auspex:hostname"))))
                        return 1;
                return 0;
        }
-       else if(IsDynSpoof(target_p) && (source_p != NULL && !IsOper(source_p)))
+       else if(IsDynSpoof(target_p) && (source_p != NULL && !HasPrivilege(source_p, "auspex:hostname")))
                return 0;
        else
                return 1;
@@ -1865,6 +1931,9 @@ free_user(struct User *user, struct Client *client_p)
        {
                if(user->away)
                        rb_free((char *) user->away);
+               rb_free(user->opername);
+               if (user->privset)
+                       privilegeset_unref(user->privset);
                /*
                 * sanity check
                 */