call[fs]cgi: Ensure exit handlers are not called in failing children.
[ashd.git] / src / ssl-gnutls.c
index 5247f2a..3eca0bb 100644 (file)
@@ -20,6 +20,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <fcntl.h>
+#include <dirent.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -349,6 +350,28 @@ static struct namedcreds *readncreds(char *file)
     return(nc);
 }
 
+static void readncdir(struct ncredbuf *buf, char *dir)
+{
+    DIR *d;
+    struct dirent *e;
+    size_t es;
+    
+    if((d = opendir(dir)) == NULL) {
+       flog(LOG_ERR, "ssl: could not read certificate directory %s: %s", dir, strerror(errno));
+       exit(1);
+    }
+    while((e = readdir(d)) != NULL) {
+       if(e->d_name[0] == '.')
+           continue;
+       if((es = strlen(e->d_name)) <= 4)
+           continue;
+       if(strcmp(e->d_name + es - 4, ".crt"))
+           continue;
+       bufadd(*buf, readncreds(sprintf3("%s/%s", dir, e->d_name)));
+    }
+    closedir(d);
+}
+
 void handlegnussl(int argc, char **argp, char **argv)
 {
     int i, ret, port, fd;
@@ -375,11 +398,24 @@ void handlegnussl(int argc, char **argp, char **argv)
            printf("\tcrl=CRL-FILE    [no default]\n");
            printf("\t\tThe name of a file to read revocation lists from.\n");
            printf("\t\tMay be given multiple times.\n");
+           printf("\tncert=CERT-FILE [no default]\n");
+           printf("\t\tThe name of a file to read a named certificate from,\n");
+           printf("\t\tfor use with SNI-enabled clients.\n");
+           printf("\t\tMay be given multiple times.\n");
+           printf("\tncertdir=DIR    [no default]\n");
+           printf("\t\tRead all *.crt files in the given directory as if they\n");
+           printf("\t\twere given with `ncert' options.\n");
+           printf("\t\tMay be given multiple times.\n");
            printf("\tport=PORT       [443]\n");
            printf("\t\tThe TCP port to listen on.\n");
            printf("\n");
            printf("\tAll X.509 data files must be PEM-encoded.\n");
-           printf("\tSee the manpage for information on specifying multiple\n\tcertificates to support SNI operation.\n");
+           printf("\tIf any certificates were given with `ncert' options, they will be\n");
+           printf("\tused if a client explicitly names one of them with a\n");
+           printf("\tserver-name indication. If a client indicates no server name,\n");
+           printf("\tor if a server-name indication does not match any given\n");
+           printf("\tcertificate, the certificate given with the `cert' option will\n");
+           printf("\tbe used instead.\n");
            exit(0);
        } else if(!strcmp(argp[i], "cert")) {
            crtfile = argv[i];
@@ -411,6 +447,8 @@ void handlegnussl(int argc, char **argp, char **argv)
            port = atoi(argv[i]);
        } else if(!strcmp(argp[i], "ncert")) {
            bufadd(ncreds, readncreds(argv[i]));
+       } else if(!strcmp(argp[i], "ncertdir")) {
+           readncdir(&ncreds, argv[i]);
        } else {
            flog(LOG_ERR, "unknown parameter `%s' to ssl handler", argp[i]);
            exit(1);