File: | build-scan/../src/journal-remote/journal-remote-main.c |
Warning: | line 918, column 36 Null pointer passed to 1st parameter expecting 'nonnull' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
2 | ||||
3 | #include <getopt.h> | |||
4 | #include <unistd.h> | |||
5 | ||||
6 | #include "sd-daemon.h" | |||
7 | ||||
8 | #include "conf-parser.h" | |||
9 | #include "def.h" | |||
10 | #include "fd-util.h" | |||
11 | #include "fileio.h" | |||
12 | #include "journal-remote-write.h" | |||
13 | #include "journal-remote.h" | |||
14 | #include "process-util.h" | |||
15 | #include "signal-util.h" | |||
16 | #include "socket-util.h" | |||
17 | #include "stat-util.h" | |||
18 | #include "string-table.h" | |||
19 | #include "strv.h" | |||
20 | ||||
21 | #define PRIV_KEY_FILE"/etc/ssl" "/private/journal-remote.pem" CERTIFICATE_ROOT"/etc/ssl" "/private/journal-remote.pem" | |||
22 | #define CERT_FILE"/etc/ssl" "/certs/journal-remote.pem" CERTIFICATE_ROOT"/etc/ssl" "/certs/journal-remote.pem" | |||
23 | #define TRUST_FILE"/etc/ssl" "/ca/trusted.pem" CERTIFICATE_ROOT"/etc/ssl" "/ca/trusted.pem" | |||
24 | ||||
25 | static char* arg_url = NULL((void*)0); | |||
26 | static char* arg_getter = NULL((void*)0); | |||
27 | static char* arg_listen_raw = NULL((void*)0); | |||
28 | static char* arg_listen_http = NULL((void*)0); | |||
29 | static char* arg_listen_https = NULL((void*)0); | |||
30 | static char** arg_files = NULL((void*)0); | |||
31 | static int arg_compress = true1; | |||
32 | static int arg_seal = false0; | |||
33 | static int http_socket = -1, https_socket = -1; | |||
34 | static char** arg_gnutls_log = NULL((void*)0); | |||
35 | ||||
36 | static JournalWriteSplitMode arg_split_mode = _JOURNAL_WRITE_SPLIT_INVALID; | |||
37 | static char* arg_output = NULL((void*)0); | |||
38 | ||||
39 | static char *arg_key = NULL((void*)0); | |||
40 | static char *arg_cert = NULL((void*)0); | |||
41 | static char *arg_trust = NULL((void*)0); | |||
42 | static bool_Bool arg_trust_all = false0; | |||
43 | ||||
44 | static const char* const journal_write_split_mode_table[_JOURNAL_WRITE_SPLIT_MAX] = { | |||
45 | [JOURNAL_WRITE_SPLIT_NONE] = "none", | |||
46 | [JOURNAL_WRITE_SPLIT_HOST] = "host", | |||
47 | }; | |||
48 | ||||
49 | DEFINE_PRIVATE_STRING_TABLE_LOOKUP(journal_write_split_mode, JournalWriteSplitMode)static const char *journal_write_split_mode_to_string(JournalWriteSplitMode i) { if (i < 0 || i >= (JournalWriteSplitMode) __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (journal_write_split_mode_table), typeof(&*(journal_write_split_mode_table ))), sizeof(journal_write_split_mode_table)/sizeof((journal_write_split_mode_table )[0]), ((void)0)))) return ((void*)0); return journal_write_split_mode_table [i]; } static JournalWriteSplitMode journal_write_split_mode_from_string (const char *s) { return (JournalWriteSplitMode) string_table_lookup (journal_write_split_mode_table, __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(journal_write_split_mode_table ), typeof(&*(journal_write_split_mode_table))), sizeof(journal_write_split_mode_table )/sizeof((journal_write_split_mode_table)[0]), ((void)0))), s ); }; | |||
50 | static DEFINE_CONFIG_PARSE_ENUM(config_parse_write_split_mode,int config_parse_write_split_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line , const char *lvalue, int ltype, const char *rvalue, void *data , void *userdata) { JournalWriteSplitMode *i = data, x; do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/journal-remote/journal-remote-main.c" , 53, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(lvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("lvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(rvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("rvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "data"), "../src/journal-remote/journal-remote-main.c", 53, __PRETTY_FUNCTION__ ); } while (0); x = journal_write_split_mode_from_string(rvalue ); if (x < 0) { ({ int _level = (3), _e = (0); (log_get_max_level_realm (LOG_REALM_SYSTEMD) >= ((_level) & 0x07)) ? log_syntax_internal (unit, _level, filename, line, _e, "../src/journal-remote/journal-remote-main.c" , 53, __func__, "Failed to parse split mode setting" ", ignoring: %s" , rvalue) : -abs(_e); }); return 0; } *i = x; return 0; } | |||
51 | journal_write_split_mode,int config_parse_write_split_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line , const char *lvalue, int ltype, const char *rvalue, void *data , void *userdata) { JournalWriteSplitMode *i = data, x; do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/journal-remote/journal-remote-main.c" , 53, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(lvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("lvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(rvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("rvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "data"), "../src/journal-remote/journal-remote-main.c", 53, __PRETTY_FUNCTION__ ); } while (0); x = journal_write_split_mode_from_string(rvalue ); if (x < 0) { ({ int _level = (3), _e = (0); (log_get_max_level_realm (LOG_REALM_SYSTEMD) >= ((_level) & 0x07)) ? log_syntax_internal (unit, _level, filename, line, _e, "../src/journal-remote/journal-remote-main.c" , 53, __func__, "Failed to parse split mode setting" ", ignoring: %s" , rvalue) : -abs(_e); }); return 0; } *i = x; return 0; } | |||
52 | JournalWriteSplitMode,int config_parse_write_split_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line , const char *lvalue, int ltype, const char *rvalue, void *data , void *userdata) { JournalWriteSplitMode *i = data, x; do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/journal-remote/journal-remote-main.c" , 53, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(lvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("lvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(rvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("rvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "data"), "../src/journal-remote/journal-remote-main.c", 53, __PRETTY_FUNCTION__ ); } while (0); x = journal_write_split_mode_from_string(rvalue ); if (x < 0) { ({ int _level = (3), _e = (0); (log_get_max_level_realm (LOG_REALM_SYSTEMD) >= ((_level) & 0x07)) ? log_syntax_internal (unit, _level, filename, line, _e, "../src/journal-remote/journal-remote-main.c" , 53, __func__, "Failed to parse split mode setting" ", ignoring: %s" , rvalue) : -abs(_e); }); return 0; } *i = x; return 0; } | |||
53 | "Failed to parse split mode setting")int config_parse_write_split_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line , const char *lvalue, int ltype, const char *rvalue, void *data , void *userdata) { JournalWriteSplitMode *i = data, x; do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/journal-remote/journal-remote-main.c" , 53, __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(lvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("lvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(rvalue)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("rvalue"), "../src/journal-remote/journal-remote-main.c", 53 , __PRETTY_FUNCTION__); } while (0); do { if ((__builtin_expect (!!(!(data)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ( "data"), "../src/journal-remote/journal-remote-main.c", 53, __PRETTY_FUNCTION__ ); } while (0); x = journal_write_split_mode_from_string(rvalue ); if (x < 0) { ({ int _level = (3), _e = (0); (log_get_max_level_realm (LOG_REALM_SYSTEMD) >= ((_level) & 0x07)) ? log_syntax_internal (unit, _level, filename, line, _e, "../src/journal-remote/journal-remote-main.c" , 53, __func__, "Failed to parse split mode setting" ", ignoring: %s" , rvalue) : -abs(_e); }); return 0; } *i = x; return 0; }; | |||
54 | ||||
55 | /********************************************************************** | |||
56 | ********************************************************************** | |||
57 | **********************************************************************/ | |||
58 | ||||
59 | static int spawn_child(const char* child, char** argv) { | |||
60 | pid_t child_pid; | |||
61 | int fd[2], r; | |||
62 | ||||
63 | if (pipe(fd) < 0) | |||
64 | return log_error_errno(errno, "Failed to create pager pipe: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal-remote/journal-remote-main.c" , 64, __func__, "Failed to create pager pipe: %m") : -abs(_e) ; }); | |||
65 | ||||
66 | r = safe_fork("(remote)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &child_pid); | |||
67 | if (r < 0) { | |||
68 | safe_close_pair(fd); | |||
69 | return r; | |||
70 | } | |||
71 | ||||
72 | /* In the child */ | |||
73 | if (r == 0) { | |||
74 | safe_close(fd[0]); | |||
75 | ||||
76 | r = rearrange_stdio(STDIN_FILENO0, fd[1], STDERR_FILENO2); | |||
77 | if (r < 0) { | |||
78 | log_error_errno(r, "Failed to dup pipe to stdout: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 78, __func__ , "Failed to dup pipe to stdout: %m") : -abs(_e); }); | |||
79 | _exit(EXIT_FAILURE1); | |||
80 | } | |||
81 | ||||
82 | execvp(child, argv); | |||
83 | log_error_errno(errno, "Failed to exec child %s: %m", child)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal-remote/journal-remote-main.c" , 83, __func__, "Failed to exec child %s: %m", child) : -abs( _e); }); | |||
84 | _exit(EXIT_FAILURE1); | |||
85 | } | |||
86 | ||||
87 | safe_close(fd[1]); | |||
88 | ||||
89 | r = fd_nonblock(fd[0], true1); | |||
90 | if (r < 0) | |||
91 | log_warning_errno(errno, "Failed to set child pipe to non-blocking: %m")({ int _level = ((4)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal-remote/journal-remote-main.c" , 91, __func__, "Failed to set child pipe to non-blocking: %m" ) : -abs(_e); }); | |||
92 | ||||
93 | return fd[0]; | |||
94 | } | |||
95 | ||||
96 | static int spawn_curl(const char* url) { | |||
97 | char **argv = STRV_MAKE("curl",((char**) ((const char*[]) { "curl", "-HAccept: application/vnd.fdo.journal" , "--silent", "--show-error", url, ((void*)0) })) | |||
98 | "-HAccept: application/vnd.fdo.journal",((char**) ((const char*[]) { "curl", "-HAccept: application/vnd.fdo.journal" , "--silent", "--show-error", url, ((void*)0) })) | |||
99 | "--silent",((char**) ((const char*[]) { "curl", "-HAccept: application/vnd.fdo.journal" , "--silent", "--show-error", url, ((void*)0) })) | |||
100 | "--show-error",((char**) ((const char*[]) { "curl", "-HAccept: application/vnd.fdo.journal" , "--silent", "--show-error", url, ((void*)0) })) | |||
101 | url)((char**) ((const char*[]) { "curl", "-HAccept: application/vnd.fdo.journal" , "--silent", "--show-error", url, ((void*)0) })); | |||
102 | int r; | |||
103 | ||||
104 | r = spawn_child("curl", argv); | |||
105 | if (r < 0) | |||
106 | log_error_errno(r, "Failed to spawn curl: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 106, __func__ , "Failed to spawn curl: %m") : -abs(_e); }); | |||
107 | return r; | |||
108 | } | |||
109 | ||||
110 | static int spawn_getter(const char *getter) { | |||
111 | int r; | |||
112 | _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **words = NULL((void*)0); | |||
113 | ||||
114 | assert(getter)do { if ((__builtin_expect(!!(!(getter)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("getter"), "../src/journal-remote/journal-remote-main.c" , 114, __PRETTY_FUNCTION__); } while (0); | |||
115 | r = strv_split_extract(&words, getter, WHITESPACE" \t\n\r", EXTRACT_QUOTES); | |||
116 | if (r < 0) | |||
117 | return log_error_errno(r, "Failed to split getter option: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 117, __func__ , "Failed to split getter option: %m") : -abs(_e); }); | |||
118 | ||||
119 | r = spawn_child(words[0], words); | |||
120 | if (r < 0) | |||
121 | log_error_errno(r, "Failed to spawn getter %s: %m", getter)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 121, __func__ , "Failed to spawn getter %s: %m", getter) : -abs(_e); }); | |||
122 | ||||
123 | return r; | |||
124 | } | |||
125 | ||||
126 | /********************************************************************** | |||
127 | ********************************************************************** | |||
128 | **********************************************************************/ | |||
129 | ||||
130 | static int null_timer_event_handler(sd_event_source *s, | |||
131 | uint64_t usec, | |||
132 | void *userdata); | |||
133 | static int dispatch_http_event(sd_event_source *event, | |||
134 | int fd, | |||
135 | uint32_t revents, | |||
136 | void *userdata); | |||
137 | ||||
138 | static int request_meta(void **connection_cls, int fd, char *hostname) { | |||
139 | RemoteSource *source; | |||
140 | Writer *writer; | |||
141 | int r; | |||
142 | ||||
143 | assert(connection_cls)do { if ((__builtin_expect(!!(!(connection_cls)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("connection_cls"), "../src/journal-remote/journal-remote-main.c" , 143, __PRETTY_FUNCTION__); } while (0); | |||
144 | if (*connection_cls) | |||
145 | return 0; | |||
146 | ||||
147 | r = journal_remote_get_writer(journal_remote_server_global, hostname, &writer); | |||
148 | if (r < 0) | |||
149 | return log_warning_errno(r, "Failed to get writer for source %s: %m",({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 150, __func__ , "Failed to get writer for source %s: %m", hostname) : -abs( _e); }) | |||
150 | hostname)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 150, __func__ , "Failed to get writer for source %s: %m", hostname) : -abs( _e); }); | |||
151 | ||||
152 | source = source_new(fd, true1, hostname, writer); | |||
153 | if (!source) { | |||
154 | writer_unref(writer); | |||
155 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 155, __func__); | |||
156 | } | |||
157 | ||||
158 | log_debug("Added RemoteSource as connection metadata %p", source)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 158, __func__ , "Added RemoteSource as connection metadata %p", source) : - abs(_e); }); | |||
159 | ||||
160 | *connection_cls = source; | |||
161 | return 0; | |||
162 | } | |||
163 | ||||
164 | static void request_meta_free(void *cls, | |||
165 | struct MHD_Connection *connection, | |||
166 | void **connection_cls, | |||
167 | enum MHD_RequestTerminationCode toe) { | |||
168 | RemoteSource *s; | |||
169 | ||||
170 | assert(connection_cls)do { if ((__builtin_expect(!!(!(connection_cls)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("connection_cls"), "../src/journal-remote/journal-remote-main.c" , 170, __PRETTY_FUNCTION__); } while (0); | |||
171 | s = *connection_cls; | |||
172 | ||||
173 | if (s) { | |||
174 | log_debug("Cleaning up connection metadata %p", s)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 174, __func__ , "Cleaning up connection metadata %p", s) : -abs(_e); }); | |||
175 | source_free(s); | |||
176 | *connection_cls = NULL((void*)0); | |||
177 | } | |||
178 | } | |||
179 | ||||
180 | static int process_http_upload( | |||
181 | struct MHD_Connection *connection, | |||
182 | const char *upload_data, | |||
183 | size_t *upload_data_size, | |||
184 | RemoteSource *source) { | |||
185 | ||||
186 | bool_Bool finished = false0; | |||
187 | size_t remaining; | |||
188 | int r; | |||
189 | ||||
190 | assert(source)do { if ((__builtin_expect(!!(!(source)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("source"), "../src/journal-remote/journal-remote-main.c" , 190, __PRETTY_FUNCTION__); } while (0); | |||
191 | ||||
192 | log_trace("%s: connection %p, %zu bytes",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 193, __func__ , "%s: connection %p, %zu bytes", __func__, connection, *upload_data_size ) : -abs(_e); }) | |||
193 | __func__, connection, *upload_data_size)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 193, __func__ , "%s: connection %p, %zu bytes", __func__, connection, *upload_data_size ) : -abs(_e); }); | |||
194 | ||||
195 | if (*upload_data_size) { | |||
196 | log_trace("Received %zu bytes", *upload_data_size)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 196, __func__ , "Received %zu bytes", *upload_data_size) : -abs(_e); }); | |||
197 | ||||
198 | r = journal_importer_push_data(&source->importer, | |||
199 | upload_data, *upload_data_size); | |||
200 | if (r < 0) | |||
201 | return mhd_respond_oom(connection); | |||
202 | ||||
203 | *upload_data_size = 0; | |||
204 | } else | |||
205 | finished = true1; | |||
206 | ||||
207 | for (;;) { | |||
208 | r = process_source(source, | |||
209 | journal_remote_server_global->compress, | |||
210 | journal_remote_server_global->seal); | |||
211 | if (r == -EAGAIN11) | |||
212 | break; | |||
213 | if (r < 0) { | |||
214 | if (r == -ENOBUFS105) | |||
215 | log_warning_errno(r, "Entry is above the maximum of %u, aborting connection %p.",({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 216, __func__ , "Entry is above the maximum of %u, aborting connection %p." , (1024*1024*768u), connection) : -abs(_e); }) | |||
216 | DATA_SIZE_MAX, connection)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 216, __func__ , "Entry is above the maximum of %u, aborting connection %p." , (1024*1024*768u), connection) : -abs(_e); }); | |||
217 | else if (r == -E2BIG7) | |||
218 | log_warning_errno(r, "Entry with more fields than the maximum of %u, aborting connection %p.",({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 219, __func__ , "Entry with more fields than the maximum of %u, aborting connection %p." , 1024, connection) : -abs(_e); }) | |||
219 | ENTRY_FIELD_COUNT_MAX, connection)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 219, __func__ , "Entry with more fields than the maximum of %u, aborting connection %p." , 1024, connection) : -abs(_e); }); | |||
220 | else | |||
221 | log_warning_errno(r, "Failed to process data, aborting connection %p: %m",({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 222, __func__ , "Failed to process data, aborting connection %p: %m", connection ) : -abs(_e); }) | |||
222 | connection)({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 222, __func__ , "Failed to process data, aborting connection %p: %m", connection ) : -abs(_e); }); | |||
223 | return MHD_NO; | |||
224 | } | |||
225 | } | |||
226 | ||||
227 | if (!finished) | |||
228 | return MHD_YES; | |||
229 | ||||
230 | /* The upload is finished */ | |||
231 | ||||
232 | remaining = journal_importer_bytes_remaining(&source->importer); | |||
233 | if (remaining > 0) { | |||
234 | log_warning("Premature EOF byte. %zu bytes lost.", remaining)({ int _level = (((4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 234, __func__ , "Premature EOF byte. %zu bytes lost.", remaining) : -abs(_e ); }); | |||
235 | return mhd_respondf(connection, | |||
236 | 0, MHD_HTTP_EXPECTATION_FAILED417, | |||
237 | "Premature EOF. %zu bytes of trailing data not processed.", | |||
238 | remaining); | |||
239 | } | |||
240 | ||||
241 | return mhd_respond(connection, MHD_HTTP_ACCEPTED202, "OK."); | |||
242 | }; | |||
243 | ||||
244 | static mhd_resultenum MHD_Result request_handler( | |||
245 | void *cls, | |||
246 | struct MHD_Connection *connection, | |||
247 | const char *url, | |||
248 | const char *method, | |||
249 | const char *version, | |||
250 | const char *upload_data, | |||
251 | size_t *upload_data_size, | |||
252 | void **connection_cls) { | |||
253 | ||||
254 | const char *header; | |||
255 | int r, code, fd; | |||
256 | _cleanup_free___attribute__((cleanup(freep))) char *hostname = NULL((void*)0); | |||
257 | bool_Bool chunked = false0; | |||
258 | size_t len; | |||
259 | ||||
260 | assert(connection)do { if ((__builtin_expect(!!(!(connection)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("connection"), "../src/journal-remote/journal-remote-main.c" , 260, __PRETTY_FUNCTION__); } while (0); | |||
261 | assert(connection_cls)do { if ((__builtin_expect(!!(!(connection_cls)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("connection_cls"), "../src/journal-remote/journal-remote-main.c" , 261, __PRETTY_FUNCTION__); } while (0); | |||
262 | assert(url)do { if ((__builtin_expect(!!(!(url)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("url"), "../src/journal-remote/journal-remote-main.c" , 262, __PRETTY_FUNCTION__); } while (0); | |||
263 | assert(method)do { if ((__builtin_expect(!!(!(method)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("method"), "../src/journal-remote/journal-remote-main.c" , 263, __PRETTY_FUNCTION__); } while (0); | |||
264 | ||||
265 | log_trace("Handling a connection %s %s %s", method, url, version)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 265, __func__ , "Handling a connection %s %s %s", method, url, version) : - abs(_e); }); | |||
266 | ||||
267 | if (*connection_cls) | |||
268 | return process_http_upload(connection, | |||
269 | upload_data, upload_data_size, | |||
270 | *connection_cls); | |||
271 | ||||
272 | if (!streq(method, "POST")(strcmp((method),("POST")) == 0)) | |||
273 | return mhd_respond(connection, MHD_HTTP_NOT_ACCEPTABLE406, "Unsupported method."); | |||
274 | ||||
275 | if (!streq(url, "/upload")(strcmp((url),("/upload")) == 0)) | |||
276 | return mhd_respond(connection, MHD_HTTP_NOT_FOUND404, "Not found."); | |||
277 | ||||
278 | header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Type"); | |||
279 | if (!header || !streq(header, "application/vnd.fdo.journal")(strcmp((header),("application/vnd.fdo.journal")) == 0)) | |||
280 | return mhd_respond(connection, MHD_HTTP_UNSUPPORTED_MEDIA_TYPE415, | |||
281 | "Content-Type: application/vnd.fdo.journal is required."); | |||
282 | ||||
283 | header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Transfer-Encoding"); | |||
284 | if (header) { | |||
285 | if (!strcaseeq(header, "chunked")(strcasecmp((header),("chunked")) == 0)) | |||
286 | return mhd_respondf(connection, 0, MHD_HTTP_BAD_REQUEST400, | |||
287 | "Unsupported Transfer-Encoding type: %s", header); | |||
288 | ||||
289 | chunked = true1; | |||
290 | } | |||
291 | ||||
292 | header = MHD_lookup_connection_value(connection, MHD_HEADER_KIND, "Content-Length"); | |||
293 | if (header) { | |||
294 | if (chunked) | |||
295 | return mhd_respond(connection, MHD_HTTP_BAD_REQUEST400, | |||
296 | "Content-Length must not specified when Transfer-Encoding type is 'chuncked'"); | |||
297 | ||||
298 | r = safe_atozu(header, &len); | |||
299 | if (r < 0) | |||
300 | return mhd_respondf(connection, r, MHD_HTTP_LENGTH_REQUIRED411, | |||
301 | "Content-Length: %s cannot be parsed: %m", header); | |||
302 | ||||
303 | if (len > ENTRY_SIZE_MAX(1024*1024*770u)) | |||
304 | /* When serialized, an entry of maximum size might be slightly larger, | |||
305 | * so this does not correspond exactly to the limit in journald. Oh well. | |||
306 | */ | |||
307 | return mhd_respondf(connection, 0, MHD_HTTP_PAYLOAD_TOO_LARGE413, | |||
308 | "Payload larger than maximum size of %u bytes", ENTRY_SIZE_MAX(1024*1024*770u)); | |||
309 | } | |||
310 | ||||
311 | { | |||
312 | const union MHD_ConnectionInfo *ci; | |||
313 | ||||
314 | ci = MHD_get_connection_info(connection, | |||
315 | MHD_CONNECTION_INFO_CONNECTION_FD); | |||
316 | if (!ci) { | |||
317 | log_error("MHD_get_connection_info failed: cannot get remote fd")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 317, __func__ , "MHD_get_connection_info failed: cannot get remote fd") : - abs(_e); }); | |||
318 | return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR500, | |||
319 | "Cannot check remote address."); | |||
320 | } | |||
321 | ||||
322 | fd = ci->connect_fd; | |||
323 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal-remote/journal-remote-main.c" , 323, __PRETTY_FUNCTION__); } while (0); | |||
324 | } | |||
325 | ||||
326 | if (journal_remote_server_global->check_trust) { | |||
327 | r = check_permissions(connection, &code, &hostname); | |||
328 | if (r < 0) | |||
329 | return code; | |||
330 | } else { | |||
331 | r = getpeername_pretty(fd, false0, &hostname); | |||
332 | if (r < 0) | |||
333 | return mhd_respond(connection, MHD_HTTP_INTERNAL_SERVER_ERROR500, | |||
334 | "Cannot check remote hostname."); | |||
335 | } | |||
336 | ||||
337 | assert(hostname)do { if ((__builtin_expect(!!(!(hostname)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("hostname"), "../src/journal-remote/journal-remote-main.c" , 337, __PRETTY_FUNCTION__); } while (0); | |||
338 | ||||
339 | r = request_meta(connection_cls, fd, hostname); | |||
340 | if (r == -ENOMEM12) | |||
341 | return respond_oom(connection)log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 341, __func__), mhd_respond_oom(connection); | |||
342 | else if (r < 0) | |||
343 | return mhd_respondf(connection, r, MHD_HTTP_INTERNAL_SERVER_ERROR500, "%m"); | |||
344 | ||||
345 | hostname = NULL((void*)0); | |||
346 | return MHD_YES; | |||
347 | } | |||
348 | ||||
349 | static int setup_microhttpd_server(RemoteServer *s, | |||
350 | int fd, | |||
351 | const char *key, | |||
352 | const char *cert, | |||
353 | const char *trust) { | |||
354 | struct MHD_OptionItem opts[] = { | |||
355 | { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free}, | |||
356 | { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger}, | |||
357 | { MHD_OPTION_LISTEN_SOCKET, fd}, | |||
358 | { MHD_OPTION_CONNECTION_MEMORY_LIMIT, 128*1024}, | |||
359 | { MHD_OPTION_END}, | |||
360 | { MHD_OPTION_END}, | |||
361 | { MHD_OPTION_END}, | |||
362 | { MHD_OPTION_END}, | |||
363 | { MHD_OPTION_END}}; | |||
364 | int opts_pos = 4; | |||
365 | int flags = | |||
366 | MHD_USE_DEBUG | | |||
367 | MHD_USE_DUAL_STACK | | |||
368 | MHD_USE_EPOLLMHD_USE_EPOLL_LINUX_ONLY | | |||
369 | MHD_USE_ITCMHD_USE_PIPE_FOR_SHUTDOWN; | |||
370 | ||||
371 | const union MHD_DaemonInfo *info; | |||
372 | int r, epoll_fd; | |||
373 | MHDDaemonWrapper *d; | |||
374 | ||||
375 | assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/journal-remote/journal-remote-main.c" , 375, __PRETTY_FUNCTION__); } while (0); | |||
376 | ||||
377 | r = fd_nonblock(fd, true1); | |||
378 | if (r < 0) | |||
379 | return log_error_errno(r, "Failed to make fd:%d nonblocking: %m", fd)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 379, __func__ , "Failed to make fd:%d nonblocking: %m", fd) : -abs(_e); }); | |||
380 | ||||
381 | /* MHD_OPTION_STRICT_FOR_CLIENT is introduced in microhttpd 0.9.54, | |||
382 | * and MHD_USE_PEDANTIC_CHECKS will be deprecated in future. | |||
383 | * If MHD_USE_PEDANTIC_CHECKS is '#define'd, then it is deprecated | |||
384 | * and we should use MHD_OPTION_STRICT_FOR_CLIENT. On the other hand, | |||
385 | * if MHD_USE_PEDANTIC_CHECKS is not '#define'd, then it is not | |||
386 | * deprecated yet and there exists an enum element with the same name. | |||
387 | * So we can safely use it. */ | |||
388 | #ifdef MHD_USE_PEDANTIC_CHECKS | |||
389 | opts[opts_pos++] = (struct MHD_OptionItem) | |||
390 | {MHD_OPTION_STRICT_FOR_CLIENT, 1}; | |||
391 | #else | |||
392 | flags |= MHD_USE_PEDANTIC_CHECKS; | |||
393 | #endif | |||
394 | ||||
395 | if (key) { | |||
396 | assert(cert)do { if ((__builtin_expect(!!(!(cert)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("cert"), "../src/journal-remote/journal-remote-main.c" , 396, __PRETTY_FUNCTION__); } while (0); | |||
397 | ||||
398 | opts[opts_pos++] = (struct MHD_OptionItem) | |||
399 | {MHD_OPTION_HTTPS_MEM_KEY, 0, (char*) key}; | |||
400 | opts[opts_pos++] = (struct MHD_OptionItem) | |||
401 | {MHD_OPTION_HTTPS_MEM_CERT, 0, (char*) cert}; | |||
402 | ||||
403 | flags |= MHD_USE_TLSMHD_USE_SSL; | |||
404 | ||||
405 | if (trust) | |||
406 | opts[opts_pos++] = (struct MHD_OptionItem) | |||
407 | {MHD_OPTION_HTTPS_MEM_TRUST, 0, (char*) trust}; | |||
408 | } | |||
409 | ||||
410 | d = new(MHDDaemonWrapper, 1)((MHDDaemonWrapper*) malloc_multiply(sizeof(MHDDaemonWrapper) , (1))); | |||
411 | if (!d) | |||
412 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 412, __func__); | |||
413 | ||||
414 | d->fd = (uint64_t) fd; | |||
415 | ||||
416 | d->daemon = MHD_start_daemon(flags, 0, | |||
417 | NULL((void*)0), NULL((void*)0), | |||
418 | request_handler, NULL((void*)0), | |||
419 | MHD_OPTION_ARRAY, opts, | |||
420 | MHD_OPTION_END); | |||
421 | if (!d->daemon) { | |||
422 | log_error("Failed to start µhttp daemon")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 422, __func__ , "Failed to start µhttp daemon") : -abs(_e); }); | |||
423 | r = -EINVAL22; | |||
424 | goto error; | |||
425 | } | |||
426 | ||||
427 | log_debug("Started MHD %s daemon on fd:%d (wrapper @ %p)",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 428, __func__ , "Started MHD %s daemon on fd:%d (wrapper @ %p)", key ? "HTTPS" : "HTTP", fd, d) : -abs(_e); }) | |||
428 | key ? "HTTPS" : "HTTP", fd, d)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 428, __func__ , "Started MHD %s daemon on fd:%d (wrapper @ %p)", key ? "HTTPS" : "HTTP", fd, d) : -abs(_e); }); | |||
429 | ||||
430 | info = MHD_get_daemon_info(d->daemon, MHD_DAEMON_INFO_EPOLL_FD_LINUX_ONLY); | |||
431 | if (!info) { | |||
432 | log_error("µhttp returned NULL daemon info")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 432, __func__ , "µhttp returned NULL daemon info") : -abs(_e); }); | |||
433 | r = -EOPNOTSUPP95; | |||
434 | goto error; | |||
435 | } | |||
436 | ||||
437 | epoll_fd = info->listen_fd; | |||
438 | if (epoll_fd < 0) { | |||
439 | log_error("µhttp epoll fd is invalid")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 439, __func__ , "µhttp epoll fd is invalid") : -abs(_e); }); | |||
440 | r = -EUCLEAN117; | |||
441 | goto error; | |||
442 | } | |||
443 | ||||
444 | r = sd_event_add_io(s->events, &d->io_event, | |||
445 | epoll_fd, EPOLLINEPOLLIN, | |||
446 | dispatch_http_event, d); | |||
447 | if (r < 0) { | |||
448 | log_error_errno(r, "Failed to add event callback: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 448, __func__ , "Failed to add event callback: %m") : -abs(_e); }); | |||
449 | goto error; | |||
450 | } | |||
451 | ||||
452 | r = sd_event_source_set_description(d->io_event, "io_event"); | |||
453 | if (r < 0) { | |||
454 | log_error_errno(r, "Failed to set source name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 454, __func__ , "Failed to set source name: %m") : -abs(_e); }); | |||
455 | goto error; | |||
456 | } | |||
457 | ||||
458 | r = sd_event_add_time(s->events, &d->timer_event, | |||
459 | CLOCK_MONOTONIC1, (uint64_t) -1, 0, | |||
460 | null_timer_event_handler, d); | |||
461 | if (r < 0) { | |||
462 | log_error_errno(r, "Failed to add timer_event: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 462, __func__ , "Failed to add timer_event: %m") : -abs(_e); }); | |||
463 | goto error; | |||
464 | } | |||
465 | ||||
466 | r = sd_event_source_set_description(d->timer_event, "timer_event"); | |||
467 | if (r < 0) { | |||
468 | log_error_errno(r, "Failed to set source name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 468, __func__ , "Failed to set source name: %m") : -abs(_e); }); | |||
469 | goto error; | |||
470 | } | |||
471 | ||||
472 | r = hashmap_ensure_allocated(&s->daemons, &uint64_hash_ops)internal_hashmap_ensure_allocated(&s->daemons, &uint64_hash_ops ); | |||
473 | if (r < 0) { | |||
474 | log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 474, __func__); | |||
475 | goto error; | |||
476 | } | |||
477 | ||||
478 | r = hashmap_put(s->daemons, &d->fd, d); | |||
479 | if (r < 0) { | |||
480 | log_error_errno(r, "Failed to add daemon to hashmap: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 480, __func__ , "Failed to add daemon to hashmap: %m") : -abs(_e); }); | |||
481 | goto error; | |||
482 | } | |||
483 | ||||
484 | s->active++; | |||
485 | return 0; | |||
486 | ||||
487 | error: | |||
488 | MHD_stop_daemon(d->daemon); | |||
489 | free(d->daemon); | |||
490 | free(d); | |||
491 | return r; | |||
492 | } | |||
493 | ||||
494 | static int setup_microhttpd_socket(RemoteServer *s, | |||
495 | const char *address, | |||
496 | const char *key, | |||
497 | const char *cert, | |||
498 | const char *trust) { | |||
499 | int fd; | |||
500 | ||||
501 | fd = make_socket_fd(LOG_DEBUG7, address, SOCK_STREAMSOCK_STREAM, SOCK_CLOEXECSOCK_CLOEXEC); | |||
502 | if (fd < 0) | |||
503 | return fd; | |||
504 | ||||
505 | return setup_microhttpd_server(s, fd, key, cert, trust); | |||
506 | } | |||
507 | ||||
508 | static int null_timer_event_handler(sd_event_source *timer_event, | |||
509 | uint64_t usec, | |||
510 | void *userdata) { | |||
511 | return dispatch_http_event(timer_event, 0, 0, userdata); | |||
512 | } | |||
513 | ||||
514 | static int dispatch_http_event(sd_event_source *event, | |||
515 | int fd, | |||
516 | uint32_t revents, | |||
517 | void *userdata) { | |||
518 | MHDDaemonWrapper *d = userdata; | |||
519 | int r; | |||
520 | MHD_UNSIGNED_LONG_LONGunsigned long long timeout = ULONG_LONG_MAX(9223372036854775807LL*2ULL+1ULL); | |||
521 | ||||
522 | assert(d)do { if ((__builtin_expect(!!(!(d)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("d"), "../src/journal-remote/journal-remote-main.c" , 522, __PRETTY_FUNCTION__); } while (0); | |||
523 | ||||
524 | r = MHD_run(d->daemon); | |||
525 | if (r == MHD_NO) { | |||
526 | log_error("MHD_run failed!")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 526, __func__ , "MHD_run failed!") : -abs(_e); }); | |||
527 | // XXX: unregister daemon | |||
528 | return -EINVAL22; | |||
529 | } | |||
530 | if (MHD_get_timeout(d->daemon, &timeout) == MHD_NO) | |||
531 | timeout = ULONG_LONG_MAX(9223372036854775807LL*2ULL+1ULL); | |||
532 | ||||
533 | r = sd_event_source_set_time(d->timer_event, timeout); | |||
534 | if (r < 0) { | |||
535 | log_warning_errno(r, "Unable to set event loop timeout: %m, this may result in indefinite blocking!")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 535, __func__ , "Unable to set event loop timeout: %m, this may result in indefinite blocking!" ) : -abs(_e); }); | |||
536 | return 1; | |||
537 | } | |||
538 | ||||
539 | r = sd_event_source_set_enabled(d->timer_event, SD_EVENT_ON); | |||
540 | if (r < 0) | |||
541 | log_warning_errno(r, "Unable to enable timer_event: %m, this may result in indefinite blocking!")({ int _level = ((4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 541, __func__ , "Unable to enable timer_event: %m, this may result in indefinite blocking!" ) : -abs(_e); }); | |||
542 | ||||
543 | return 1; /* work to do */ | |||
544 | } | |||
545 | ||||
546 | /********************************************************************** | |||
547 | ********************************************************************** | |||
548 | **********************************************************************/ | |||
549 | ||||
550 | static int setup_signals(RemoteServer *s) { | |||
551 | int r; | |||
552 | ||||
553 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/journal-remote/journal-remote-main.c" , 553, __PRETTY_FUNCTION__); } while (0); | |||
554 | ||||
555 | assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, -1) >= 0)do { if ((__builtin_expect(!!(!(sigprocmask_many(2, ((void*)0 ), 2, 15, -1) >= 0)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD , ("sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, -1) >= 0" ), "../src/journal-remote/journal-remote-main.c", 555, __PRETTY_FUNCTION__ ); } while (0); | |||
556 | ||||
557 | r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM15, NULL((void*)0), s); | |||
558 | if (r < 0) | |||
559 | return r; | |||
560 | ||||
561 | r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT2, NULL((void*)0), s); | |||
562 | if (r < 0) | |||
563 | return r; | |||
564 | ||||
565 | return 0; | |||
566 | } | |||
567 | ||||
568 | static int setup_raw_socket(RemoteServer *s, const char *address) { | |||
569 | int fd; | |||
570 | ||||
571 | fd = make_socket_fd(LOG_INFO6, address, SOCK_STREAMSOCK_STREAM, SOCK_CLOEXECSOCK_CLOEXEC); | |||
572 | if (fd < 0) | |||
573 | return fd; | |||
574 | ||||
575 | return journal_remote_add_raw_socket(s, fd); | |||
576 | } | |||
577 | ||||
578 | static int create_remoteserver( | |||
579 | RemoteServer *s, | |||
580 | const char* key, | |||
581 | const char* cert, | |||
582 | const char* trust) { | |||
583 | ||||
584 | int r, n, fd; | |||
585 | char **file; | |||
586 | ||||
587 | r = journal_remote_server_init(s, arg_output, arg_split_mode, arg_compress, arg_seal); | |||
588 | if (r < 0) | |||
589 | return r; | |||
590 | ||||
591 | setup_signals(s); | |||
592 | ||||
593 | n = sd_listen_fds(true1); | |||
594 | if (n < 0) | |||
595 | return log_error_errno(n, "Failed to read listening file descriptors from environment: %m")({ int _level = ((3)), _e = ((n)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 595, __func__ , "Failed to read listening file descriptors from environment: %m" ) : -abs(_e); }); | |||
596 | else | |||
597 | log_debug("Received %d descriptors", n)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 597, __func__ , "Received %d descriptors", n) : -abs(_e); }); | |||
598 | ||||
599 | if (MAX(http_socket, https_socket)__extension__ ({ const typeof((http_socket)) __unique_prefix_A13 = ((http_socket)); const typeof((https_socket)) __unique_prefix_B14 = ((https_socket)); __unique_prefix_A13 > __unique_prefix_B14 ? __unique_prefix_A13 : __unique_prefix_B14; }) >= SD_LISTEN_FDS_START3 + n) { | |||
600 | log_error("Received fewer sockets than expected")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 600, __func__ , "Received fewer sockets than expected") : -abs(_e); }); | |||
601 | return -EBADFD77; | |||
602 | } | |||
603 | ||||
604 | for (fd = SD_LISTEN_FDS_START3; fd < SD_LISTEN_FDS_START3 + n; fd++) { | |||
605 | if (sd_is_socket(fd, AF_UNSPEC0, 0, true1)) { | |||
606 | log_debug("Received a listening socket (fd:%d)", fd)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 606, __func__ , "Received a listening socket (fd:%d)", fd) : -abs(_e); }); | |||
607 | ||||
608 | if (fd == http_socket) | |||
609 | r = setup_microhttpd_server(s, fd, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
610 | else if (fd == https_socket) | |||
611 | r = setup_microhttpd_server(s, fd, key, cert, trust); | |||
612 | else | |||
613 | r = journal_remote_add_raw_socket(s, fd); | |||
614 | } else if (sd_is_socket(fd, AF_UNSPEC0, 0, false0)) { | |||
615 | char *hostname; | |||
616 | ||||
617 | r = getpeername_pretty(fd, false0, &hostname); | |||
618 | if (r < 0) | |||
619 | return log_error_errno(r, "Failed to retrieve remote name: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 619, __func__ , "Failed to retrieve remote name: %m") : -abs(_e); }); | |||
620 | ||||
621 | log_debug("Received a connection socket (fd:%d) from %s", fd, hostname)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 621, __func__ , "Received a connection socket (fd:%d) from %s", fd, hostname ) : -abs(_e); }); | |||
622 | ||||
623 | r = journal_remote_add_source(s, fd, hostname, true1); | |||
624 | } else { | |||
625 | log_error("Unknown socket passed on fd:%d", fd)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 625, __func__ , "Unknown socket passed on fd:%d", fd) : -abs(_e); }); | |||
626 | ||||
627 | return -EINVAL22; | |||
628 | } | |||
629 | ||||
630 | if (r < 0) | |||
631 | return log_error_errno(r, "Failed to register socket (fd:%d): %m",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 632, __func__ , "Failed to register socket (fd:%d): %m", fd) : -abs(_e); }) | |||
632 | fd)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 632, __func__ , "Failed to register socket (fd:%d): %m", fd) : -abs(_e); }); | |||
633 | } | |||
634 | ||||
635 | if (arg_getter) { | |||
636 | log_info("Spawning getter %s...", arg_getter)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 636, __func__ , "Spawning getter %s...", arg_getter) : -abs(_e); }); | |||
637 | fd = spawn_getter(arg_getter); | |||
638 | if (fd < 0) | |||
639 | return fd; | |||
640 | ||||
641 | r = journal_remote_add_source(s, fd, (char*) arg_output, false0); | |||
642 | if (r < 0) | |||
643 | return r; | |||
644 | } | |||
645 | ||||
646 | if (arg_url) { | |||
647 | const char *url; | |||
648 | char *hostname, *p; | |||
649 | ||||
650 | if (!strstr(arg_url, "/entries")) { | |||
651 | if (endswith(arg_url, "/")) | |||
652 | url = strjoina(arg_url, "entries")({ const char *_appendees_[] = { arg_url, "entries" }; char * _d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
653 | else | |||
654 | url = strjoina(arg_url, "/entries")({ const char *_appendees_[] = { arg_url, "/entries" }; char * _d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
655 | } | |||
656 | else | |||
657 | url = strdupa(arg_url)(__extension__ ({ const char *__old = (arg_url); size_t __len = strlen (__old) + 1; char *__new = (char *) __builtin_alloca (__len); (char *) memcpy (__new, __old, __len); })); | |||
658 | ||||
659 | log_info("Spawning curl %s...", url)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 659, __func__ , "Spawning curl %s...", url) : -abs(_e); }); | |||
660 | fd = spawn_curl(url); | |||
661 | if (fd < 0) | |||
662 | return fd; | |||
663 | ||||
664 | hostname = | |||
665 | startswith(arg_url, "https://") ?: | |||
666 | startswith(arg_url, "http://") ?: | |||
667 | arg_url; | |||
668 | ||||
669 | hostname = strdupa(hostname)(__extension__ ({ const char *__old = (hostname); size_t __len = strlen (__old) + 1; char *__new = (char *) __builtin_alloca (__len); (char *) memcpy (__new, __old, __len); })); | |||
670 | if ((p = strchr(hostname, '/'))) | |||
671 | *p = '\0'; | |||
672 | if ((p = strchr(hostname, ':'))) | |||
673 | *p = '\0'; | |||
674 | ||||
675 | r = journal_remote_add_source(s, fd, hostname, false0); | |||
676 | if (r < 0) | |||
677 | return r; | |||
678 | } | |||
679 | ||||
680 | if (arg_listen_raw) { | |||
681 | log_debug("Listening on a socket...")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 681, __func__ , "Listening on a socket...") : -abs(_e); }); | |||
682 | r = setup_raw_socket(s, arg_listen_raw); | |||
683 | if (r < 0) | |||
684 | return r; | |||
685 | } | |||
686 | ||||
687 | if (arg_listen_http) { | |||
688 | r = setup_microhttpd_socket(s, arg_listen_http, NULL((void*)0), NULL((void*)0), NULL((void*)0)); | |||
689 | if (r < 0) | |||
690 | return r; | |||
691 | } | |||
692 | ||||
693 | if (arg_listen_https) { | |||
694 | r = setup_microhttpd_socket(s, arg_listen_https, key, cert, trust); | |||
695 | if (r < 0) | |||
696 | return r; | |||
697 | } | |||
698 | ||||
699 | STRV_FOREACH(file, arg_files)for ((file) = (arg_files); (file) && *(file); (file)++ ) { | |||
700 | const char *output_name; | |||
701 | ||||
702 | if (streq(*file, "-")(strcmp((*file),("-")) == 0)) { | |||
703 | log_debug("Using standard input as source.")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 703, __func__ , "Using standard input as source.") : -abs(_e); }); | |||
704 | ||||
705 | fd = STDIN_FILENO0; | |||
706 | output_name = "stdin"; | |||
707 | } else { | |||
708 | log_debug("Reading file %s...", *file)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 708, __func__ , "Reading file %s...", *file) : -abs(_e); }); | |||
709 | ||||
710 | fd = open(*file, O_RDONLY00|O_CLOEXEC02000000|O_NOCTTY0400|O_NONBLOCK04000); | |||
711 | if (fd < 0) | |||
712 | return log_error_errno(errno, "Failed to open %s: %m", *file)({ int _level = ((3)), _e = (((*__errno_location ()))), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >= ((_level) & 0x07)) ? log_internal_realm(((_realm) << 10 | (_level)), _e, "../src/journal-remote/journal-remote-main.c" , 712, __func__, "Failed to open %s: %m", *file) : -abs(_e); } ); | |||
713 | output_name = *file; | |||
714 | } | |||
715 | ||||
716 | r = journal_remote_add_source(s, fd, (char*) output_name, false0); | |||
717 | if (r < 0) | |||
718 | return r; | |||
719 | } | |||
720 | ||||
721 | if (s->active == 0) { | |||
722 | log_error("Zero sources specified")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 722, __func__ , "Zero sources specified") : -abs(_e); }); | |||
723 | return -EINVAL22; | |||
724 | } | |||
725 | ||||
726 | if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE) { | |||
727 | /* In this case we know what the writer will be | |||
728 | called, so we can create it and verify that we can | |||
729 | create output as expected. */ | |||
730 | r = journal_remote_get_writer(s, NULL((void*)0), &s->_single_writer); | |||
731 | if (r < 0) | |||
732 | return r; | |||
733 | } | |||
734 | ||||
735 | return 0; | |||
736 | } | |||
737 | ||||
738 | static int negative_fd(const char *spec) { | |||
739 | /* Return a non-positive number as its inverse, -EINVAL otherwise. */ | |||
740 | ||||
741 | int fd, r; | |||
742 | ||||
743 | r = safe_atoi(spec, &fd); | |||
744 | if (r < 0) | |||
745 | return r; | |||
746 | ||||
747 | if (fd > 0) | |||
748 | return -EINVAL22; | |||
749 | else | |||
750 | return -fd; | |||
751 | } | |||
752 | ||||
753 | static int parse_config(void) { | |||
754 | const ConfigTableItem items[] = { | |||
755 | { "Remote", "Seal", config_parse_bool, 0, &arg_seal }, | |||
756 | { "Remote", "SplitMode", config_parse_write_split_mode, 0, &arg_split_mode }, | |||
757 | { "Remote", "ServerKeyFile", config_parse_path, 0, &arg_key }, | |||
758 | { "Remote", "ServerCertificateFile", config_parse_path, 0, &arg_cert }, | |||
759 | { "Remote", "TrustedCertificateFile", config_parse_path, 0, &arg_trust }, | |||
760 | {}}; | |||
761 | ||||
762 | return config_parse_many_nulstr(PKGSYSCONFDIR"/etc/systemd" "/journal-remote.conf", | |||
763 | CONF_PATHS_NULSTR("systemd/journal-remote.conf.d")"/etc/" "systemd/journal-remote.conf.d" "\0" "/run/" "systemd/journal-remote.conf.d" "\0" "/usr/local/lib/" "systemd/journal-remote.conf.d" "\0" "/usr/lib/" "systemd/journal-remote.conf.d" "\0", | |||
764 | "Remote\0", config_item_table_lookup, items, | |||
765 | CONFIG_PARSE_WARN, NULL((void*)0)); | |||
766 | } | |||
767 | ||||
768 | static void help(void) { | |||
769 | printf("%s [OPTIONS...] {FILE|-}...\n\n" | |||
770 | "Write external journal events to journal file(s).\n\n" | |||
771 | " -h --help Show this help\n" | |||
772 | " --version Show package version\n" | |||
773 | " --url=URL Read events from systemd-journal-gatewayd at URL\n" | |||
774 | " --getter=COMMAND Read events from the output of COMMAND\n" | |||
775 | " --listen-raw=ADDR Listen for connections at ADDR\n" | |||
776 | " --listen-http=ADDR Listen for HTTP connections at ADDR\n" | |||
777 | " --listen-https=ADDR Listen for HTTPS connections at ADDR\n" | |||
778 | " -o --output=FILE|DIR Write output to FILE or DIR/external-*.journal\n" | |||
779 | " --compress[=BOOL] XZ-compress the output journal (default: yes)\n" | |||
780 | " --seal[=BOOL] Use event sealing (default: no)\n" | |||
781 | " --key=FILENAME SSL key in PEM format (default:\n" | |||
782 | " \"" PRIV_KEY_FILE"/etc/ssl" "/private/journal-remote.pem" "\")\n" | |||
783 | " --cert=FILENAME SSL certificate in PEM format (default:\n" | |||
784 | " \"" CERT_FILE"/etc/ssl" "/certs/journal-remote.pem" "\")\n" | |||
785 | " --trust=FILENAME|all SSL CA certificate or disable checking (default:\n" | |||
786 | " \"" TRUST_FILE"/etc/ssl" "/ca/trusted.pem" "\")\n" | |||
787 | " --gnutls-log=CATEGORY...\n" | |||
788 | " Specify a list of gnutls logging categories\n" | |||
789 | " --split-mode=none|host How many output files to create\n" | |||
790 | "\n" | |||
791 | "Note: file descriptors from sd_listen_fds() will be consumed, too.\n" | |||
792 | , program_invocation_short_name); | |||
793 | } | |||
794 | ||||
795 | static int parse_argv(int argc, char *argv[]) { | |||
796 | enum { | |||
797 | ARG_VERSION = 0x100, | |||
798 | ARG_URL, | |||
799 | ARG_LISTEN_RAW, | |||
800 | ARG_LISTEN_HTTP, | |||
801 | ARG_LISTEN_HTTPS, | |||
802 | ARG_GETTER, | |||
803 | ARG_SPLIT_MODE, | |||
804 | ARG_COMPRESS, | |||
805 | ARG_SEAL, | |||
806 | ARG_KEY, | |||
807 | ARG_CERT, | |||
808 | ARG_TRUST, | |||
809 | ARG_GNUTLS_LOG, | |||
810 | }; | |||
811 | ||||
812 | static const struct option options[] = { | |||
813 | { "help", no_argument0, NULL((void*)0), 'h' }, | |||
814 | { "version", no_argument0, NULL((void*)0), ARG_VERSION }, | |||
815 | { "url", required_argument1, NULL((void*)0), ARG_URL }, | |||
816 | { "getter", required_argument1, NULL((void*)0), ARG_GETTER }, | |||
817 | { "listen-raw", required_argument1, NULL((void*)0), ARG_LISTEN_RAW }, | |||
818 | { "listen-http", required_argument1, NULL((void*)0), ARG_LISTEN_HTTP }, | |||
819 | { "listen-https", required_argument1, NULL((void*)0), ARG_LISTEN_HTTPS }, | |||
820 | { "output", required_argument1, NULL((void*)0), 'o' }, | |||
821 | { "split-mode", required_argument1, NULL((void*)0), ARG_SPLIT_MODE }, | |||
822 | { "compress", optional_argument2, NULL((void*)0), ARG_COMPRESS }, | |||
823 | { "seal", optional_argument2, NULL((void*)0), ARG_SEAL }, | |||
824 | { "key", required_argument1, NULL((void*)0), ARG_KEY }, | |||
825 | { "cert", required_argument1, NULL((void*)0), ARG_CERT }, | |||
826 | { "trust", required_argument1, NULL((void*)0), ARG_TRUST }, | |||
827 | { "gnutls-log", required_argument1, NULL((void*)0), ARG_GNUTLS_LOG }, | |||
828 | {} | |||
829 | }; | |||
830 | ||||
831 | int c, r; | |||
832 | bool_Bool type_a, type_b; | |||
833 | ||||
834 | assert(argc >= 0)do { if ((__builtin_expect(!!(!(argc >= 0)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argc >= 0"), "../src/journal-remote/journal-remote-main.c" , 834, __PRETTY_FUNCTION__); } while (0); | |||
| ||||
835 | assert(argv)do { if ((__builtin_expect(!!(!(argv)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("argv"), "../src/journal-remote/journal-remote-main.c" , 835, __PRETTY_FUNCTION__); } while (0); | |||
836 | ||||
837 | while ((c = getopt_long(argc, argv, "ho:", options, NULL((void*)0))) >= 0) | |||
838 | switch(c) { | |||
839 | case 'h': | |||
840 | help(); | |||
841 | return 0 /* done */; | |||
842 | ||||
843 | case ARG_VERSION: | |||
844 | return version(); | |||
845 | ||||
846 | case ARG_URL: | |||
847 | if (arg_url) { | |||
848 | log_error("cannot currently set more than one --url")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 848, __func__ , "cannot currently set more than one --url") : -abs(_e); }); | |||
849 | return -EINVAL22; | |||
850 | } | |||
851 | ||||
852 | arg_url = optarg; | |||
853 | break; | |||
854 | ||||
855 | case ARG_GETTER: | |||
856 | if (arg_getter) { | |||
857 | log_error("cannot currently use --getter more than once")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 857, __func__ , "cannot currently use --getter more than once") : -abs(_e); }); | |||
858 | return -EINVAL22; | |||
859 | } | |||
860 | ||||
861 | arg_getter = optarg; | |||
862 | break; | |||
863 | ||||
864 | case ARG_LISTEN_RAW: | |||
865 | if (arg_listen_raw) { | |||
866 | log_error("cannot currently use --listen-raw more than once")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 866, __func__ , "cannot currently use --listen-raw more than once") : -abs( _e); }); | |||
867 | return -EINVAL22; | |||
868 | } | |||
869 | ||||
870 | arg_listen_raw = optarg; | |||
871 | break; | |||
872 | ||||
873 | case ARG_LISTEN_HTTP: | |||
874 | if (arg_listen_http || http_socket >= 0) { | |||
875 | log_error("cannot currently use --listen-http more than once")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 875, __func__ , "cannot currently use --listen-http more than once") : -abs (_e); }); | |||
876 | return -EINVAL22; | |||
877 | } | |||
878 | ||||
879 | r = negative_fd(optarg); | |||
880 | if (r >= 0) | |||
881 | http_socket = r; | |||
882 | else | |||
883 | arg_listen_http = optarg; | |||
884 | break; | |||
885 | ||||
886 | case ARG_LISTEN_HTTPS: | |||
887 | if (arg_listen_https || https_socket >= 0) { | |||
888 | log_error("cannot currently use --listen-https more than once")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 888, __func__ , "cannot currently use --listen-https more than once") : -abs (_e); }); | |||
889 | return -EINVAL22; | |||
890 | } | |||
891 | ||||
892 | r = negative_fd(optarg); | |||
893 | if (r >= 0) | |||
894 | https_socket = r; | |||
895 | else | |||
896 | arg_listen_https = optarg; | |||
897 | ||||
898 | break; | |||
899 | ||||
900 | case ARG_KEY: | |||
901 | if (arg_key) { | |||
902 | log_error("Key file specified twice")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 902, __func__ , "Key file specified twice") : -abs(_e); }); | |||
903 | return -EINVAL22; | |||
904 | } | |||
905 | ||||
906 | arg_key = strdup(optarg); | |||
907 | if (!arg_key) | |||
908 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 908, __func__); | |||
909 | ||||
910 | break; | |||
911 | ||||
912 | case ARG_CERT: | |||
913 | if (arg_cert) { | |||
914 | log_error("Certificate file specified twice")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 914, __func__ , "Certificate file specified twice") : -abs(_e); }); | |||
915 | return -EINVAL22; | |||
916 | } | |||
917 | ||||
918 | arg_cert = strdup(optarg); | |||
| ||||
919 | if (!arg_cert) | |||
920 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 920, __func__); | |||
921 | ||||
922 | break; | |||
923 | ||||
924 | case ARG_TRUST: | |||
925 | if (arg_trust || arg_trust_all) { | |||
926 | log_error("Confusing trusted CA configuration")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 926, __func__ , "Confusing trusted CA configuration") : -abs(_e); }); | |||
927 | return -EINVAL22; | |||
928 | } | |||
929 | ||||
930 | if (streq(optarg, "all")(strcmp((optarg),("all")) == 0)) | |||
931 | arg_trust_all = true1; | |||
932 | else { | |||
933 | #if HAVE_GNUTLS1 | |||
934 | arg_trust = strdup(optarg); | |||
935 | if (!arg_trust) | |||
936 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 936, __func__); | |||
937 | #else | |||
938 | log_error("Option --trust is not available.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 938, __func__ , "Option --trust is not available.") : -abs(_e); }); | |||
939 | return -EINVAL22; | |||
940 | #endif | |||
941 | } | |||
942 | ||||
943 | break; | |||
944 | ||||
945 | case 'o': | |||
946 | if (arg_output) { | |||
947 | log_error("cannot use --output/-o more than once")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 947, __func__ , "cannot use --output/-o more than once") : -abs(_e); }); | |||
948 | return -EINVAL22; | |||
949 | } | |||
950 | ||||
951 | arg_output = optarg; | |||
952 | break; | |||
953 | ||||
954 | case ARG_SPLIT_MODE: | |||
955 | arg_split_mode = journal_write_split_mode_from_string(optarg); | |||
956 | if (arg_split_mode == _JOURNAL_WRITE_SPLIT_INVALID) { | |||
957 | log_error("Invalid split mode: %s", optarg)({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 957, __func__ , "Invalid split mode: %s", optarg) : -abs(_e); }); | |||
958 | return -EINVAL22; | |||
959 | } | |||
960 | break; | |||
961 | ||||
962 | case ARG_COMPRESS: | |||
963 | if (optarg) { | |||
964 | r = parse_boolean(optarg); | |||
965 | if (r < 0) { | |||
966 | log_error("Failed to parse --compress= parameter.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 966, __func__ , "Failed to parse --compress= parameter.") : -abs(_e); }); | |||
967 | return -EINVAL22; | |||
968 | } | |||
969 | ||||
970 | arg_compress = !!r; | |||
971 | } else | |||
972 | arg_compress = true1; | |||
973 | ||||
974 | break; | |||
975 | ||||
976 | case ARG_SEAL: | |||
977 | if (optarg) { | |||
978 | r = parse_boolean(optarg); | |||
979 | if (r < 0) { | |||
980 | log_error("Failed to parse --seal= parameter.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 980, __func__ , "Failed to parse --seal= parameter.") : -abs(_e); }); | |||
981 | return -EINVAL22; | |||
982 | } | |||
983 | ||||
984 | arg_seal = !!r; | |||
985 | } else | |||
986 | arg_seal = true1; | |||
987 | ||||
988 | break; | |||
989 | ||||
990 | case ARG_GNUTLS_LOG: { | |||
991 | #if HAVE_GNUTLS1 | |||
992 | const char* p = optarg; | |||
993 | for (;;) { | |||
994 | _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0); | |||
995 | ||||
996 | r = extract_first_word(&p, &word, ",", 0); | |||
997 | if (r < 0) | |||
998 | return log_error_errno(r, "Failed to parse --gnutls-log= argument: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 998, __func__ , "Failed to parse --gnutls-log= argument: %m") : -abs(_e); } ); | |||
999 | ||||
1000 | if (r == 0) | |||
1001 | break; | |||
1002 | ||||
1003 | if (strv_push(&arg_gnutls_log, word) < 0) | |||
1004 | return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/journal-remote/journal-remote-main.c" , 1004, __func__); | |||
1005 | ||||
1006 | word = NULL((void*)0); | |||
1007 | } | |||
1008 | break; | |||
1009 | #else | |||
1010 | log_error("Option --gnutls-log is not available.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1010, __func__ , "Option --gnutls-log is not available.") : -abs(_e); }); | |||
1011 | return -EINVAL22; | |||
1012 | #endif | |||
1013 | } | |||
1014 | ||||
1015 | case '?': | |||
1016 | return -EINVAL22; | |||
1017 | ||||
1018 | default: | |||
1019 | assert_not_reached("Unknown option code.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, ( "Unknown option code."), "../src/journal-remote/journal-remote-main.c" , 1019, __PRETTY_FUNCTION__); } while (0); | |||
1020 | } | |||
1021 | ||||
1022 | if (optind < argc) | |||
1023 | arg_files = argv + optind; | |||
1024 | ||||
1025 | type_a = arg_getter || !strv_isempty(arg_files); | |||
1026 | type_b = arg_url | |||
1027 | || arg_listen_raw | |||
1028 | || arg_listen_http || arg_listen_https | |||
1029 | || sd_listen_fds(false0) > 0; | |||
1030 | if (type_a && type_b) { | |||
1031 | log_error("Cannot use file input or --getter with "({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1032, __func__ , "Cannot use file input or --getter with " "--arg-listen-... or socket activation." ) : -abs(_e); }) | |||
1032 | "--arg-listen-... or socket activation.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1032, __func__ , "Cannot use file input or --getter with " "--arg-listen-... or socket activation." ) : -abs(_e); }); | |||
1033 | return -EINVAL22; | |||
1034 | } | |||
1035 | if (type_a) { | |||
1036 | if (!arg_output) { | |||
1037 | log_error("Option --output must be specified with file input or --getter.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1037, __func__ , "Option --output must be specified with file input or --getter." ) : -abs(_e); }); | |||
1038 | return -EINVAL22; | |||
1039 | } | |||
1040 | ||||
1041 | if (!IN_SET(arg_split_mode, JOURNAL_WRITE_SPLIT_NONE, _JOURNAL_WRITE_SPLIT_INVALID)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended [20 - sizeof((int[]){JOURNAL_WRITE_SPLIT_NONE, _JOURNAL_WRITE_SPLIT_INVALID })/sizeof(int)]; switch(arg_split_mode) { case JOURNAL_WRITE_SPLIT_NONE : case _JOURNAL_WRITE_SPLIT_INVALID: _found = 1; break; default : break; } _found; })) { | |||
1042 | log_error("For active sources, only --split-mode=none is allowed.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1042, __func__ , "For active sources, only --split-mode=none is allowed.") : -abs(_e); }); | |||
1043 | return -EINVAL22; | |||
1044 | } | |||
1045 | ||||
1046 | arg_split_mode = JOURNAL_WRITE_SPLIT_NONE; | |||
1047 | } | |||
1048 | ||||
1049 | if (arg_split_mode == _JOURNAL_WRITE_SPLIT_INVALID) | |||
1050 | arg_split_mode = JOURNAL_WRITE_SPLIT_HOST; | |||
1051 | ||||
1052 | if (arg_split_mode == JOURNAL_WRITE_SPLIT_NONE && arg_output) { | |||
1053 | if (is_dir(arg_output, true1) > 0) { | |||
1054 | log_error("For SplitMode=none, output must be a file.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1054, __func__ , "For SplitMode=none, output must be a file.") : -abs(_e); } ); | |||
1055 | return -EINVAL22; | |||
1056 | } | |||
1057 | if (!endswith(arg_output, ".journal")) { | |||
1058 | log_error("For SplitMode=none, output file name must end with .journal.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1058, __func__ , "For SplitMode=none, output file name must end with .journal." ) : -abs(_e); }); | |||
1059 | return -EINVAL22; | |||
1060 | } | |||
1061 | } | |||
1062 | ||||
1063 | if (arg_split_mode == JOURNAL_WRITE_SPLIT_HOST | |||
1064 | && arg_output && is_dir(arg_output, true1) <= 0) { | |||
1065 | log_error("For SplitMode=host, output must be a directory.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1065, __func__ , "For SplitMode=host, output must be a directory.") : -abs(_e ); }); | |||
1066 | return -EINVAL22; | |||
1067 | } | |||
1068 | ||||
1069 | log_debug("Full config: SplitMode=%s Key=%s Cert=%s Trust=%s",({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1073, __func__ , "Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string (arg_split_mode), strna(arg_key), strna(arg_cert), strna(arg_trust )) : -abs(_e); }) | |||
1070 | journal_write_split_mode_to_string(arg_split_mode),({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1073, __func__ , "Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string (arg_split_mode), strna(arg_key), strna(arg_cert), strna(arg_trust )) : -abs(_e); }) | |||
1071 | strna(arg_key),({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1073, __func__ , "Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string (arg_split_mode), strna(arg_key), strna(arg_cert), strna(arg_trust )) : -abs(_e); }) | |||
1072 | strna(arg_cert),({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1073, __func__ , "Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string (arg_split_mode), strna(arg_key), strna(arg_cert), strna(arg_trust )) : -abs(_e); }) | |||
1073 | strna(arg_trust))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1073, __func__ , "Full config: SplitMode=%s Key=%s Cert=%s Trust=%s", journal_write_split_mode_to_string (arg_split_mode), strna(arg_key), strna(arg_cert), strna(arg_trust )) : -abs(_e); }); | |||
1074 | ||||
1075 | return 1 /* work to do */; | |||
1076 | } | |||
1077 | ||||
1078 | static int load_certificates(char **key, char **cert, char **trust) { | |||
1079 | int r; | |||
1080 | ||||
1081 | r = read_full_file(arg_key ?: PRIV_KEY_FILE"/etc/ssl" "/private/journal-remote.pem", key, NULL((void*)0)); | |||
1082 | if (r < 0) | |||
1083 | return log_error_errno(r, "Failed to read key from file '%s': %m",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1084, __func__ , "Failed to read key from file '%s': %m", arg_key ?: "/etc/ssl" "/private/journal-remote.pem") : -abs(_e); }) | |||
1084 | arg_key ?: PRIV_KEY_FILE)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1084, __func__ , "Failed to read key from file '%s': %m", arg_key ?: "/etc/ssl" "/private/journal-remote.pem") : -abs(_e); }); | |||
1085 | ||||
1086 | r = read_full_file(arg_cert ?: CERT_FILE"/etc/ssl" "/certs/journal-remote.pem", cert, NULL((void*)0)); | |||
1087 | if (r < 0) | |||
1088 | return log_error_errno(r, "Failed to read certificate from file '%s': %m",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1089, __func__ , "Failed to read certificate from file '%s': %m", arg_cert ? : "/etc/ssl" "/certs/journal-remote.pem") : -abs(_e); }) | |||
1089 | arg_cert ?: CERT_FILE)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1089, __func__ , "Failed to read certificate from file '%s': %m", arg_cert ? : "/etc/ssl" "/certs/journal-remote.pem") : -abs(_e); }); | |||
1090 | ||||
1091 | if (arg_trust_all) | |||
1092 | log_info("Certificate checking disabled.")({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1092, __func__ , "Certificate checking disabled.") : -abs(_e); }); | |||
1093 | else { | |||
1094 | r = read_full_file(arg_trust ?: TRUST_FILE"/etc/ssl" "/ca/trusted.pem", trust, NULL((void*)0)); | |||
1095 | if (r < 0) | |||
1096 | return log_error_errno(r, "Failed to read CA certificate file '%s': %m",({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1097, __func__ , "Failed to read CA certificate file '%s': %m", arg_trust ?: "/etc/ssl" "/ca/trusted.pem") : -abs(_e); }) | |||
1097 | arg_trust ?: TRUST_FILE)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1097, __func__ , "Failed to read CA certificate file '%s': %m", arg_trust ?: "/etc/ssl" "/ca/trusted.pem") : -abs(_e); }); | |||
1098 | } | |||
1099 | ||||
1100 | if ((arg_listen_raw || arg_listen_http) && *trust) { | |||
1101 | log_error("Option --trust makes all non-HTTPS connections untrusted.")({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1101, __func__ , "Option --trust makes all non-HTTPS connections untrusted." ) : -abs(_e); }); | |||
1102 | return -EINVAL22; | |||
1103 | } | |||
1104 | ||||
1105 | return 0; | |||
1106 | } | |||
1107 | ||||
1108 | int main(int argc, char **argv) { | |||
1109 | RemoteServer s = {}; | |||
1110 | int r; | |||
1111 | _cleanup_free___attribute__((cleanup(freep))) char *key = NULL((void*)0), *cert = NULL((void*)0), *trust = NULL((void*)0); | |||
1112 | ||||
1113 | log_show_color(true1); | |||
1114 | log_parse_environment()log_parse_environment_realm(LOG_REALM_SYSTEMD); | |||
1115 | ||||
1116 | r = parse_config(); | |||
1117 | if (r < 0) | |||
1118 | return EXIT_FAILURE1; | |||
1119 | ||||
1120 | r = parse_argv(argc, argv); | |||
1121 | if (r <= 0) | |||
1122 | return r == 0 ? EXIT_SUCCESS0 : EXIT_FAILURE1; | |||
1123 | ||||
1124 | if (arg_listen_http || arg_listen_https) { | |||
1125 | r = setup_gnutls_logger(arg_gnutls_log); | |||
1126 | if (r < 0) | |||
1127 | return EXIT_FAILURE1; | |||
1128 | } | |||
1129 | ||||
1130 | if (arg_listen_https || https_socket >= 0) | |||
1131 | if (load_certificates(&key, &cert, &trust) < 0) | |||
1132 | return EXIT_FAILURE1; | |||
1133 | ||||
1134 | if (create_remoteserver(&s, key, cert, trust) < 0) | |||
1135 | return EXIT_FAILURE1; | |||
1136 | ||||
1137 | r = sd_event_set_watchdog(s.events, true1); | |||
1138 | if (r < 0) | |||
1139 | log_error_errno(r, "Failed to enable watchdog: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1139, __func__ , "Failed to enable watchdog: %m") : -abs(_e); }); | |||
1140 | else | |||
1141 | log_debug("Watchdog is %sd.", enable_disable(r > 0))({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1141, __func__ , "Watchdog is %sd.", enable_disable(r > 0)) : -abs(_e); } ); | |||
1142 | ||||
1143 | log_debug("%s running as pid "PID_FMT,({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1144, __func__ , "%s running as pid ""%" "i", program_invocation_short_name, getpid_cached()) : -abs(_e); }) | |||
1144 | program_invocation_short_name, getpid_cached())({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1144, __func__ , "%s running as pid ""%" "i", program_invocation_short_name, getpid_cached()) : -abs(_e); }); | |||
1145 | sd_notify(false0, | |||
1146 | "READY=1\n" | |||
1147 | "STATUS=Processing requests..."); | |||
1148 | ||||
1149 | while (s.active) { | |||
1150 | r = sd_event_get_state(s.events); | |||
1151 | if (r < 0) | |||
1152 | break; | |||
1153 | if (r == SD_EVENT_FINISHED) | |||
1154 | break; | |||
1155 | ||||
1156 | r = sd_event_run(s.events, -1); | |||
1157 | if (r < 0) { | |||
1158 | log_error_errno(r, "Failed to run event loop: %m")({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1158, __func__ , "Failed to run event loop: %m") : -abs(_e); }); | |||
1159 | break; | |||
1160 | } | |||
1161 | } | |||
1162 | ||||
1163 | sd_notifyf(false0, | |||
1164 | "STOPPING=1\n" | |||
1165 | "STATUS=Shutting down after writing %" PRIu64"l" "u" " entries...", s.event_count); | |||
1166 | log_info("Finishing after writing %" PRIu64 " entries", s.event_count)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/journal-remote/journal-remote-main.c", 1166, __func__ , "Finishing after writing %" "l" "u" " entries", s.event_count ) : -abs(_e); }); | |||
1167 | ||||
1168 | journal_remote_server_destroy(&s); | |||
1169 | ||||
1170 | free(arg_key); | |||
1171 | free(arg_cert); | |||
1172 | free(arg_trust); | |||
1173 | ||||
1174 | return r >= 0 ? EXIT_SUCCESS0 : EXIT_FAILURE1; | |||
1175 | } |