summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/journal/journal-gatewayd.c120
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) {