Commits

Jilles Tjoelker  committed 9d76985

Pass certfp to other servers and show it in whois. Do not show it on connect.

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.

  • Participants
  • Parent commits 7155b98

Comments (0)

Files changed (10)

File include/client.h

 	struct PreClient *preClient;
 
 	time_t large_ctcp_sent; /* ctcp to large group sent, relax flood checks */
+	char *certfp; /* client certificate fingerprint */
 };
 
 struct LocalUser

File include/numeric.h

 
 #define RPL_PRIVS            270 /* from ircu */
 
+#define RPL_WHOISCERTFP      276 /* from oftc-hybrid */
+
 #define RPL_ACCEPTLIST	     281
 #define RPL_ENDOFACCEPT      282
 

File modules/Makefile.in

   m_away.c \
   m_cap.c \
   m_capab.c \
+  m_certfp.c \
   m_challenge.c \
   m_chghost.c \
   m_close.c \

File modules/m_certfp.c

+/*
+ * 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;
+}

File modules/m_whois.c

 	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))
 	{

File src/client.c

 	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);
 }
 

File src/messages.tab

 /* 273 */       NULL,
 /* 274 */       NULL,
 /* 275 */       NULL,
-/* 276 */       NULL,
+/* 276 RPL_WHOISCERTFP */       "%s :has client certificate fingerprint %s",
 /* 277 */       NULL,
 /* 278 */       NULL,
 /* 279 */       NULL,

File src/s_serv.c

 				   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))

File src/s_user.c

 		      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",

File src/sslproc.c

 	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)
 	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