]> jfr.im git - irc/rqf/shadowircd.git/commitdiff
Pass certfp to other servers and show it in whois. Do not show it on connect.
authorJilles Tjoelker <redacted>
Fri, 5 Feb 2010 23:18:27 +0000 (00:18 +0100)
committerJilles Tjoelker <redacted>
Fri, 5 Feb 2010 23:18:27 +0000 (00:18 +0100)
The server protocol for this is
:<uid> ENCAP * CERTFP :<40 hex chars>
both in new user introductions and in burst.

As in oftc-hybrid, only the user themselves and opers can see the certfp.

Displaying the certfp on connect seems unnecessary to me,
the user can whois themselves if needed.

include/client.h
include/numeric.h
modules/Makefile.in
modules/m_certfp.c [new file with mode: 0644]
modules/m_whois.c
src/client.c
src/messages.tab
src/s_serv.c
src/s_user.c
src/sslproc.c

index 508b9db25cd034aa3e1b0b3677125ef87da29154..8af1709c78d1eabb709ddce768009b192fc2f338 100644 (file)
@@ -161,6 +161,7 @@ struct Client
        struct PreClient *preClient;
 
        time_t large_ctcp_sent; /* ctcp to large group sent, relax flood checks */
+       char *certfp; /* client certificate fingerprint */
 };
 
 struct LocalUser
index 6b449e48d3051545778d477d3c62c8ce3eb3c6d8..92dc560fa3abf8bc32fe896089f192d0aac20ecd 100644 (file)
@@ -120,6 +120,8 @@ extern const char *form_str(int);
 
 #define RPL_PRIVS            270 /* from ircu */
 
+#define RPL_WHOISCERTFP      276 /* from oftc-hybrid */
+
 #define RPL_ACCEPTLIST      281
 #define RPL_ENDOFACCEPT      282
 
index f1807cf586b2d5b6d7fac72036752e40b6e3b148..dd9666448e38210078f04cf040bc5cb0063d74bb 100644 (file)
@@ -55,6 +55,7 @@ TSRCS =                          \
   m_away.c \
   m_cap.c \
   m_capab.c \
+  m_certfp.c \
   m_challenge.c \
   m_chghost.c \
   m_close.c \
diff --git a/modules/m_certfp.c b/modules/m_certfp.c
new file mode 100644 (file)
index 0000000..6670f88
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * m_certfp.c: propagates client certificate fingerprint information
+ *
+ * Copyright (C) 2010 Jilles Tjoelker
+ * Copyright (C) 2010 charybdis development team
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1.Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ * 2.Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "stdinc.h"
+#include "client.h"
+#include "common.h"
+#include "match.h"
+#include "hash.h"
+#include "ircd.h"
+#include "numeric.h"
+#include "send.h"
+#include "msg.h"
+#include "modules.h"
+
+static int me_certfp(struct Client *, struct Client *, int, const char **);
+
+struct Message certfp_msgtab = {
+       "CERTFP", 0, 0, 0, MFLG_SLOW,
+       {mg_unreg, mg_ignore, mg_ignore, mg_ignore, {me_certfp, 0}, mg_ignore}
+};
+
+mapi_clist_av1 certfp_clist[] = { &certfp_msgtab, NULL };
+
+DECLARE_MODULE_AV1(certfp, NULL, NULL, certfp_clist, NULL, NULL, "$Revision$");
+
+/*
+** me_certfp
+**      parv[1] = certfp string
+*/
+static int
+me_certfp(struct Client *client_p, struct Client *source_p, int parc, const char *parv[])
+{
+       if (!IsPerson(source_p))
+               return 0;
+       if (parc != 2)
+               return 0;
+
+       rb_free(source_p->certfp);
+       source_p->certfp = NULL;
+       if (!EmptyString(parv[1]))
+               source_p->certfp = rb_strdup(parv[1]);
+       return 0;
+}
index ca8dc23848522c87cc16d17c43771469f30de822..f4fb8854d06f04ccf27e0c7aab04cf44fb421cf9 100644 (file)
@@ -320,6 +320,11 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
        if(IsSSLClient(target_p))
                sendto_one_numeric(source_p, RPL_WHOISSECURE, form_str(RPL_WHOISSECURE),
                                   target_p->name);
