summary refs log tree commit diff
path: root/bounce.c
diff options
context:
space:
mode:
authorJune McEnroe <june@causal.agency>2020-01-12 18:07:54 -0500
committerJune McEnroe <june@causal.agency>2020-01-12 18:07:54 -0500
commit5e6094e437a5437ceb6b083d16995ea629a4d720 (patch)
tree34ad1b244212caab1b832a6243988e388282434a /bounce.c
parentAdd a vendor capability for passive clients (diff)
downloadpounce-5e6094e437a5437ceb6b083d16995ea629a4d720.tar.gz
pounce-5e6094e437a5437ceb6b083d16995ea629a4d720.zip
Add option to set local client CA
This is a little bit messy. Allows setting either -A or -W or both.
Implements SASL EXTERNAL for clients that expect that when connecting
with a client certificate.

Need to test that reloading still works inside capsicum, since I suspect
that rewind call may be blocked.
Diffstat (limited to '')
-rw-r--r--bounce.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/bounce.c b/bounce.c
index 89b2ff1..7ea1c3f 100644
--- a/bounce.c
+++ b/bounce.c
@@ -215,6 +215,7 @@ int main(int argc, char *argv[]) {
 	char bindPath[PATH_MAX] = "";
 	char certPath[PATH_MAX] = "";
 	char privPath[PATH_MAX] = "";
+	const char *caPath = NULL;
 
 	bool insecure = false;
 	const char *clientCert = NULL;
@@ -232,9 +233,10 @@ int main(int argc, char *argv[]) {
 	const char *join = NULL;
 	const char *quit = "connection reset by purr";
 
-	const char *Opts = "!C:H:K:NP:U:W:a:c:ef:g:h:j:k:n:p:q:r:s:u:vw:xy:";
+	const char *Opts = "!A:C:H:K:NP:U:W:a:c:ef:g:h:j:k:n:p:q:r:s:u:vw:xy:";
 	const struct option LongOpts[] = {
 		{ "insecure", no_argument, NULL, '!' },
+		{ "client-ca", required_argument, NULL, 'A' },
 		{ "cert", required_argument, NULL, 'C' },
 		{ "bind-host", required_argument, NULL, 'H' },
 		{ "priv", required_argument, NULL, 'K' },
@@ -265,6 +267,7 @@ int main(int argc, char *argv[]) {
 	while (0 < (opt = getopt_config(argc, argv, Opts, LongOpts, NULL))) {
 		switch (opt) {
 			break; case '!': insecure = true;
+			break; case 'A': clientCA = true; caPath = optarg;
 			break; case 'C': strlcpy(certPath, optarg, sizeof(certPath));
 			break; case 'H': bindHost = optarg;
 			break; case 'K': strlcpy(privPath, optarg, sizeof(privPath));
@@ -331,11 +334,17 @@ int main(int argc, char *argv[]) {
 	ringAlloc(ringSize);
 	if (savePath) saveLoad(savePath);
 
+	FILE *localCA = NULL;
+	if (caPath) {
+		localCA = fopen(caPath, "r");
+		if (!localCA) err(EX_NOINPUT, "%s", caPath);
+	}
+
 	struct SplitPath certSplit = splitPath(certPath);
 	struct SplitPath privSplit = splitPath(privPath);
 	FILE *cert = splitOpen(certSplit);
 	FILE *priv = splitOpen(privSplit);
-	localConfig(cert, priv);
+	localConfig(cert, priv, localCA, !clientPass);
 	fclose(cert);
 	fclose(priv);
 
@@ -359,6 +368,7 @@ int main(int argc, char *argv[]) {
 	cap_rights_merge(&bindRights, &sockRights);
 
 	if (saveFile) capLimit(fileno(saveFile), &saveRights);
+	if (localCA) capLimit(fileno(localCA), &fileRights);
 	capLimitSplit(certSplit, &fileRights);
 	capLimitSplit(privSplit, &fileRights);
 	for (size_t i = 0; i < binds; ++i) {
@@ -401,7 +411,7 @@ int main(int argc, char *argv[]) {
 		if (signals[SIGUSR1]) {
 			cert = splitOpen(certSplit);
 			priv = splitOpen(privSplit);
-			localConfig(cert, priv);
+			localConfig(cert, priv, localCA, !clientPass);
 			fclose(cert);
 			fclose(priv);
 			signals[SIGUSR1] = 0;