about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2019-11-06 01:56:39 -0500
committerJune McEnroe <june@causal.agency>2019-11-06 01:56:39 -0500
commit97def9aafbb2ff374bf9766e200ec184f4dae556 (patch)
treee64e6c946c6c8528dd88650e6cfe4292185f0a0d
parentGive SYNOPSIS Ars more informative names (diff)
downloadpounce-97def9aafbb2ff374bf9766e200ec184f4dae556.tar.gz
pounce-97def9aafbb2ff374bf9766e200ec184f4dae556.zip
Add flag to generate a client certificate
This is essentially the command freenode tells you to run:
<https://freenode.net/kb/answer/certfp>.
-rw-r--r--bounce.c18
-rw-r--r--pounce.115
2 files changed, 31 insertions, 2 deletions
diff --git a/bounce.c b/bounce.c
index 4e5c663..71416df 100644
--- a/bounce.c
+++ b/bounce.c
@@ -50,6 +50,21 @@ static void hashPass(void) {
 	printf("%s\n", crypt(pass, salt));
 }
 
+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", "openssl", "req",
+		"-x509", "-new", "-newkey", "rsa:4096", "-sha256", "-days", "1000",
+		"-nodes", "-subj", subj, "-out", path, "-keyout", path,
+		NULL
+	);
+	err(EX_UNAVAILABLE, "openssl");
+}
+
 static size_t parseSize(const char *str) {
 	char *rest;
 	size_t size = strtoull(str, &rest, 0);
@@ -216,7 +231,7 @@ int main(int argc, char *argv[]) {
 	const char *away = "pounced :3";
 	const char *quit = "connection reset by purr";
 
-	const char *Opts = "!A:C:H:K:NP:Q:U:W:a:c:ef:h:j:k:n:p:r:s:u:vw:x";
+	const char *Opts = "!A:C:H:K:NP:Q:U:W:a:c:ef:g:h:j:k:n:p:r:s:u:vw:x";
 	const struct option LongOpts[] = {
 		{ "insecure", no_argument, NULL, '!' },
 		{ "away", required_argument, NULL, 'A' },
@@ -262,6 +277,7 @@ int main(int argc, char *argv[]) {
 			break; case 'c': clientCert = optarg;
 			break; case 'e': sasl = true;
 			break; case 'f': savePath = optarg;
+			break; case 'g': genCert(optarg);
 			break; case 'h': host = optarg;
 			break; case 'j': join = optarg;
 			break; case 'k': clientPriv = optarg;
diff --git a/pounce.1 b/pounce.1
index 2058052..4db3535 100644
--- a/pounce.1
+++ b/pounce.1
@@ -30,7 +30,12 @@
 .Op Fl u Ar user
 .Op Fl w Ar pass
 .Op Ar config ...
-.Nm Fl x
+.
+.Nm
+.Fl g Ar cert
+.
+.Nm
+.Fl x
 .
 .Sh DESCRIPTION
 The
@@ -152,6 +157,8 @@ 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.
@@ -167,6 +174,12 @@ On shutdown,
 save the contents of the buffer to
 .Ar path .
 .
+.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
 .Ar host .