+       if((source_p == target_p || IsOper(source_p)) &&
+                       target_p->certfp != NULL)
+               sendto_one_numeric(source_p, RPL_WHOISCERTFP,
+                               form_str(RPL_WHOISCERTFP),
+                               target_p->name, target_p->certfp);
 
        if(MyClient(target_p))
        {
index 428b799c4fc679a358bb2b302acf0f4e04d07976..b3f33c3fc27b60158870bdd6acc89b12a83ec95e 100644 (file)
@@ -256,6 +256,7 @@ free_client(struct Client *client_p)
        s_assert(&me != client_p);
        free_local_client(client_p);
        free_pre_client(client_p);
+       rb_free(client_p->certfp);
        rb_bh_free(client_heap, client_p);
 }
 
index 2602cb671e0d186c9c2f4b94ab8ec4460bf46b8f..af5ebab97bb152cbdb009d77718b7cf2d15a98d3 100644 (file)
@@ -297,7 +297,7 @@ static  const char *  replies[] = {
 /* 273 */       NULL,
 /* 274 */       NULL,
 /* 275 */       NULL,
-/* 276 */       NULL,
+/* 276 RPL_WHOISCERTFP */       "%s :has client certificate fingerprint %s",
 /* 277 */       NULL,
 /* 278 */       NULL,
 /* 279 */       NULL,
index 10c0fab05a6c971e8ec29e5ff052d2df6c21535f..a43c60c37f9e815fc36d7c969a07fdd3c77d555c 100644 (file)
@@ -506,6 +506,10 @@ burst_TS6(struct Client *client_p)
                                   IsIPSpoof(target_p) ? "0" : target_p->sockhost,
                                   target_p->id, target_p->info);
 
+               if(!EmptyString(target_p->certfp))
+                       sendto_one(client_p, ":%s ENCAP * CERTFP :%s",
+                                       use_id(target_p), target_p->certfp);
+
                if(!IsCapable(client_p, CAP_EUID))
                {
                        if(IsDynSpoof(target_p))
index 7d7bc1b94cc8af544c7754d7ceef750f6a5ecd97..b774e901964cb465beefb92755162e7768ae0e10 100644 (file)
@@ -633,6 +633,11 @@ introduce_client(struct Client *client_p, struct Client *source_p, struct User *
                      IsIPSpoof(source_p) ? "0" : sockhost,
                      source_p->id, source_p->info);
 
+       if(!EmptyString(source_p->certfp))
+               sendto_server(client_p, NULL, CAP_TS6, NOCAPS,
+                               ":%s ENCAP * CERTFP :%s",
+                               use_id(source_p), source_p->certfp);
+
        if (IsDynSpoof(source_p))
        {
                sendto_server(client_p, NULL, CAP_TS6, use_euid ? CAP_EUID : NOCAPS, ":%s ENCAP * REALHOST %s",
index a886b66699a2180d7a80c22ba86448de92b41cb9..178fde32b7f3c10e4575b4a700276bc3cee5d642 100644 (file)
@@ -408,7 +408,7 @@ ssl_process_certfp(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
        struct Client *client_p;
        int32_t fd;
        uint8_t *certfp;
-       char certfp_string[RB_SSL_CERTFP_LEN * 2 + 1];
+       char *certfp_string;
        int i;
 
        if(ctl_buf->buflen != 5 + RB_SSL_CERTFP_LEN)
@@ -419,10 +419,12 @@ ssl_process_certfp(ssl_ctl_t * ctl, ssl_ctl_buf_t * ctl_buf)
        client_p = find_cli_fd_hash(fd);
        if(client_p == NULL)
                return;
+       rb_free(client_p->certfp);
+       certfp_string = rb_malloc(RB_SSL_CERTFP_LEN * 2 + 1);
        for(i = 0; i < RB_SSL_CERTFP_LEN; i++)
                rb_snprintf(certfp_string + 2 * i, 3, "%02x",
                                certfp[i]);
-       sendto_one_notice(client_p, ":*** Your client certificate fingerprint is: %s", certfp_string);
+       client_p->certfp = certfp_string;
 }
 
 static void