From fcfbe8a14c2a376d84e8f17be123a57373558071 Mon Sep 17 00:00:00 2001 From: C. McEnroe Date: Thu, 13 Feb 2020 01:39:25 -0500 Subject: Add -g for generating certificates Copied from pounce. --- catgirl.1 | 45 +++++++++++++++++++++++++++++++++++++++++++++ chat.c | 23 ++++++++++++++++++++++- configure | 2 ++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/catgirl.1 b/catgirl.1 index b7a9559..cd06200 100644 --- a/catgirl.1 +++ b/catgirl.1 @@ -27,6 +27,9 @@ .Op Fl w Ar pass .Op Ar config ... . +.Nm +.Fl g Ar cert +. .Sh DESCRIPTION The .Nm @@ -122,12 +125,22 @@ it is loaded with With .Fl e , authenticate using SASL EXTERNAL. +Certificates can be generated with +.Fl g . . .It Fl e , Cm sasl-external Authenticate using SASL EXTERNAL, also known as CertFP. The TLS client certificate is loaded with .Fl c . +For more information, see +.Sx Configuring CertFP . +. +.It Fl g Ar path +Generate a TLS client certificate using +.Xr openssl 1 +and write it to +.Ar path . . .It Fl h Ar host , Cm host = Ar host Connect to @@ -185,6 +198,38 @@ Log in with the server password .Ar pass . .El . +.Ss Configuring CertFP +.Bl -enum +.It +Generate a new TLS client certificate: +.Bd -literal -offset indent +catgirl -g ~/.config/catgirl/example.pem +.Ed +.It +Connect to the server using the certificate: +.Bd -literal -offset indent +cert = example.pem +# or: catgirl -c example.pem +.Ed +.It +Identify with services or use +.Cm sasl-plain , +then add the certificate fingerprint +to your account: +.Bd -literal -offset indent +/msg NickServ CERT ADD +.Ed +.It +Enable SASL EXTERNAL +to require successful authentication +when connecting: +.Bd -literal -offset indent +cert = example.pem +sasl-external +# or: catgirl -e -c example.pem +.Ed +.El +. .Sh COMMANDS Any unique prefix can be used to abbreviate a command. For example, diff --git a/chat.c b/chat.c index 284302d..c142bc9 100644 --- a/chat.c +++ b/chat.c @@ -25,12 +25,32 @@ #include #include #include +#include #include #include #include #include "chat.h" +#ifndef OPENSSL_BIN +#define OPENSSL_BIN "openssl" +#endif + +static void genCert(const char *path) { + const char *name = strrchr(path, '/'); + name = (name ? &name[1] : path); + char subj[256]; + snprintf(subj, sizeof(subj), "/CN=%.*s", (int)strcspn(name, "."), name); + umask(0066); + execlp( + OPENSSL_BIN, "openssl", "req", + "-x509", "-new", "-newkey", "rsa:4096", "-sha256", "-days", "3650", + "-nodes", "-subj", subj, "-out", path, "-keyout", path, + NULL + ); + err(EX_UNAVAILABLE, "openssl"); +} + char *idNames[IDCap] = { [None] = "", [Debug] = "", @@ -94,7 +114,7 @@ int main(int argc, char *argv[]) { const char *user = NULL; const char *real = NULL; - const char *Opts = "!C:H:N:O:RS:a:c:eh:j:k:n:p:r:s:u:vw:"; + const char *Opts = "!C:H:N:O:RS:a:c:eg:h:j:k:n:p:r:s:u:vw:"; const struct option LongOpts[] = { { "insecure", no_argument, NULL, '!' }, { "copy", required_argument, NULL, 'C' }, @@ -132,6 +152,7 @@ int main(int argc, char *argv[]) { break; case 'a': sasl = true; self.plain = optarg; break; case 'c': cert = optarg; break; case 'e': sasl = true; + break; case 'g': genCert(optarg); break; case 'h': host = optarg; break; case 'j': self.join = optarg; break; case 'k': priv = optarg; diff --git a/configure b/configure index 94545c4..b0f818f 100755 --- a/configure +++ b/configure @@ -10,6 +10,7 @@ case "$(uname)" in prefix=$(pkg query '%p' libressl) cat >config.mk <<-EOF CFLAGS += -I${prefix}/include + CFLAGS += -D'OPENSSL_BIN="${prefix}/bin/openssl"' LDFLAGS += -L${prefix}/lib EOF exit @@ -21,6 +22,7 @@ pkg-config --print-errors $libs cat >config.mk <