summaryrefslogtreecommitdiffstats
path: root/src/journal/journal-gatewayd.c
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2012-11-25 23:26:15 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2013-01-18 07:15:54 +0100
commit858634ff0e158757dfd630f4da72e790a42e60dd (patch)
tree7365ac4df6681ce70f6c2e2edc810645eb3f3429 /src/journal/journal-gatewayd.c
parentjournal-gatewayd: unify two code paths (diff)
downloadsystemd-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.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) {