]> jfr.im git - irc/freenode/solanum.git/commitdiff
Implement oper realhost view via a hidden cap
authorEd Kellett <redacted>
Thu, 22 Oct 2020 13:46:21 +0000 (14:46 +0100)
committerEd Kellett <redacted>
Sat, 24 Oct 2020 15:19:52 +0000 (16:19 +0100)
extensions/cap_realhost.c

index 1ddf96b05b534eb9f1b7cabb1b215a2c5614344c..46de2532e4a5e4efef6d4462f28624cb097b2217 100644 (file)
 
 static char cap_realhost_desc[] = "Provides the solanum.chat/realhost oper-only capability";
 
-static bool cap_realhost_visible(struct Client *);
+static bool cap_oper_realhost_visible(struct Client *);
 static void cap_realhost_outbound_msgbuf(void *);
 static void cap_realhost_umode_changed(void *);
+static void cap_realhost_cap_change(void *);
 
 static unsigned CLICAP_REALHOST;
+static unsigned CLICAP_OPER_REALHOST;
 
-static struct ClientCapability cap_realhost = {
-       .visible = cap_realhost_visible,
+static struct ClientCapability capdata_oper_realhost = {
+       .visible = cap_oper_realhost_visible,
 };
 
 mapi_cap_list_av2 cap_realhost_caps[] = {
-       { MAPI_CAP_CLIENT, "solanum.chat/realhost", &cap_realhost, &CLICAP_REALHOST },
+       { MAPI_CAP_CLIENT, "solanum.chat/realhost", NULL, &CLICAP_REALHOST },
+       { MAPI_CAP_CLIENT, "?oper_realhost", &capdata_oper_realhost, &CLICAP_OPER_REALHOST },
        { 0, NULL, NULL, NULL },
 };
 
 mapi_hfn_list_av1 cap_realhost_hfnlist[] = {
        { "outbound_msgbuf", cap_realhost_outbound_msgbuf, HOOK_NORMAL },
        { "umode_changed", cap_realhost_umode_changed, HOOK_MONITOR },
+       { "cap_change", cap_realhost_cap_change, HOOK_MONITOR },
        { NULL, NULL, 0 },
 };
 
 static bool
-cap_realhost_visible(struct Client *client)
+cap_oper_realhost_visible(struct Client *client)
 {
-       return HasPrivilege(client, "cap:realhost");
+       return false;
 }
 
 static void
@@ -60,14 +64,34 @@ cap_realhost_outbound_msgbuf(void *data_)
        hook_data *data = data_;
        struct MsgBuf *msgbuf = data->arg1;
 
-       if (data->client == NULL)
+       if (data->client == NULL || !IsPerson(data->client))
                return;
 
        if (!IsIPSpoof(data->client) && !EmptyString(data->client->sockhost) && strcmp(data->client->sockhost, "0"))
-               msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost, CLICAP_REALHOST);
+       {
+               if (IsDynSpoof(data->client))
+                       msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost, CLICAP_OPER_REALHOST);
+               else
+                       msgbuf_append_tag(msgbuf, "solanum.chat/ip", data->client->sockhost, CLICAP_REALHOST);
+       }
 
        if (!EmptyString(data->client->orighost))
-               msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_REALHOST);
+       {
+               if (IsDynSpoof(data->client))
+                       msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_OPER_REALHOST);
+               else
+                       msgbuf_append_tag(msgbuf, "solanum.chat/realhost", data->client->orighost, CLICAP_REALHOST);
+       }
+}
+
+static inline void
+update_clicap_oper_realhost(struct Client *client)
+{
+       client->localClient->caps &= ~CLICAP_OPER_REALHOST;
+       if (client->localClient->caps & CLICAP_REALHOST && HasPrivilege(client, "auspex:hostname"))
+       {
+               client->localClient->caps |= CLICAP_OPER_REALHOST;
+       }
 }
 
 static void
@@ -78,8 +102,30 @@ cap_realhost_umode_changed(void *data_)
        if (!MyClient(data->client))
                return;
 
-       if (!cap_realhost_visible(data->client))
-               data->client->localClient->caps &= ~CLICAP_REALHOST;
+       update_clicap_oper_realhost(data->client);
+}
+
+static void
+cap_realhost_cap_change(void *data_)
+{
+       hook_data_cap_change *data = data_;
+
+       update_clicap_oper_realhost(data->client);
+}
+
+static int
+modinit(void)
+{
+       rb_dlink_node *ptr;
+
+       RB_DLINK_FOREACH(ptr, lclient_list.head)
+       {
+               struct Client *client = ptr->data;
+
+               update_clicap_oper_realhost(client);
+       }
+
+       return 0;
 }
 
-DECLARE_MODULE_AV2(cap_realhost, NULL, NULL, NULL, NULL, cap_realhost_hfnlist, cap_realhost_caps, NULL, cap_realhost_desc);
+DECLARE_MODULE_AV2(cap_realhost, modinit, NULL, NULL, NULL, cap_realhost_hfnlist, cap_realhost_caps, NULL, cap_realhost_desc);