diff options
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | README.7 | 2 | ||||
-rw-r--r-- | bounce.c | 52 | ||||
-rw-r--r-- | bounce.h | 12 | ||||
-rw-r--r-- | cert.c | 95 | ||||
-rw-r--r-- | local.c | 62 |
6 files changed, 31 insertions, 193 deletions
diff --git a/Makefile b/Makefile index 39324d8..ac9c045 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,6 @@ LDLIBS.pounce = ${LDADD.crypt} ${LDADD.libtls} OBJS.calico += dispatch.o OBJS.pounce += bounce.o -OBJS.pounce += cert.o OBJS.pounce += client.o OBJS.pounce += config.o OBJS.pounce += local.o diff --git a/README.7 b/README.7 index 2ad9f67..63634f5 100644 --- a/README.7 +++ b/README.7 @@ -181,8 +181,6 @@ remote client connections state shared between clients .It Pa ring.c buffer between server and clients -.It Pa cert.c -sandboxed certificate reloading .It Pa config.c .Xr getopt_long 3 Ns -integrated configuration parsing diff --git a/bounce.c b/bounce.c index 2548626..7f0add5 100644 --- a/bounce.c +++ b/bounce.c @@ -354,44 +354,8 @@ int main(int argc, char *argv[]) { if (error) err(EX_OSERR, "pledge"); #endif - struct Cert localCA = { -1, -1, "" }; - if (caPath) { - error = 0; - const char *dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, caPath));) { - error = certOpen(&localCA, path); - if (!error) break; - } - if (error) err(EX_NOINPUT, "%s", caPath); - } - - const char *dirs; - struct Cert cert; - struct Cert priv; - dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, certPath));) { - error = certOpen(&cert, path); - if (!error) break; - } - if (error) err(EX_NOINPUT, "%s", certPath); - dirs = NULL; - for (const char *path; NULL != (path = configPath(&dirs, privPath));) { - error = certOpen(&priv, path); - if (!error) break; - } - if (error) err(EX_NOINPUT, "%s", privPath); - - FILE *certRead = certFile(&cert); - if (!certRead) err(EX_NOINPUT, "%s", certPath); - FILE *privRead = certFile(&priv); - if (!privRead) err(EX_NOINPUT, "%s", privPath); - FILE *caRead = (caPath ? certFile(&localCA) : NULL); - if (caPath && !caRead) err(EX_NOINPUT, "%s", caPath); - - localConfig(certRead, privRead, caRead, !clientPass); - fclose(certRead); - fclose(privRead); - if (caPath) fclose(caRead); + error = localConfig(certPath, privPath, caPath, !clientPass); + if (error) return EX_NOINPUT; int bind[8]; size_t binds = bindPath[0] @@ -506,17 +470,7 @@ int main(int argc, char *argv[]) { } if (signals[SIGUSR1]) { signals[SIGUSR1] = 0; - certRead = certFile(&cert); - privRead = certFile(&priv); - if (caPath) caRead = certFile(&localCA); - if (!certRead) warn("%s", certPath); - if (!privRead) warn("%s", privPath); - if (!caRead && caPath) warn("%s", caPath); - if (!certRead || !privRead || (!caRead && caPath)) continue; - localConfig(certRead, privRead, caRead, !clientPass); - fclose(certRead); - fclose(privRead); - if (caPath) fclose(caRead); + localConfig(certPath, privPath, caPath, !clientPass); } } diff --git a/bounce.h b/bounce.h index 4318410..295a448 100644 --- a/bounce.h +++ b/bounce.h @@ -183,7 +183,9 @@ void ringInfo(void); int ringSave(FILE *file); void ringLoad(FILE *file); -void localConfig(FILE *cert, FILE *priv, FILE *ca, bool require); +int localConfig( + const char *cert, const char *priv, const char *ca, bool require +); size_t localBind(int fds[], size_t cap, const char *host, const char *port); size_t localUnix(int fds[], size_t cap, const char *path); int localAccept(struct tls **tls, int bind); @@ -247,14 +249,6 @@ void stateSync(struct Client *client); const char *stateNick(void); const char *stateEcho(void); -struct Cert { - int parent; - int target; - char name[NAME_MAX]; -}; -int certOpen(struct Cert *cert, const char *path); -FILE *certFile(const struct Cert *cert); - const char *configPath(const char **dirs, const char *path); const char *dataPath(const char **dirs, const char *path); FILE *configOpen(const char *path, const char *mode); diff --git a/cert.c b/cert.c deleted file mode 100644 index 23c9ce8..0000000 --- a/cert.c +++ /dev/null @@ -1,95 +0,0 @@ -/* Copyright (C) 2020 C. McEnroe <june@causal.agency> - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - * - * Additional permission under GNU GPL version 3 section 7: - * - * If you modify this Program, or any covered work, by linking or - * combining it with OpenSSL (or a modified version of that library), - * containing parts covered by the terms of the OpenSSL License and the - * original SSLeay license, the licensors of this Program grant you - * additional permission to convey the resulting work. Corresponding - * Source for a non-source form of such a combination shall include the - * source code for the parts of OpenSSL used as well as that of the - * covered work. - */ - -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sysexits.h> -#include <unistd.h> - -#include "bounce.h" - -// This basically exists to work around certbot's symlinks from "live" into -// "archive" under capsicum. - -int certOpen(struct Cert *cert, const char *path) { - char buf[PATH_MAX]; - snprintf(buf, sizeof(buf), "%s", path); - - char *base = strrchr(buf, '/'); - if (base) { - *base = '\0'; - snprintf(cert->name, sizeof(cert->name), "%s", &base[1]); - cert->parent = open(buf, O_DIRECTORY); - } else { - snprintf(cert->name, sizeof(cert->name), "%s", path); - cert->parent = open(".", O_DIRECTORY); - } - if (cert->parent < 0) return -1; - - cert->target = cert->parent; - ssize_t len = readlinkat(cert->parent, cert->name, buf, sizeof(buf) - 1); - if (len < 0 && errno == EINVAL) return 0; - if (len < 0) return -1; - buf[len] = '\0'; - - base = strrchr(buf, '/'); - if (base) { - *base = '\0'; - cert->target = openat(cert->parent, buf, O_DIRECTORY); - if (cert->target < 0) return -1; - } - return 0; -} - -FILE *certFile(const struct Cert *cert) { - const char *name = cert->name; - - char buf[PATH_MAX]; - ssize_t len = readlinkat(cert->parent, cert->name, buf, sizeof(buf) - 1); - if (len < 0) { - if (errno != EINVAL) return NULL; - } else { - // XXX: Assume only the target base name has changed. - buf[len] = '\0'; - name = strrchr(buf, '/'); - if (name) { - name = &name[1]; - } else { - name = buf; - } - } - - int fd = openat(cert->target, name, O_RDONLY); - if (fd < 0) return NULL; - - return fdopen(fd, "r"); -} diff --git a/local.c b/local.c index 4f0cc5e..35286b3 100644 --- a/local.c +++ b/local.c @@ -33,7 +33,6 @@ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> -#include <sys/stat.h> #include <sys/un.h> #include <sysexits.h> #include <tls.h> @@ -43,54 +42,37 @@ static struct tls *server; -static byte *readFile(size_t *len, FILE *file) { - struct stat stat; - int error = fstat(fileno(file), &stat); - if (error) err(EX_IOERR, "fstat"); - - byte *buf = malloc(stat.st_size); - if (!buf) err(EX_OSERR, "malloc"); - - rewind(file); - *len = fread(buf, 1, stat.st_size, file); - if (ferror(file)) err(EX_IOERR, "fread"); - - return buf; -} - -void localConfig(FILE *cert, FILE *priv, FILE *ca, bool require) { +int localConfig( + const char *cert, const char *priv, const char *ca, bool require +) { if (!server) server = tls_server(); if (!server) errx(EX_SOFTWARE, "tls_server"); struct tls_config *config = tls_config_new(); if (!config) errx(EX_SOFTWARE, "tls_config_new"); - size_t len; - byte *buf = readFile(&len, cert); - int error = tls_config_set_cert_mem(config, buf, len); - if (error) { - errx(EX_CONFIG, "tls_config_set_cert_mem: %s", tls_config_error(config)); + int error; + const char *dirs = NULL; + for (const char *path; NULL != (path = configPath(&dirs, cert));) { + error = tls_config_set_cert_file(config, path); + if (!error) break; } - free(buf); + if (error) goto fail; - buf = readFile(&len, priv); - error = tls_config_set_key_mem(config, buf, len); - if (error) { - errx(EX_CONFIG, "tls_config_set_key_mem: %s", tls_config_error(config)); + dirs = NULL; + for (const char *path; NULL != (path = configPath(&dirs, priv));) { + error = tls_config_set_key_file(config, path); + if (!error) break; } - explicit_bzero(buf, len); - free(buf); + if (error) goto fail; if (ca) { - buf = readFile(&len, ca); - error = tls_config_set_ca_mem(config, buf, len); - if (error) { - errx( - EX_CONFIG, "tls_config_set_ca_mem: %s", - tls_config_error(config) - ); + dirs = NULL; + for (const char *path; NULL != (path = configPath(&dirs, ca));) { + error = tls_config_set_ca_file(config, path); + if (!error) break; } - free(buf); + if (error) goto fail; if (require) { tls_config_verify_client(config); } else { @@ -101,6 +83,12 @@ void localConfig(FILE *cert, FILE *priv, FILE *ca, bool require) { error = tls_configure(server, config); if (error) errx(EX_SOFTWARE, "tls_configure: %s", tls_error(server)); tls_config_free(config); + return 0; + +fail: + warnx("%s", tls_config_error(config)); + tls_config_free(config); + return -1; } size_t localBind(int fds[], size_t cap, const char *host, const char *port) { |