diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2012-11-25 23:26:15 +0100 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-01-18 07:15:54 +0100 |
commit | 858634ff0e158757dfd630f4da72e790a42e60dd (patch) | |
tree | 7365ac4df6681ce70f6c2e2edc810645eb3f3429 /src/journal/journal-gatewayd.c | |
parent | journal-gatewayd: unify two code paths (diff) | |
download | systemd-858634ff0e158757dfd630f4da72e790a42e60dd.tar.xz systemd-858634ff0e158757dfd630f4da72e790a42e60dd.zip |
journal-gatewayd: SSL support
For now the certificates are passed around as options to the
program. This might not be the most convenient under "production",
but makes for fairly easy testing.
Diffstat (limited to 'src/journal/journal-gatewayd.c')
-rw-r--r-- | src/journal/journal-gatewayd.c | 120 |
1 files changed, 105 insertions, 15 deletions
diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 9c33218822..6922ebcf9c 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -23,6 +23,7 @@ #include <string.h> #include <unistd.h> #include <fcntl.h> +#include <getopt.h> #include <microhttpd.h> @@ -32,6 +33,7 @@ #include "sd-daemon.h" #include "logs-show.h" #include "virt.h" +#include "build.h" typedef struct RequestMeta { sd_journal *journal; @@ -859,19 +861,96 @@ static int request_handler( return respond_error(connection, MHD_HTTP_NOT_FOUND, "Not found.\n"); } -int main(int argc, char *argv[]) { - struct MHD_Daemon *d = NULL; - int r = EXIT_FAILURE, n; +static char *key_pem = NULL; +static char *cert_pem = NULL; + +static int parse_argv(int argc, char *argv[]) { + enum { + ARG_VERSION = 0x100, + ARG_KEY, + ARG_CERT, + }; + + int r, c; + + static const struct option options[] = { + { "version", no_argument, NULL, ARG_VERSION }, + { "key", required_argument, NULL, ARG_KEY }, + { "cert", required_argument, NULL, ARG_CERT }, + { NULL, 0, NULL, 0 } + }; + + assert(argc >= 0); + assert(argv); + + while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) + switch(c) { + case ARG_VERSION: + puts(PACKAGE_STRING); + puts(SYSTEMD_FEATURES); + return 0; + + case ARG_KEY: + if (key_pem) { + log_error("Key file specified twice"); + return -EINVAL; + } + r = read_full_file(optarg, &key_pem, NULL); + if (r < 0) { + log_error("Failed to read key file: %s", strerror(-r)); + return r; + } + assert(key_pem); + break; - if (argc > 1) { + case ARG_CERT: + if (cert_pem) { + log_error("Certificate file specified twice"); + return -EINVAL; + } + r = read_full_file(optarg, &cert_pem, NULL); + if (r < 0) { + log_error("Failed to read certificate file: %s", strerror(-r)); + return r; + } + assert(cert_pem); + break; + + case '?': + return -EINVAL; + + default: + log_error("Unknown option code %c", c); + return -EINVAL; + } + + if (optind < argc) { log_error("This program does not take arguments."); - goto finish; + return -EINVAL; + } + + if (!!key_pem != !!cert_pem) { + log_error("Certificate and key files must be specified together"); + return -EINVAL; } + return 1; +} + +int main(int argc, char *argv[]) { + struct MHD_Daemon *d = NULL; + int r, n; + log_set_target(LOG_TARGET_AUTO); log_parse_environment(); log_open(); + r = parse_argv(argc, argv); + if (r < 0) + return EXIT_FAILURE; + if (r == 0) + return EXIT_SUCCESS; + n = sd_listen_fds(1); if (n < 0) { log_error("Failed to determine passed sockets: %s", strerror(-n)); @@ -884,18 +963,29 @@ int main(int argc, char *argv[]) { { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free, NULL }, { MHD_OPTION_END, 0, NULL }, + { MHD_OPTION_END, 0, NULL }, + { MHD_OPTION_END, 0, NULL }, { MHD_OPTION_END, 0, NULL }}; + int opts_pos = 1; + int flags = MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG; + if (n > 0) - opts[1] = (struct MHD_OptionItem) - {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START, NULL}; - - d = MHD_start_daemon( - MHD_USE_THREAD_PER_CONNECTION|MHD_USE_POLL|MHD_USE_DEBUG, - 19531, - NULL, NULL, - request_handler, NULL, - MHD_OPTION_ARRAY, opts, - MHD_OPTION_END); + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_LISTEN_SOCKET, SD_LISTEN_FDS_START}; + if (key_pem) { + assert(cert_pem); + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_HTTPS_MEM_KEY, 0, key_pem}; + opts[opts_pos++] = (struct MHD_OptionItem) + {MHD_OPTION_HTTPS_MEM_CERT, 0, cert_pem}; + flags |= MHD_USE_SSL; + } + + d = MHD_start_daemon(flags, 19531, + NULL, NULL, + request_handler, NULL, + MHD_OPTION_ARRAY, opts, + MHD_OPTION_END); } if (!d) { |