Coverage Report

Created: 2025-05-08 06:41

/src/sudo/logsrvd/logsrvd_conf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * SPDX-License-Identifier: ISC
3
 *
4
 * Copyright (c) 2019-2023 Todd C. Miller <Todd.Miller@sudo.ws>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
/*
20
 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
21
 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
22
 */
23
24
#include <config.h>
25
26
#include <sys/stat.h>
27
#include <sys/types.h>
28
#include <sys/socket.h>
29
#include <netinet/in.h>
30
31
#include <errno.h>
32
#include <ctype.h>
33
#include <fcntl.h>
34
#include <limits.h>
35
#include <netdb.h>
36
#ifdef HAVE_STDBOOL_H
37
# include <stdbool.h>
38
#else
39
# include <compat/stdbool.h>
40
#endif
41
#include <stddef.h>
42
#include <stdio.h>
43
#include <stdlib.h>
44
#include <string.h>
45
#include <syslog.h>
46
#include <time.h>
47
#include <unistd.h>
48
#include <grp.h>
49
#include <pwd.h>
50
#ifndef HAVE_GETADDRINFO
51
# include <compat/getaddrinfo.h>
52
#endif
53
54
#include <pathnames.h>
55
#include <sudo_compat.h>
56
#include <sudo_debug.h>
57
#include <sudo_eventlog.h>
58
#include <sudo_fatal.h>
59
#include <sudo_gettext.h>
60
#include <sudo_iolog.h>
61
#include <sudo_util.h>
62
63
#include <logsrvd.h>
64
65
#if defined(HAVE_OPENSSL)
66
4.04k
# define DEFAULT_CA_CERT_PATH       "/etc/ssl/sudo/cacert.pem"
67
4.04k
# define DEFAULT_SERVER_CERT_PATH   "/etc/ssl/sudo/certs/logsrvd_cert.pem"
68
4.04k
# define DEFAULT_SERVER_KEY_PATH    "/etc/ssl/sudo/private/logsrvd_key.pem"
69
70
/* Evaluates to true if at least one TLS field is set, else false. */
71
# define TLS_CONFIGURED(_s)           \
72
0
    ((_s).tls_key_path != NULL || (_s).tls_cert_path != NULL ||   \
73
0
     (_s).tls_cacert_path != NULL || (_s).tls_dhparams_path != NULL || \
74
0
     (_s).tls_ciphers_v12 != NULL || (_s).tls_ciphers_v13 != NULL || \
75
0
     (_s).tls_verify != -1)
76
77
/* Evaluates to the relay-specific TLS setting, falling back to server. */
78
# define TLS_RELAY_STR(_c, _f)  \
79
0
    ((_c)->relay._f != NULL ? (_c)->relay._f : (_c)->server._f)
80
81
# define TLS_RELAY_INT(_c, _f)  \
82
0
    ((_c)->relay._f != -1 ? (_c)->relay._f : (_c)->server._f)
83
#endif
84
85
enum server_log_type {
86
    SERVER_LOG_NONE,
87
    SERVER_LOG_STDERR,
88
    SERVER_LOG_SYSLOG,
89
    SERVER_LOG_FILE
90
};
91
92
struct logsrvd_config;
93
typedef bool (*logsrvd_conf_cb_t)(struct logsrvd_config *, const char *, size_t);
94
95
struct logsrvd_config_entry {
96
    const char *conf_str;
97
    logsrvd_conf_cb_t setter;
98
    size_t offset;
99
};
100
101
struct logsrvd_config_section {
102
    const char *name;
103
    struct logsrvd_config_entry *entries;
104
};
105
106
struct address_list_container {
107
    unsigned int refcnt;
108
    struct server_address_list addrs;
109
};
110
111
static struct logsrvd_config {
112
    struct logsrvd_config_server {
113
        struct address_list_container addresses;
114
        struct timespec timeout;
115
        bool tcp_keepalive;
116
  enum server_log_type log_type;
117
  FILE *log_stream;
118
  char *log_file;
119
  char *pid_file;
120
#if defined(HAVE_OPENSSL)
121
  char *tls_key_path;
122
  char *tls_cert_path;
123
  char *tls_cacert_path;
124
  char *tls_dhparams_path;
125
  char *tls_ciphers_v12;
126
  char *tls_ciphers_v13;
127
  int tls_check_peer;
128
  int tls_verify;
129
  SSL_CTX *ssl_ctx;
130
#endif
131
    } server;
132
    struct logsrvd_config_relay {
133
        struct address_list_container relays;
134
        struct timespec connect_timeout;
135
        struct timespec timeout;
136
  time_t retry_interval;
137
  char *relay_dir;
138
        bool tcp_keepalive;
139
  bool store_first;
140
#if defined(HAVE_OPENSSL)
141
  char *tls_key_path;
142
  char *tls_cert_path;
143
  char *tls_cacert_path;
144
  char *tls_dhparams_path;
145
  char *tls_ciphers_v12;
146
  char *tls_ciphers_v13;
147
  int tls_check_peer;
148
  int tls_verify;
149
  SSL_CTX *ssl_ctx;
150
#endif
151
    } relay;
152
    struct logsrvd_config_iolog {
153
  bool compress;
154
  bool flush;
155
  bool gid_set;
156
  bool log_passwords;
157
  uid_t uid;
158
  gid_t gid;
159
  mode_t mode;
160
  unsigned int maxseq;
161
  char *iolog_dir;
162
  char *iolog_file;
163
  void *passprompt_regex;
164
    } iolog;
165
    struct logsrvd_config_eventlog {
166
  int log_type;
167
        bool log_exit;
168
  enum eventlog_format log_format;
169
    } eventlog;
170
    struct logsrvd_config_syslog {
171
  unsigned int maxlen;
172
  int server_facility;
173
  int facility;
174
  int acceptpri;
175
  int rejectpri;
176
  int alertpri;
177
    } syslog;
178
    struct logsrvd_config_logfile {
179
  char *path;
180
  char *time_format;
181
  FILE *stream;
182
    } logfile;
183
} *logsrvd_config;
184
185
static bool logsrvd_warn_enable_stderr = true;
186
187
/* eventlog getters */
188
bool
189
logsrvd_conf_log_exit(void)
190
0
{
191
0
    return logsrvd_config->eventlog.log_exit;
192
0
}
193
194
/* iolog getters */
195
uid_t
196
logsrvd_conf_iolog_uid(void)
197
0
{
198
0
    return logsrvd_config->iolog.uid;
199
0
}
200
201
gid_t
202
logsrvd_conf_iolog_gid(void)
203
0
{
204
0
    return logsrvd_config->iolog.gid;
205
0
}
206
207
mode_t
208
logsrvd_conf_iolog_mode(void)
209
0
{
210
0
    return logsrvd_config->iolog.mode;
211
0
}
212
213
const char *
214
logsrvd_conf_iolog_dir(void)
215
0
{
216
0
    return logsrvd_config->iolog.iolog_dir;
217
0
}
218
219
const char *
220
logsrvd_conf_iolog_file(void)
221
0
{
222
0
    return logsrvd_config->iolog.iolog_file;
223
0
}
224
225
bool
226
logsrvd_conf_iolog_log_passwords(void)
227
0
{
228
0
    return logsrvd_config->iolog.log_passwords;
229
0
}
230
231
void *
232
logsrvd_conf_iolog_passprompt_regex(void)
233
0
{
234
0
    return logsrvd_config->iolog.passprompt_regex;
235
0
}
236
237
/* server getters */
238
struct server_address_list *
239
logsrvd_conf_server_listen_address(void)
240
0
{
241
0
    return &logsrvd_config->server.addresses.addrs;
242
0
}
243
244
bool
245
logsrvd_conf_server_tcp_keepalive(void)
246
0
{
247
0
    return logsrvd_config->server.tcp_keepalive;
248
0
}
249
250
const char *
251
logsrvd_conf_pid_file(void)
252
0
{
253
0
    return logsrvd_config->server.pid_file;
254
0
}
255
256
struct timespec *
257
logsrvd_conf_server_timeout(void)
258
0
{
259
0
    if (sudo_timespecisset(&logsrvd_config->server.timeout)) {
260
0
        return &logsrvd_config->server.timeout;
261
0
    }
262
263
0
    return NULL;
264
0
}
265
266
#if defined(HAVE_OPENSSL)
267
SSL_CTX *
268
logsrvd_server_tls_ctx(void)
269
0
{
270
0
    return logsrvd_config->server.ssl_ctx;
271
0
}
272
273
bool
274
logsrvd_conf_server_tls_check_peer(void)
275
0
{
276
0
    return logsrvd_config->server.tls_check_peer;
277
0
}
278
#endif
279
280
/* relay getters */
281
struct server_address_list *
282
logsrvd_conf_relay_address(void)
283
0
{
284
0
    return &logsrvd_config->relay.relays.addrs;
285
0
}
286
287
const char *
288
logsrvd_conf_relay_dir(void)
289
0
{
290
0
    return logsrvd_config->relay.relay_dir;
291
0
}
292
293
bool
294
logsrvd_conf_relay_store_first(void)
295
0
{
296
0
    return logsrvd_config->relay.store_first;
297
0
}
298
299
bool
300
logsrvd_conf_relay_tcp_keepalive(void)
301
0
{
302
0
    return logsrvd_config->relay.tcp_keepalive;
303
0
}
304
305
struct timespec *
306
logsrvd_conf_relay_timeout(void)
307
0
{
308
0
    if (sudo_timespecisset(&logsrvd_config->relay.timeout)) {
309
0
        return &logsrvd_config->relay.timeout;
310
0
    }
311
312
0
    return NULL;
313
0
}
314
315
struct timespec *
316
logsrvd_conf_relay_connect_timeout(void)
317
0
{
318
0
    if (sudo_timespecisset(&logsrvd_config->relay.connect_timeout)) {
319
0
        return &logsrvd_config->relay.connect_timeout;
320
0
    }
321
322
0
    return NULL;
323
0
}
324
325
time_t
326
logsrvd_conf_relay_retry_interval(void)
327
0
{
328
0
    return logsrvd_config->relay.retry_interval;
329
0
}
330
331
#if defined(HAVE_OPENSSL)
332
SSL_CTX *
333
logsrvd_relay_tls_ctx(void)
334
0
{
335
0
    if (logsrvd_config->relay.ssl_ctx != NULL)
336
0
  return logsrvd_config->relay.ssl_ctx;
337
0
    return logsrvd_config->server.ssl_ctx;
338
0
}
339
340
bool
341
logsrvd_conf_relay_tls_check_peer(void)
342
0
{
343
0
    if (logsrvd_config->relay.tls_check_peer != -1)
344
0
  return logsrvd_config->relay.tls_check_peer;
345
0
    return logsrvd_config->server.tls_check_peer;
346
0
}
347
#endif
348
349
/* I/O log callbacks */
350
static bool
351
cb_iolog_dir(struct logsrvd_config *config, const char *path, size_t offset)
352
4.23k
{
353
4.23k
    debug_decl(cb_iolog_dir, SUDO_DEBUG_UTIL);
354
355
4.23k
    free(config->iolog.iolog_dir);
356
4.23k
    if ((config->iolog.iolog_dir = strdup(path)) == NULL) {
357
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
358
0
  debug_return_bool(false);
359
0
    }
360
4.23k
    debug_return_bool(true);
361
4.23k
}
362
363
static bool
364
cb_iolog_file(struct logsrvd_config *config, const char *path, size_t offset)
365
4.23k
{
366
4.23k
    debug_decl(cb_iolog_file, SUDO_DEBUG_UTIL);
367
368
4.23k
    free(config->iolog.iolog_file);
369
4.23k
    if ((config->iolog.iolog_file = strdup(path)) == NULL) {
370
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
371
0
  debug_return_bool(false);
372
0
    }
373
4.23k
    debug_return_bool(true);
374
4.23k
}
375
376
static bool
377
cb_iolog_compress(struct logsrvd_config *config, const char *str, size_t offset)
378
205
{
379
205
    int val;
380
205
    debug_decl(cb_iolog_compress, SUDO_DEBUG_UTIL);
381
382
205
    if ((val = sudo_strtobool(str)) == -1)
383
4
  debug_return_bool(false);
384
385
201
    config->iolog.compress = val;
386
201
    debug_return_bool(true);
387
201
}
388
389
static bool
390
cb_iolog_log_passwords(struct logsrvd_config *config, const char *str, size_t offset)
391
330
{
392
330
    int val;
393
330
    debug_decl(cb_iolog_log_passwords, SUDO_DEBUG_UTIL);
394
395
330
    if ((val = sudo_strtobool(str)) == -1)
396
5
  debug_return_bool(false);
397
398
325
    config->iolog.log_passwords = val;
399
325
    debug_return_bool(true);
400
325
}
401
402
static bool
403
cb_iolog_flush(struct logsrvd_config *config, const char *str, size_t offset)
404
338
{
405
338
    int val;
406
338
    debug_decl(cb_iolog_flush, SUDO_DEBUG_UTIL);
407
408
338
    if ((val = sudo_strtobool(str)) == -1)
409
5
  debug_return_bool(false);
410
411
333
    config->iolog.flush = val;
412
333
    debug_return_bool(true);
413
333
}
414
415
static bool
416
cb_iolog_user(struct logsrvd_config *config, const char *user, size_t offset)
417
568
{
418
568
    struct passwd *pw;
419
568
    debug_decl(cb_iolog_user, SUDO_DEBUG_UTIL);
420
421
568
    if ((pw = getpwnam(user)) == NULL) {
422
121
  sudo_warnx(U_("unknown user %s"), user);
423
121
  debug_return_bool(false);
424
121
    }
425
447
    config->iolog.uid = pw->pw_uid;
426
447
    if (!config->iolog.gid_set)
427
253
  config->iolog.gid = pw->pw_gid;
428
429
447
    debug_return_bool(true);
430
447
}
431
432
static bool
433
cb_iolog_group(struct logsrvd_config *config, const char *group, size_t offset)
434
375
{
435
375
    struct group *gr;
436
375
    debug_decl(cb_iolog_group, SUDO_DEBUG_UTIL);
437
438
375
    if ((gr = getgrnam(group)) == NULL) {
439
121
  sudo_warnx(U_("unknown group %s"), group);
440
121
  debug_return_bool(false);
441
121
    }
442
254
    config->iolog.gid = gr->gr_gid;
443
254
    config->iolog.gid_set = true;
444
445
254
    debug_return_bool(true);
446
254
}
447
448
static bool
449
cb_iolog_mode(struct logsrvd_config *config, const char *str, size_t offset)
450
399
{
451
399
    const char *errstr;
452
399
    mode_t mode;
453
399
    debug_decl(cb_iolog_mode, SUDO_DEBUG_UTIL);
454
455
399
    mode = sudo_strtomode(str, &errstr);
456
399
    if (errstr != NULL) {
457
176
  sudo_warnx(U_("unable to parse iolog mode %s"), str);
458
176
  debug_return_bool(false);
459
176
    }
460
223
    config->iolog.mode = mode;
461
223
    debug_return_bool(true);
462
223
}
463
464
static bool
465
cb_iolog_maxseq(struct logsrvd_config *config, const char *str, size_t offset)
466
1.48k
{
467
1.48k
    const char *errstr;
468
1.48k
    unsigned int value;
469
1.48k
    debug_decl(cb_iolog_maxseq, SUDO_DEBUG_UTIL);
470
471
1.48k
    value = (unsigned int)sudo_strtonum(str, 0, SESSID_MAX, &errstr);
472
1.48k
    if (errstr != NULL) {
473
678
        if (errno != ERANGE) {
474
27
      sudo_warnx(U_("invalid value for %s: %s"), "maxseq", errstr);
475
27
            debug_return_bool(false);
476
27
        }
477
        /* Out of range, clamp to SESSID_MAX as documented. */
478
651
        value = SESSID_MAX;
479
651
    }
480
1.45k
    config->iolog.maxseq = value;
481
1.45k
    debug_return_bool(true);
482
1.45k
}
483
484
static bool
485
cb_iolog_passprompt_regex(struct logsrvd_config *config, const char *str, size_t offset)
486
1.20k
{
487
1.20k
    debug_decl(cb_iolog_passprompt_regex, SUDO_DEBUG_UTIL);
488
489
1.20k
    if (config->iolog.passprompt_regex == NULL) {
490
  /* Lazy alloc of the passprompt regex handle. */
491
826
  config->iolog.passprompt_regex = iolog_pwfilt_alloc();
492
826
  if (config->iolog.passprompt_regex == NULL)
493
0
      debug_return_bool(false);
494
826
    }
495
1.20k
    debug_return_bool(iolog_pwfilt_add(config->iolog.passprompt_regex, str));
496
1.20k
}
497
498
/* Server callbacks */
499
static bool
500
append_address(struct server_address_list *addresses, const char *str,
501
    bool allow_wildcard)
502
1.91k
{
503
1.91k
    struct addrinfo hints, *res, *res0 = NULL;
504
1.91k
    char *sa_str = NULL, *sa_host = NULL;
505
1.91k
    char *copy, *host, *port;
506
1.91k
    bool tls, ret = false;
507
1.91k
    int error;
508
1.91k
    debug_decl(append_address, SUDO_DEBUG_UTIL);
509
510
1.91k
    if ((copy = strdup(str)) == NULL) {
511
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
512
0
  debug_return_bool(false);
513
0
    }
514
515
    /* Parse host[:port] */
516
1.91k
    if (!iolog_parse_host_port(copy, &host, &port, &tls, DEFAULT_PORT,
517
1.91k
      DEFAULT_PORT_TLS))
518
4
  goto done;
519
1.91k
    if (host[0] == '*' && host[1] == '\0') {
520
818
  if (!allow_wildcard)
521
2
      goto done;
522
816
  host = NULL;
523
816
    }
524
525
#if !defined(HAVE_OPENSSL)
526
    if (tls) {
527
  sudo_warnx("%s", U_("TLS not supported"));
528
  goto done;
529
    }
530
#endif
531
532
    /* Only make a single copy of the string + host for all addresses. */
533
1.91k
    if ((sa_str = sudo_rcstr_dup(str)) == NULL)  {
534
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
535
0
  goto done;
536
0
    }
537
1.91k
    if (host != NULL && (sa_host = sudo_rcstr_dup(host)) == NULL) {
538
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
539
0
  goto done;
540
0
    }
541
542
    /* Resolve host (and port if it is a service). */
543
1.91k
    memset(&hints, 0, sizeof(hints));
544
1.91k
    hints.ai_family = AF_UNSPEC;
545
1.91k
    hints.ai_socktype = SOCK_STREAM;
546
1.91k
    hints.ai_flags = AI_PASSIVE;
547
1.91k
    error = getaddrinfo(host, port, &hints, &res0);
548
1.91k
    if (error != 0) {
549
1.91k
  sudo_gai_warn(error, U_("%s:%s"), host ? host : "*", port);
550
1.91k
  goto done;
551
1.91k
    }
552
0
    for (res = res0; res != NULL; res = res->ai_next) {
553
0
  struct server_address *addr;
554
555
0
  if ((addr = malloc(sizeof(*addr))) == NULL) {
556
0
      sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
557
0
      goto done;
558
0
  }
559
0
  addr->sa_str = sudo_rcstr_addref(sa_str);
560
0
  addr->sa_host = sudo_rcstr_addref(sa_host);
561
562
0
  memcpy(&addr->sa_un, res->ai_addr, res->ai_addrlen);
563
0
  addr->sa_size = res->ai_addrlen;
564
0
  addr->tls = tls;
565
0
  TAILQ_INSERT_TAIL(addresses, addr, entries);
566
0
    }
567
568
0
    ret = true;
569
1.91k
done:
570
1.91k
    sudo_rcstr_delref(sa_str);
571
1.91k
    sudo_rcstr_delref(sa_host);
572
1.91k
    if (res0 != NULL)
573
0
  freeaddrinfo(res0);
574
1.91k
    free(copy);
575
1.91k
    debug_return_bool(ret);
576
1.91k
}
577
578
static bool
579
cb_server_listen_address(struct logsrvd_config *config, const char *str, size_t offset)
580
1.52k
{
581
1.52k
    return append_address(&config->server.addresses.addrs, str, true);
582
1.52k
}
583
584
static bool
585
cb_server_timeout(struct logsrvd_config *config, const char *str, size_t offset)
586
215
{
587
215
    time_t timeout;
588
215
    const char *errstr;
589
215
    debug_decl(cb_server_timeout, SUDO_DEBUG_UTIL);
590
591
215
    timeout = (time_t)sudo_strtonum(str, 0, TIME_T_MAX, &errstr);
592
215
    if (errstr != NULL)
593
6
  debug_return_bool(false);
594
595
209
    config->server.timeout.tv_sec = timeout;
596
597
209
    debug_return_bool(true);
598
209
}
599
600
static bool
601
cb_server_keepalive(struct logsrvd_config *config, const char *str, size_t offset)
602
205
{
603
205
    int val;
604
205
    debug_decl(cb_server_keepalive, SUDO_DEBUG_UTIL);
605
606
205
    if ((val = sudo_strtobool(str)) == -1)
607
4
  debug_return_bool(false);
608
609
201
    config->server.tcp_keepalive = val;
610
201
    debug_return_bool(true);
611
201
}
612
613
static bool
614
cb_server_pid_file(struct logsrvd_config *config, const char *str, size_t offset)
615
404
{
616
404
    char *copy = NULL;
617
404
    debug_decl(cb_server_pid_file, SUDO_DEBUG_UTIL);
618
619
    /* An empty value means to disable the pid file. */
620
404
    if (*str != '\0') {
621
209
  if (*str != '/') {
622
15
      sudo_warnx(U_("%s: not a fully qualified path"), str);
623
15
      debug_return_bool(false);
624
15
  }
625
194
  if ((copy = strdup(str)) == NULL) {
626
0
      sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
627
0
      debug_return_bool(false);
628
0
  }
629
194
    }
630
631
389
    free(config->server.pid_file);
632
389
    config->server.pid_file = copy;
633
634
389
    debug_return_bool(true);
635
389
}
636
637
static bool
638
cb_server_log(struct logsrvd_config *config, const char *str, size_t offset)
639
874
{
640
874
    char *copy = NULL;
641
874
    enum server_log_type log_type = SERVER_LOG_NONE;
642
874
    debug_decl(cb_server_log, SUDO_DEBUG_UTIL);
643
644
    /* An empty value means to disable the server log. */
645
874
    if (*str != '\0') {
646
679
  if (*str == '/') {
647
195
      log_type = SERVER_LOG_FILE;
648
195
      if ((copy = strdup(str)) == NULL) {
649
0
    sudo_warnx(U_("%s: %s"), __func__,
650
0
        U_("unable to allocate memory"));
651
0
    debug_return_bool(false);
652
0
      }
653
484
  } else if (strcmp(str, "stderr") == 0) {
654
196
      log_type = SERVER_LOG_STDERR;
655
288
  } else if (strcmp(str, "syslog") == 0) {
656
194
      log_type = SERVER_LOG_SYSLOG;
657
194
  } else {
658
94
      debug_return_bool(false);
659
94
  }
660
679
    }
661
662
780
    free(config->server.log_file);
663
780
    config->server.log_file = copy;
664
780
    config->server.log_type = log_type;
665
666
780
    debug_return_bool(true);
667
780
}
668
669
#if defined(HAVE_OPENSSL)
670
static bool
671
cb_tls_key(struct logsrvd_config *config, const char *path, size_t offset)
672
194
{
673
194
    char **p = (char **)((char *)config + offset);
674
194
    debug_decl(cb_tls_key, SUDO_DEBUG_UTIL);
675
676
194
    free(*p);
677
194
    if ((*p = strdup(path)) == NULL) {
678
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
679
0
        debug_return_bool(false);
680
0
    }
681
194
    debug_return_bool(true);
682
194
}
683
684
static bool
685
cb_tls_cacert(struct logsrvd_config *config, const char *path, size_t offset)
686
197
{
687
197
    char **p = (char **)((char *)config + offset);
688
197
    debug_decl(cb_tls_cacert, SUDO_DEBUG_UTIL);
689
690
197
    free(*p);
691
197
    if ((*p = strdup(path)) == NULL) {
692
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
693
0
        debug_return_bool(false);
694
0
    }
695
197
    debug_return_bool(true);
696
197
}
697
698
static bool
699
cb_tls_cert(struct logsrvd_config *config, const char *path, size_t offset)
700
197
{
701
197
    char **p = (char **)((char *)config + offset);
702
197
    debug_decl(cb_tls_cert, SUDO_DEBUG_UTIL);
703
704
197
    free(*p);
705
197
    if ((*p = strdup(path)) == NULL) {
706
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
707
0
        debug_return_bool(false);
708
0
    }
709
197
    debug_return_bool(true);
710
197
}
711
712
static bool
713
cb_tls_dhparams(struct logsrvd_config *config, const char *path, size_t offset)
714
194
{
715
194
    char **p = (char **)((char *)config + offset);
716
194
    debug_decl(cb_tls_dhparams, SUDO_DEBUG_UTIL);
717
718
194
    free(*p);
719
194
    if ((*p = strdup(path)) == NULL) {
720
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
721
0
        debug_return_bool(false);
722
0
    }
723
194
    debug_return_bool(true);
724
194
}
725
726
static bool
727
cb_tls_ciphers12(struct logsrvd_config *config, const char *str, size_t offset)
728
209
{
729
209
    char **p = (char **)((char *)config + offset);
730
209
    debug_decl(cb_tls_ciphers12, SUDO_DEBUG_UTIL);
731
732
209
    free(*p);
733
209
    if ((*p = strdup(str)) == NULL) {
734
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
735
0
        debug_return_bool(false);
736
0
    }
737
209
    debug_return_bool(true);
738
209
}
739
740
static bool
741
cb_tls_ciphers13(struct logsrvd_config *config, const char *str, size_t offset)
742
194
{
743
194
    char **p = (char **)((char *)config + offset);
744
194
    debug_decl(cb_tls_ciphers13, SUDO_DEBUG_UTIL);
745
746
194
    free(*p);
747
194
    if ((*p = strdup(str)) == NULL) {
748
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
749
0
        debug_return_bool(false);
750
0
    }
751
194
    debug_return_bool(true);
752
194
}
753
754
static bool
755
cb_tls_verify(struct logsrvd_config *config, const char *str, size_t offset)
756
506
{
757
506
    int *p = (int *)((char *)config + offset);
758
506
    int val;
759
506
    debug_decl(cb_tls_verify, SUDO_DEBUG_UTIL);
760
761
506
    if ((val = sudo_strtobool(str)) == -1)
762
163
  debug_return_bool(false);
763
764
343
    *p = val;
765
343
    debug_return_bool(true);
766
343
}
767
768
static bool
769
cb_tls_checkpeer(struct logsrvd_config *config, const char *str, size_t offset)
770
77
{
771
77
    int *p = (int *)((char *)config + offset);
772
77
    int val;
773
77
    debug_decl(cb_tls_checkpeer, SUDO_DEBUG_UTIL);
774
775
77
    if ((val = sudo_strtobool(str)) == -1)
776
4
  debug_return_bool(false);
777
778
73
    *p = val;
779
73
    debug_return_bool(true);
780
73
}
781
#endif
782
783
/* relay callbacks */
784
static bool
785
cb_relay_host(struct logsrvd_config *config, const char *str, size_t offset)
786
396
{
787
396
    return append_address(&config->relay.relays.addrs, str, false);
788
396
}
789
790
static bool
791
cb_relay_timeout(struct logsrvd_config *config, const char *str, size_t offset)
792
317
{
793
317
    time_t timeout;
794
317
    const char *errstr;
795
317
    debug_decl(cb_relay_timeout, SUDO_DEBUG_UTIL);
796
797
317
    timeout = (time_t)sudo_strtonum(str, 0, TIME_T_MAX, &errstr);
798
317
    if (errstr != NULL)
799
29
  debug_return_bool(false);
800
801
288
    config->server.timeout.tv_sec = timeout;
802
803
288
    debug_return_bool(true);
804
288
}
805
806
static bool
807
cb_relay_connect_timeout(struct logsrvd_config *config, const char *str, size_t offset)
808
346
{
809
346
    time_t timeout;
810
346
    const char *errstr;
811
346
    debug_decl(cb_relay_connect_timeout, SUDO_DEBUG_UTIL);
812
813
346
    timeout = (time_t)sudo_strtonum(str, 0, TIME_T_MAX, &errstr);
814
346
    if (errstr != NULL)
815
5
  debug_return_bool(false);
816
817
341
    config->relay.connect_timeout.tv_sec = timeout;
818
819
341
    debug_return_bool(true);
820
341
}
821
822
static bool
823
cb_relay_dir(struct logsrvd_config *config, const char *str, size_t offset)
824
4.23k
{
825
4.23k
    char *copy = NULL;
826
4.23k
    debug_decl(cb_relay_dir, SUDO_DEBUG_UTIL);
827
828
4.23k
    if ((copy = strdup(str)) == NULL) {
829
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
830
0
  debug_return_bool(false);
831
0
    }
832
833
4.23k
    free(config->relay.relay_dir);
834
4.23k
    config->relay.relay_dir = copy;
835
836
4.23k
    debug_return_bool(true);
837
4.23k
}
838
839
static bool
840
cb_retry_interval(struct logsrvd_config *config, const char *str, size_t offset)
841
230
{
842
230
    time_t interval;
843
230
    const char *errstr;
844
230
    debug_decl(cb_retry_interval, SUDO_DEBUG_UTIL);
845
846
230
    interval = (time_t)sudo_strtonum(str, 0, TIME_T_MAX, &errstr);
847
230
    if (errstr != NULL)
848
4
  debug_return_bool(false);
849
850
226
    config->relay.retry_interval = interval;
851
852
226
    debug_return_bool(true);
853
226
}
854
855
static bool
856
cb_relay_store_first(struct logsrvd_config *config, const char *str, size_t offset)
857
218
{
858
218
    int val;
859
218
    debug_decl(cb_relay_store_first, SUDO_DEBUG_UTIL);
860
861
218
    if ((val = sudo_strtobool(str)) == -1)
862
5
  debug_return_bool(false);
863
864
213
    config->relay.store_first = val;
865
213
    debug_return_bool(true);
866
213
}
867
868
static bool
869
cb_relay_keepalive(struct logsrvd_config *config, const char *str, size_t offset)
870
86
{
871
86
    int val;
872
86
    debug_decl(cb_relay_keepalive, SUDO_DEBUG_UTIL);
873
874
86
    if ((val = sudo_strtobool(str)) == -1)
875
5
  debug_return_bool(false);
876
877
81
    config->relay.tcp_keepalive = val;
878
81
    debug_return_bool(true);
879
81
}
880
881
/* eventlog callbacks */
882
static bool
883
cb_eventlog_type(struct logsrvd_config *config, const char *str, size_t offset)
884
660
{
885
660
    debug_decl(cb_eventlog_type, SUDO_DEBUG_UTIL);
886
887
660
    if (strcmp(str, "none") == 0)
888
254
  config->eventlog.log_type = EVLOG_NONE;
889
406
    else if (strcmp(str, "syslog") == 0)
890
194
  config->eventlog.log_type = EVLOG_SYSLOG;
891
212
    else if (strcmp(str, "logfile") == 0)
892
68
  config->eventlog.log_type = EVLOG_FILE;
893
144
    else
894
144
  debug_return_bool(false);
895
896
516
    debug_return_bool(true);
897
516
}
898
899
static bool
900
cb_eventlog_format(struct logsrvd_config *config, const char *str, size_t offset)
901
1.15k
{
902
1.15k
    debug_decl(cb_eventlog_format, SUDO_DEBUG_UTIL);
903
904
    /* FFR - make "json" an alias for EVLOG_JSON_COMPACT instead. */
905
1.15k
    if (strcmp(str, "json") == 0)
906
195
  config->eventlog.log_format = EVLOG_JSON_PRETTY;
907
963
    else if (strcmp(str, "json_compact") == 0)
908
195
  config->eventlog.log_format = EVLOG_JSON_COMPACT;
909
768
    else if (strcmp(str, "json_pretty") == 0)
910
194
  config->eventlog.log_format = EVLOG_JSON_PRETTY;
911
574
    else if (strcmp(str, "sudo") == 0)
912
380
  config->eventlog.log_format = EVLOG_SUDO;
913
194
    else
914
194
  debug_return_bool(false);
915
916
964
    debug_return_bool(true);
917
964
}
918
919
static bool
920
cb_eventlog_exit(struct logsrvd_config *config, const char *str, size_t offset)
921
3.40k
{
922
3.40k
    int val;
923
3.40k
    debug_decl(cb_eventlog_exit, SUDO_DEBUG_UTIL);
924
925
3.40k
    if ((val = sudo_strtobool(str)) == -1)
926
92
  debug_return_bool(false);
927
928
3.30k
    config->eventlog.log_exit = val;
929
3.30k
    debug_return_bool(true);
930
3.30k
}
931
932
/* syslog callbacks */
933
static bool
934
cb_syslog_maxlen(struct logsrvd_config *config, const char *str, size_t offset)
935
215
{
936
215
    unsigned int maxlen;
937
215
    const char *errstr;
938
215
    debug_decl(cb_syslog_maxlen, SUDO_DEBUG_UTIL);
939
940
215
    maxlen = (unsigned int)sudo_strtonum(str, 1, UINT_MAX, &errstr);
941
215
    if (errstr != NULL)
942
7
  debug_return_bool(false);
943
944
208
    config->syslog.maxlen = maxlen;
945
946
208
    debug_return_bool(true);
947
208
}
948
949
static bool
950
cb_syslog_server_facility(struct logsrvd_config *config, const char *str, size_t offset)
951
266
{
952
266
    int logfac;
953
266
    debug_decl(cb_syslog_server_facility, SUDO_DEBUG_UTIL);
954
955
266
    if (!sudo_str2logfac(str, &logfac)) {
956
7
  sudo_warnx(U_("unknown syslog facility %s"), str);
957
7
  debug_return_bool(false);
958
7
    }
959
960
259
    config->syslog.server_facility = logfac;
961
962
259
    debug_return_bool(true);
963
259
}
964
965
static bool
966
cb_syslog_facility(struct logsrvd_config *config, const char *str, size_t offset)
967
4.90k
{
968
4.90k
    int logfac;
969
4.90k
    debug_decl(cb_syslog_facility, SUDO_DEBUG_UTIL);
970
971
4.90k
    if (!sudo_str2logfac(str, &logfac)) {
972
101
  sudo_warnx(U_("unknown syslog facility %s"), str);
973
101
  debug_return_bool(false);
974
101
    }
975
976
4.80k
    config->syslog.facility = logfac;
977
978
4.80k
    debug_return_bool(true);
979
4.80k
}
980
981
static bool
982
cb_syslog_acceptpri(struct logsrvd_config *config, const char *str, size_t offset)
983
4.41k
{
984
4.41k
    int logpri;
985
4.41k
    debug_decl(cb_syslog_acceptpri, SUDO_DEBUG_UTIL);
986
987
4.41k
    if (!sudo_str2logpri(str, &logpri)) {
988
8
  sudo_warnx(U_("unknown syslog priority %s"), str);
989
8
  debug_return_bool(false);
990
8
    }
991
992
4.40k
    config->syslog.acceptpri = logpri;
993
994
4.40k
    debug_return_bool(true);
995
4.40k
}
996
997
static bool
998
cb_syslog_rejectpri(struct logsrvd_config *config, const char *str, size_t offset)
999
4.29k
{
1000
4.29k
    int logpri;
1001
4.29k
    debug_decl(cb_syslog_rejectpri, SUDO_DEBUG_UTIL);
1002
1003
4.29k
    if (!sudo_str2logpri(str, &logpri)) {
1004
8
  sudo_warnx(U_("unknown syslog priority %s"), str);
1005
8
  debug_return_bool(false);
1006
8
    }
1007
1008
4.28k
    config->syslog.rejectpri = logpri;
1009
1010
4.28k
    debug_return_bool(true);
1011
4.28k
}
1012
1013
static bool
1014
cb_syslog_alertpri(struct logsrvd_config *config, const char *str, size_t offset)
1015
5.59k
{
1016
5.59k
    int logpri;
1017
5.59k
    debug_decl(cb_syslog_alertpri, SUDO_DEBUG_UTIL);
1018
1019
5.59k
    if (!sudo_str2logpri(str, &logpri)) {
1020
103
  sudo_warnx(U_("unknown syslog priority %s"), str);
1021
103
  debug_return_bool(false);
1022
103
    }
1023
1024
5.49k
    config->syslog.alertpri = logpri;
1025
1026
5.49k
    debug_return_bool(true);
1027
5.49k
}
1028
1029
/* logfile callbacks */
1030
static bool
1031
cb_logfile_path(struct logsrvd_config *config, const char *str, size_t offset)
1032
4.61k
{
1033
4.61k
    char *copy = NULL;
1034
4.61k
    debug_decl(cb_logfile_path, SUDO_DEBUG_UTIL);
1035
1036
4.61k
    if (*str != '/') {
1037
17
  sudo_warnx(U_("%s: not a fully qualified path"), str);
1038
17
  debug_return_bool(false);
1039
17
    }
1040
4.59k
    if ((copy = strdup(str)) == NULL) {
1041
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1042
0
  debug_return_bool(false);
1043
0
    }
1044
1045
4.59k
    free(config->logfile.path);
1046
4.59k
    config->logfile.path = copy;
1047
1048
4.59k
    debug_return_bool(true);
1049
4.59k
}
1050
1051
static bool
1052
cb_logfile_time_format(struct logsrvd_config *config, const char *str, size_t offset)
1053
4.23k
{
1054
4.23k
    char *copy = NULL;
1055
4.23k
    debug_decl(cb_logfile_time_format, SUDO_DEBUG_UTIL);
1056
1057
4.23k
    if ((copy = strdup(str)) == NULL) {
1058
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1059
0
  debug_return_bool(false);
1060
0
    }
1061
1062
4.23k
    free(config->logfile.time_format);
1063
4.23k
    config->logfile.time_format = copy;
1064
1065
4.23k
    debug_return_bool(true);
1066
4.23k
}
1067
1068
void
1069
address_list_addref(struct server_address_list *al)
1070
0
{
1071
0
    struct address_list_container *container =
1072
0
  __containerof(al, struct address_list_container, addrs);
1073
0
    container->refcnt++;
1074
0
}
1075
1076
void
1077
address_list_delref(struct server_address_list *al)
1078
8.08k
{
1079
8.08k
    struct address_list_container *container =
1080
8.08k
  __containerof(al, struct address_list_container, addrs);
1081
8.08k
    if (--container->refcnt == 0) {
1082
8.08k
  struct server_address *addr;
1083
8.08k
  while ((addr = TAILQ_FIRST(al))) {
1084
0
      TAILQ_REMOVE(al, addr, entries);
1085
0
      sudo_rcstr_delref(addr->sa_str);
1086
0
      sudo_rcstr_delref(addr->sa_host);
1087
0
      free(addr);
1088
0
  }
1089
8.08k
    }
1090
8.08k
}
1091
1092
static struct logsrvd_config_entry server_conf_entries[] = {
1093
    { "listen_address", cb_server_listen_address },
1094
    { "timeout", cb_server_timeout },
1095
    { "tcp_keepalive", cb_server_keepalive },
1096
    { "pid_file", cb_server_pid_file },
1097
    { "server_log", cb_server_log },
1098
#if defined(HAVE_OPENSSL)
1099
    { "tls_key", cb_tls_key, offsetof(struct logsrvd_config, server.tls_key_path) },
1100
    { "tls_cacert", cb_tls_cacert, offsetof(struct logsrvd_config, server.tls_cacert_path) },
1101
    { "tls_cert", cb_tls_cert, offsetof(struct logsrvd_config, server.tls_cert_path) },
1102
    { "tls_dhparams", cb_tls_dhparams, offsetof(struct logsrvd_config, server.tls_dhparams_path) },
1103
    { "tls_ciphers_v12", cb_tls_ciphers12, offsetof(struct logsrvd_config, server.tls_ciphers_v12) },
1104
    { "tls_ciphers_v13", cb_tls_ciphers13, offsetof(struct logsrvd_config, server.tls_ciphers_v13) },
1105
    { "tls_checkpeer", cb_tls_checkpeer, offsetof(struct logsrvd_config, server.tls_check_peer) },
1106
    { "tls_verify", cb_tls_verify, offsetof(struct logsrvd_config, server.tls_verify) },
1107
#endif
1108
    { NULL }
1109
};
1110
1111
static struct logsrvd_config_entry relay_conf_entries[] = {
1112
    { "relay_host", cb_relay_host },
1113
    { "timeout", cb_relay_timeout },
1114
    { "connect_timeout", cb_relay_connect_timeout },
1115
    { "relay_dir", cb_relay_dir },
1116
    { "retry_interval", cb_retry_interval },
1117
    { "store_first", cb_relay_store_first },
1118
    { "tcp_keepalive", cb_relay_keepalive },
1119
#if defined(HAVE_OPENSSL)
1120
    { "tls_key", cb_tls_key, offsetof(struct logsrvd_config, relay.tls_key_path) },
1121
    { "tls_cacert", cb_tls_cacert, offsetof(struct logsrvd_config, relay.tls_cacert_path) },
1122
    { "tls_cert", cb_tls_cert, offsetof(struct logsrvd_config, relay.tls_cert_path) },
1123
    { "tls_dhparams", cb_tls_dhparams, offsetof(struct logsrvd_config, relay.tls_dhparams_path) },
1124
    { "tls_ciphers_v12", cb_tls_ciphers12, offsetof(struct logsrvd_config, relay.tls_ciphers_v12) },
1125
    { "tls_ciphers_v13", cb_tls_ciphers13, offsetof(struct logsrvd_config, relay.tls_ciphers_v13) },
1126
    { "tls_checkpeer", cb_tls_checkpeer, offsetof(struct logsrvd_config, relay.tls_check_peer) },
1127
    { "tls_verify", cb_tls_verify, offsetof(struct logsrvd_config, relay.tls_verify) },
1128
#endif
1129
    { NULL }
1130
};
1131
1132
static struct logsrvd_config_entry iolog_conf_entries[] = {
1133
    { "iolog_dir", cb_iolog_dir },
1134
    { "iolog_file", cb_iolog_file },
1135
    { "iolog_flush", cb_iolog_flush },
1136
    { "iolog_compress", cb_iolog_compress },
1137
    { "iolog_user", cb_iolog_user },
1138
    { "iolog_group", cb_iolog_group },
1139
    { "iolog_mode", cb_iolog_mode },
1140
    { "log_passwords", cb_iolog_log_passwords },
1141
    { "maxseq", cb_iolog_maxseq },
1142
    { "passprompt_regex", cb_iolog_passprompt_regex },
1143
    { NULL }
1144
};
1145
1146
static struct logsrvd_config_entry eventlog_conf_entries[] = {
1147
    { "log_type", cb_eventlog_type },
1148
    { "log_format", cb_eventlog_format },
1149
    { "log_exit", cb_eventlog_exit },
1150
    { NULL }
1151
};
1152
1153
static struct logsrvd_config_entry syslog_conf_entries[] = {
1154
    { "maxlen", cb_syslog_maxlen },
1155
    { "server_facility", cb_syslog_server_facility },
1156
    { "facility", cb_syslog_facility },
1157
    { "reject_priority", cb_syslog_rejectpri },
1158
    { "accept_priority", cb_syslog_acceptpri },
1159
    { "alert_priority", cb_syslog_alertpri },
1160
    { NULL }
1161
};
1162
1163
static struct logsrvd_config_entry logfile_conf_entries[] = {
1164
    { "path", cb_logfile_path },
1165
    { "time_format", cb_logfile_time_format },
1166
    { NULL }
1167
};
1168
1169
static struct logsrvd_config_section logsrvd_config_sections[] = {
1170
    { "server", server_conf_entries },
1171
    { "relay", relay_conf_entries },
1172
    { "iolog", iolog_conf_entries },
1173
    { "eventlog", eventlog_conf_entries },
1174
    { "syslog", syslog_conf_entries },
1175
    { "logfile", logfile_conf_entries },
1176
    { NULL }
1177
};
1178
1179
static bool
1180
logsrvd_conf_parse(struct logsrvd_config *config, FILE *fp, const char *path)
1181
4.04k
{
1182
4.04k
    struct logsrvd_config_section *conf_section = NULL;
1183
4.04k
    unsigned int lineno = 0;
1184
4.04k
    size_t linesize = 0;
1185
4.04k
    char *line = NULL;
1186
4.04k
    bool ret = false;
1187
4.04k
    debug_decl(logsrvd_conf_parse, SUDO_DEBUG_UTIL);
1188
1189
26.9k
    while (sudo_parseln(&line, &linesize, &lineno, fp, 0) != -1) {
1190
26.1k
  struct logsrvd_config_entry *entry;
1191
26.1k
  char *ep, *val;
1192
1193
  /* Skip blank, comment or invalid lines. */
1194
26.1k
  if (*line == '\0' || *line == ';')
1195
1.51k
      continue;
1196
1197
  /* New section */
1198
24.6k
  if (line[0] == '[') {
1199
4.23k
      char *cp, *section_name = line + 1;
1200
1201
4.23k
      if ((ep = strchr(section_name, ']')) == NULL) {
1202
48
    sudo_warnx(U_("%s:%d unmatched '[': %s"),
1203
48
        path, lineno, line);
1204
48
    goto done;
1205
48
      }
1206
4.54k
      for (cp = ep + 1; *cp != '\0'; cp++) {
1207
371
    if (!isspace((unsigned char)*cp)) {
1208
17
        sudo_warnx(U_("%s:%d garbage after ']': %s"),
1209
17
      path, lineno, line);
1210
17
        goto done;
1211
17
    }
1212
371
      }
1213
4.17k
      *ep = '\0';
1214
11.3k
      for (conf_section = logsrvd_config_sections; conf_section->name != NULL;
1215
11.2k
        conf_section++) {
1216
11.2k
    if (strcasecmp(section_name, conf_section->name) == 0)
1217
4.01k
        break;
1218
11.2k
      }
1219
4.17k
      if (conf_section->name == NULL) {
1220
152
    sudo_warnx(U_("%s:%d invalid config section: %s"),
1221
152
        path, lineno, section_name);
1222
152
    goto done;
1223
152
      }
1224
4.01k
      continue;
1225
4.17k
  }
1226
1227
20.3k
  if ((ep = strchr(line, '=')) == NULL) {
1228
218
      sudo_warnx(U_("%s:%d invalid configuration line: %s"),
1229
218
    path, lineno, line);
1230
218
      goto done;
1231
218
  }
1232
1233
20.1k
  if (conf_section == NULL) {
1234
25
      sudo_warnx(U_("%s:%d expected section name: %s"),
1235
25
    path, lineno, line);
1236
25
      goto done;
1237
25
  }
1238
1239
20.1k
  val = ep + 1;
1240
20.1k
  while (isspace((unsigned char)*val))
1241
212
      val++;
1242
20.3k
  while (ep > line && isspace((unsigned char)ep[-1]))
1243
198
      ep--;
1244
20.1k
  *ep = '\0';
1245
97.0k
  for (entry = conf_section->entries; entry->conf_str != NULL; entry++) {
1246
96.8k
      if (strcasecmp(line, entry->conf_str) == 0) {
1247
19.9k
    if (!entry->setter(config, val, entry->offset)) {
1248
2.62k
        sudo_warnx(U_("invalid value for %s: %s"),
1249
2.62k
      entry->conf_str, val);
1250
2.62k
        goto done;
1251
2.62k
    }
1252
17.3k
    break;
1253
19.9k
      }
1254
96.8k
  }
1255
17.5k
  if (entry->conf_str == NULL) {
1256
165
      sudo_warnx(U_("%s:%d [%s] illegal key: %s"), path, lineno,
1257
165
    conf_section->name, line);
1258
165
      goto done;
1259
165
  }
1260
17.5k
    }
1261
799
    ret = true;
1262
1263
4.04k
done:
1264
4.04k
    free(line);
1265
4.04k
    debug_return_bool(ret);
1266
4.04k
}
1267
1268
static FILE *
1269
logsrvd_open_log_file(const char *path, int flags)
1270
0
{
1271
0
    mode_t oldmask;
1272
0
    FILE *fp = NULL;
1273
0
    const char *omode;
1274
0
    int fd;
1275
0
    debug_decl(logsrvd_open_log_file, SUDO_DEBUG_UTIL);
1276
1277
0
    if (ISSET(flags, O_APPEND)) {
1278
0
  omode = "a";
1279
0
    } else {
1280
0
  omode = "w";
1281
0
    }
1282
0
    oldmask = umask(S_IRWXG|S_IRWXO);
1283
0
    fd = open(path, flags, S_IRUSR|S_IWUSR);
1284
0
    (void)umask(oldmask);
1285
0
    if (fd == -1 || (fp = fdopen(fd, omode)) == NULL) {
1286
0
  sudo_warn(U_("unable to open log file %s"), path);
1287
0
  if (fd != -1)
1288
0
      close(fd);
1289
0
    }
1290
1291
0
    debug_return_ptr(fp);
1292
0
}
1293
1294
static FILE *
1295
logsrvd_open_eventlog(struct logsrvd_config *config)
1296
0
{
1297
0
    int flags;
1298
0
    debug_decl(logsrvd_open_eventlog, SUDO_DEBUG_UTIL);
1299
1300
    /* Cannot append to a JSON file that is a single object. */
1301
0
    if (config->eventlog.log_format == EVLOG_JSON_PRETTY) {
1302
0
  flags = O_RDWR|O_CREAT;
1303
0
    } else {
1304
0
  flags = O_WRONLY|O_APPEND|O_CREAT;
1305
0
    }
1306
0
    debug_return_ptr(logsrvd_open_log_file(config->logfile.path, flags));
1307
0
}
1308
1309
static FILE *
1310
logsrvd_stub_open_log(int type, const char *logfile)
1311
0
{
1312
    /* Actual open already done by logsrvd_open_eventlog() */
1313
0
    return logsrvd_config->logfile.stream;
1314
0
}
1315
1316
static void
1317
logsrvd_stub_close_log(int type, FILE *fp)
1318
0
{
1319
0
    return;
1320
0
}
1321
1322
/* Set eventlog configuration settings from logsrvd config. */
1323
static void
1324
logsrvd_conf_eventlog_setconf(struct logsrvd_config *config)
1325
0
{
1326
0
    debug_decl(logsrvd_conf_eventlog_setconf, SUDO_DEBUG_UTIL);
1327
1328
0
    eventlog_set_type(config->eventlog.log_type);
1329
0
    eventlog_set_format(config->eventlog.log_format);
1330
0
    eventlog_set_syslog_acceptpri(config->syslog.acceptpri); 
1331
0
    eventlog_set_syslog_rejectpri(config->syslog.rejectpri); 
1332
0
    eventlog_set_syslog_alertpri(config->syslog.alertpri); 
1333
0
    eventlog_set_syslog_maxlen(config->syslog.maxlen); 
1334
0
    eventlog_set_logpath(config->logfile.path);
1335
0
    eventlog_set_time_fmt(config->logfile.time_format);
1336
0
    eventlog_set_open_log(logsrvd_stub_open_log);
1337
0
    eventlog_set_close_log(logsrvd_stub_close_log);
1338
1339
0
    debug_return;
1340
0
}
1341
1342
/* Set I/O log configuration settings from logsrvd config. */
1343
static void
1344
logsrvd_conf_iolog_setconf(struct logsrvd_config *config)
1345
0
{
1346
0
    debug_decl(logsrvd_conf_iolog_setconf, SUDO_DEBUG_UTIL);
1347
1348
0
    iolog_set_defaults();
1349
0
    iolog_set_compress(config->iolog.compress);
1350
0
    iolog_set_flush(config->iolog.flush);
1351
0
    iolog_set_owner(config->iolog.uid, config->iolog.gid);
1352
0
    iolog_set_mode(config->iolog.mode);
1353
0
    iolog_set_maxseq(config->iolog.maxseq);
1354
1355
0
    debug_return;
1356
0
}
1357
1358
/*
1359
 * Conversation function for use by sudo_warn/sudo_fatal.
1360
 * Logs to stdout/stderr.
1361
 */
1362
static int
1363
logsrvd_conv_stderr(int num_msgs, const struct sudo_conv_message msgs[],
1364
    struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
1365
0
{
1366
0
    int i;
1367
0
    debug_decl(logsrvd_conv_stderr, SUDO_DEBUG_UTIL);
1368
1369
0
    for (i = 0; i < num_msgs; i++) {
1370
0
  if (fputs(msgs[i].msg, stderr) == EOF)
1371
0
      debug_return_int(-1);
1372
0
    }
1373
1374
0
    debug_return_int(0);
1375
0
}
1376
1377
/*
1378
 * Conversation function for use by sudo_warn/sudo_fatal.
1379
 * Acts as a no-op log sink.
1380
 */
1381
static int
1382
logsrvd_conv_none(int num_msgs, const struct sudo_conv_message msgs[],
1383
    struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
1384
0
{
1385
    /* Also write to stderr if still in the foreground. */
1386
0
    if (logsrvd_warn_enable_stderr) {
1387
0
  (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
1388
0
    }
1389
1390
0
    return 0;
1391
0
}
1392
1393
/*
1394
 * Conversation function for use by sudo_warn/sudo_fatal.
1395
 * Logs to syslog.
1396
 */
1397
static int
1398
logsrvd_conv_syslog(int num_msgs, const struct sudo_conv_message msgs[],
1399
    struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
1400
0
{
1401
0
    char *buf = NULL, *cp = NULL;
1402
0
    const char *progname;
1403
0
    size_t proglen, bufsize = 0;
1404
0
    int i;
1405
0
    debug_decl(logsrvd_conv_syslog, SUDO_DEBUG_UTIL);
1406
1407
0
    if (logsrvd_config == NULL) {
1408
0
  debug_return_int(logsrvd_conv_stderr(num_msgs, msgs, replies, callback));
1409
0
    }
1410
1411
    /* Also write to stderr if still in the foreground. */
1412
0
    if (logsrvd_warn_enable_stderr) {
1413
0
  (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
1414
0
    }
1415
1416
    /*
1417
     * Concat messages into a flag string that we can syslog.
1418
     */
1419
0
    progname = getprogname();
1420
0
    proglen = strlen(progname);
1421
0
    for (i = 0; i < num_msgs; i++) {
1422
0
  const char *msg = msgs[i].msg;
1423
0
  size_t len = strlen(msg);
1424
0
  size_t used = (size_t)(cp - buf);
1425
1426
  /* Strip leading "sudo_logsrvd: " prefix. */
1427
0
  if (strncmp(msg, progname, proglen) == 0) {
1428
0
      msg += proglen;
1429
0
      len -= proglen;
1430
0
      if (len == 0) {
1431
    /* Skip over ": " string that follows program name. */
1432
0
    if (i + 1 < num_msgs && strcmp(msgs[i + 1].msg, ": ") == 0) {
1433
0
        i++;
1434
0
        continue;
1435
0
    }
1436
0
      } else if (msg[0] == ':' && msg[1] == ' ') {
1437
    /* Handle "progname: " */
1438
0
    msg += 2;
1439
0
    len -= 2;
1440
0
      }
1441
0
  }
1442
1443
  /* Strip off trailing newlines. */
1444
0
  while (len > 1 && msg[len - 1] == '\n')
1445
0
      len--;
1446
0
  if (len == 0)
1447
0
      continue;
1448
1449
0
  if (len >= bufsize - used) {
1450
0
      bufsize += 1024;
1451
0
      char *tmp = realloc(buf, bufsize);
1452
0
      if (tmp == NULL) {
1453
0
    sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1454
0
    free(buf);
1455
0
    debug_return_int(-1);
1456
0
      }
1457
0
      buf = tmp;
1458
0
      cp = tmp + used;
1459
0
  }
1460
0
  memcpy(cp, msg, len);
1461
0
  cp[len] = '\0';
1462
0
  cp += len;
1463
0
    }
1464
0
    if (buf != NULL) {
1465
0
  openlog(progname, 0, logsrvd_config->syslog.server_facility);
1466
0
  syslog(LOG_ERR, "%s", buf);
1467
0
  free(buf);
1468
1469
  /* Restore old syslog settings. */
1470
0
  if (logsrvd_config->eventlog.log_type == EVLOG_SYSLOG)
1471
0
      openlog("sudo", 0, logsrvd_config->syslog.facility);
1472
0
    }
1473
1474
0
    debug_return_int(0);
1475
0
}
1476
1477
/*
1478
 * Conversation function for use by sudo_warn/sudo_fatal.
1479
 * Logs to an already-open log file.
1480
 */
1481
static int
1482
logsrvd_conv_logfile(int num_msgs, const struct sudo_conv_message msgs[],
1483
    struct sudo_conv_reply replies[], struct sudo_conv_callback *callback)
1484
0
{
1485
0
    const char *progname;
1486
0
    size_t proglen;
1487
0
    int i;
1488
0
    debug_decl(logsrvd_conv_logfile, SUDO_DEBUG_UTIL);
1489
1490
0
    if (logsrvd_config == NULL) {
1491
0
  debug_return_int(logsrvd_conv_stderr(num_msgs, msgs, replies, callback));
1492
0
    }
1493
1494
    /* Also write to stderr if still in the foreground. */
1495
0
    if (logsrvd_warn_enable_stderr) {
1496
0
  (void)logsrvd_conv_stderr(num_msgs, msgs, replies, callback);
1497
0
    }
1498
1499
0
    if (logsrvd_config->server.log_stream == NULL) {
1500
0
  errno = EBADF;
1501
0
  debug_return_int(-1);
1502
0
    }
1503
1504
0
    progname = getprogname();
1505
0
    proglen = strlen(progname);
1506
0
    for (i = 0; i < num_msgs; i++) {
1507
0
  const char *msg = msgs[i].msg;
1508
0
  size_t len = strlen(msg);
1509
1510
  /* Strip leading "sudo_logsrvd: " prefix. */
1511
0
  if (strncmp(msg, progname, proglen) == 0) {
1512
0
      msg += proglen;
1513
0
      len -= proglen;
1514
0
      if (len == 0) {
1515
    /* Skip over ": " string that follows program name. */
1516
0
    if (i + 1 < num_msgs && strcmp(msgs[i + 1].msg, ": ") == 0) {
1517
0
        i++;
1518
0
        continue;
1519
0
    }
1520
0
      } else if (msg[0] == ':' && msg[1] == ' ') {
1521
    /* Handle "progname: " */
1522
0
    msg += 2;
1523
0
    len -= 2;
1524
0
      }
1525
0
  }
1526
1527
0
  if (fwrite(msg, len, 1, logsrvd_config->server.log_stream) != 1)
1528
0
      debug_return_int(-1);
1529
0
    }
1530
1531
0
    debug_return_int(0);
1532
0
}
1533
1534
/* Free the specified struct logsrvd_config and its contents. */
1535
static void
1536
logsrvd_conf_free(struct logsrvd_config *config)
1537
4.04k
{
1538
4.04k
    debug_decl(logsrvd_conf_free, SUDO_DEBUG_UTIL);
1539
1540
4.04k
    if (config == NULL)
1541
0
  debug_return;
1542
1543
    /* struct logsrvd_config_server */
1544
4.04k
    address_list_delref(&config->server.addresses.addrs);
1545
4.04k
    free(config->server.pid_file);
1546
4.04k
    free(config->server.log_file);
1547
4.04k
    if (config->server.log_stream != NULL)
1548
0
  fclose(config->server.log_stream);
1549
4.04k
#if defined(HAVE_OPENSSL)
1550
4.04k
    free(config->server.tls_key_path);
1551
4.04k
    free(config->server.tls_cert_path);
1552
4.04k
    free(config->server.tls_cacert_path);
1553
4.04k
    free(config->server.tls_dhparams_path);
1554
4.04k
    free(config->server.tls_ciphers_v12);
1555
4.04k
    free(config->server.tls_ciphers_v13);
1556
1557
4.04k
    if (config->server.ssl_ctx != NULL)
1558
0
  SSL_CTX_free(config->server.ssl_ctx);
1559
4.04k
#endif
1560
1561
    /* struct logsrvd_config_relay */
1562
4.04k
    address_list_delref(&config->relay.relays.addrs);
1563
4.04k
    free(config->relay.relay_dir);
1564
4.04k
#if defined(HAVE_OPENSSL)
1565
4.04k
    free(config->relay.tls_key_path);
1566
4.04k
    free(config->relay.tls_cert_path);
1567
4.04k
    free(config->relay.tls_cacert_path);
1568
4.04k
    free(config->relay.tls_dhparams_path);
1569
4.04k
    free(config->relay.tls_ciphers_v12);
1570
4.04k
    free(config->relay.tls_ciphers_v13);
1571
1572
4.04k
    if (config->relay.ssl_ctx != NULL)
1573
0
  SSL_CTX_free(config->relay.ssl_ctx);
1574
4.04k
#endif
1575
1576
    /* struct logsrvd_config_iolog */
1577
4.04k
    free(config->iolog.iolog_dir);
1578
4.04k
    free(config->iolog.iolog_file);
1579
4.04k
    iolog_pwfilt_free(config->iolog.passprompt_regex);
1580
1581
    /* struct logsrvd_config_logfile */
1582
4.04k
    free(config->logfile.path);
1583
4.04k
    free(config->logfile.time_format);
1584
4.04k
    if (config->logfile.stream != NULL)
1585
0
  fclose(config->logfile.stream);
1586
1587
4.04k
    free(config);
1588
1589
4.04k
    debug_return;
1590
4.04k
}
1591
1592
/* Allocate a new struct logsrvd_config and set default values. */
1593
static struct logsrvd_config *
1594
logsrvd_conf_alloc(void)
1595
4.04k
{
1596
4.04k
    struct logsrvd_config *config;
1597
4.04k
    debug_decl(logsrvd_conf_alloc, SUDO_DEBUG_UTIL);
1598
1599
4.04k
    if ((config = calloc(1, sizeof(*config))) == NULL) {
1600
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1601
0
  debug_return_ptr(NULL);
1602
0
    }
1603
1604
    /* Relay defaults */
1605
4.04k
    TAILQ_INIT(&config->relay.relays.addrs);
1606
4.04k
    config->relay.relays.refcnt = 1;
1607
4.04k
    config->relay.timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC;
1608
4.04k
    config->relay.connect_timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC;
1609
4.04k
    config->relay.tcp_keepalive = true;
1610
4.04k
    config->relay.retry_interval = 30;
1611
4.04k
    if (!cb_relay_dir(config, _PATH_SUDO_RELAY_DIR, 0))
1612
0
  goto bad;
1613
4.04k
#if defined(HAVE_OPENSSL)
1614
4.04k
    config->relay.tls_verify = -1;
1615
4.04k
    config->relay.tls_check_peer = -1;
1616
4.04k
#endif
1617
1618
    /* Server defaults */
1619
4.04k
    TAILQ_INIT(&config->server.addresses.addrs);
1620
4.04k
    config->server.addresses.refcnt = 1;
1621
4.04k
    config->server.timeout.tv_sec = DEFAULT_SOCKET_TIMEOUT_SEC;
1622
4.04k
    config->server.tcp_keepalive = true;
1623
4.04k
    config->server.log_type = SERVER_LOG_SYSLOG;
1624
4.04k
    config->server.pid_file = strdup(_PATH_SUDO_LOGSRVD_PID);
1625
4.04k
    if (config->server.pid_file == NULL) {
1626
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1627
0
  goto bad;
1628
0
    }
1629
1630
4.04k
#if defined(HAVE_OPENSSL)
1631
    /*
1632
     * Only set default CA and cert paths if the files actually exist.
1633
     * This ensures we don't enable TLS by default when it is not configured.
1634
     */
1635
4.04k
    if (access(DEFAULT_CA_CERT_PATH, R_OK) == 0) {
1636
0
  config->server.tls_cacert_path = strdup(DEFAULT_CA_CERT_PATH);
1637
0
  if (config->server.tls_cacert_path == NULL) {
1638
0
      sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1639
0
      goto bad;
1640
0
  }
1641
0
    }
1642
4.04k
    if (access(DEFAULT_SERVER_CERT_PATH, R_OK) == 0) {
1643
0
  config->server.tls_cert_path = strdup(DEFAULT_SERVER_CERT_PATH);
1644
0
  if (config->server.tls_cert_path == NULL) {
1645
0
      sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1646
0
      goto bad;
1647
0
  }
1648
0
    }
1649
4.04k
    config->server.tls_key_path = strdup(DEFAULT_SERVER_KEY_PATH);
1650
4.04k
    if (config->server.tls_key_path == NULL) {
1651
0
  sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1652
0
  goto bad;
1653
0
    }
1654
4.04k
    config->server.tls_verify = true;
1655
4.04k
    config->server.tls_check_peer = false;
1656
4.04k
#endif
1657
1658
    /* I/O log defaults */
1659
4.04k
    config->iolog.compress = false;
1660
4.04k
    config->iolog.flush = true;
1661
4.04k
    config->iolog.mode = S_IRUSR|S_IWUSR;
1662
4.04k
    config->iolog.maxseq = SESSID_MAX;
1663
4.04k
    if (!cb_iolog_dir(config, _PATH_SUDO_IO_LOGDIR, 0))
1664
0
  goto bad;
1665
4.04k
    if (!cb_iolog_file(config, "%{seq}", 0))
1666
0
  goto bad;
1667
4.04k
    config->iolog.uid = ROOT_UID;
1668
4.04k
    config->iolog.gid = ROOT_GID;
1669
4.04k
    config->iolog.gid_set = false;
1670
4.04k
    config->iolog.log_passwords = true;
1671
1672
    /* Event log defaults */
1673
4.04k
    config->eventlog.log_type = EVLOG_SYSLOG;
1674
4.04k
    config->eventlog.log_format = EVLOG_SUDO;
1675
4.04k
    config->eventlog.log_exit = false;
1676
1677
    /* Syslog defaults */
1678
4.04k
    config->syslog.maxlen = 960;
1679
4.04k
    config->syslog.server_facility = LOG_DAEMON;
1680
4.04k
    if (!cb_syslog_facility(config, LOGFAC, 0)) {
1681
0
  sudo_warnx(U_("unknown syslog facility %s"), LOGFAC);
1682
0
  goto bad;
1683
0
    }
1684
4.04k
    if (!cb_syslog_acceptpri(config, PRI_SUCCESS, 0)) {
1685
0
  sudo_warnx(U_("unknown syslog priority %s"), PRI_SUCCESS);
1686
0
  goto bad;
1687
0
    }
1688
4.04k
    if (!cb_syslog_rejectpri(config, PRI_FAILURE, 0)) {
1689
0
  sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
1690
0
  goto bad;
1691
0
    }
1692
4.04k
    if (!cb_syslog_alertpri(config, PRI_FAILURE, 0)) {
1693
0
  sudo_warnx(U_("unknown syslog priority %s"), PRI_FAILURE);
1694
0
  goto bad;
1695
0
    }
1696
1697
    /* Log file defaults */
1698
4.04k
    if (!cb_logfile_time_format(config, "%h %e %T", 0))
1699
0
  goto bad;
1700
4.04k
    if (!cb_logfile_path(config, _PATH_SUDO_LOGFILE, 0))
1701
0
  goto bad;
1702
1703
4.04k
    debug_return_ptr(config);
1704
0
bad:
1705
0
    logsrvd_conf_free(config);
1706
0
    debug_return_ptr(NULL);
1707
0
}
1708
1709
static bool
1710
logsrvd_conf_apply(struct logsrvd_config *config)
1711
799
{
1712
799
#if defined(HAVE_OPENSSL)
1713
799
    struct server_address *addr;
1714
799
#endif
1715
799
    debug_decl(logsrvd_conf_apply, SUDO_DEBUG_UTIL);
1716
1717
    /* There can be multiple passprompt regular expressions. */
1718
799
    if (config->iolog.passprompt_regex == NULL) {
1719
779
  if (!cb_iolog_passprompt_regex(config, PASSPROMPT_REGEX, 0))
1720
0
      debug_return_bool(false);
1721
779
    }
1722
1723
    /* There can be multiple addresses so we can't set a default earlier. */
1724
799
    if (TAILQ_EMPTY(&config->server.addresses.addrs)) {
1725
  /* Enable plaintext listender. */
1726
799
  if (!cb_server_listen_address(config, "*:" DEFAULT_PORT, 0))
1727
799
      debug_return_bool(false);
1728
0
#if defined(HAVE_OPENSSL)
1729
  /* If a certificate was specified, enable the TLS listener too. */
1730
0
  if (config->server.tls_cert_path != NULL) {
1731
0
      if (!cb_server_listen_address(config, "*:" DEFAULT_PORT_TLS "(tls)", 0))
1732
0
    debug_return_bool(false);
1733
0
  }
1734
0
    } else {
1735
  /* Check that TLS configuration is valid. */
1736
0
  TAILQ_FOREACH(addr, &config->server.addresses.addrs, entries) {
1737
0
      if (!addr->tls)
1738
0
    continue;
1739
      /*
1740
       * If a TLS listener was explicitly enabled but the cert path
1741
       * was not, use the default.
1742
       */
1743
0
      if (config->server.tls_cert_path == NULL) {
1744
0
    config->server.tls_cert_path =
1745
0
        strdup(DEFAULT_SERVER_CERT_PATH);
1746
0
    if (config->server.tls_cert_path == NULL) {
1747
0
        sudo_warnx(U_("%s: %s"), __func__,
1748
0
      U_("unable to allocate memory"));
1749
0
        debug_return_bool(false);
1750
0
    }
1751
0
      }
1752
0
      break;
1753
0
  }
1754
0
#endif /* HAVE_OPENSSL */
1755
0
    }
1756
1757
0
#if defined(HAVE_OPENSSL)
1758
0
    TAILQ_FOREACH(addr, &config->server.addresses.addrs, entries) {
1759
0
  if (!addr->tls)
1760
0
      continue;
1761
        /* Create a TLS context for the server. */
1762
0
  config->server.ssl_ctx = init_tls_context(
1763
0
      config->server.tls_cacert_path, config->server.tls_cert_path,
1764
0
      config->server.tls_key_path, config->server.tls_dhparams_path,
1765
0
      config->server.tls_ciphers_v12, config->server.tls_ciphers_v13,
1766
0
      config->server.tls_verify);
1767
0
  if (config->server.ssl_ctx == NULL) {
1768
0
      sudo_warnx("%s", U_("unable to initialize server TLS context"));
1769
0
      debug_return_bool(false);
1770
0
  }
1771
0
  break;
1772
0
    }
1773
1774
0
    if (TLS_CONFIGURED(config->relay)) {
1775
0
  TAILQ_FOREACH(addr, &config->relay.relays.addrs, entries) {
1776
0
      if (!addr->tls)
1777
0
    continue;
1778
      /* Create a TLS context for the relay. */
1779
0
      config->relay.ssl_ctx = init_tls_context(
1780
0
    TLS_RELAY_STR(config, tls_cacert_path),
1781
0
    TLS_RELAY_STR(config, tls_cert_path),
1782
0
    TLS_RELAY_STR(config, tls_key_path),
1783
0
    TLS_RELAY_STR(config, tls_dhparams_path),
1784
0
    TLS_RELAY_STR(config, tls_ciphers_v12),
1785
0
    TLS_RELAY_STR(config, tls_ciphers_v13),
1786
0
    TLS_RELAY_INT(config, tls_verify));
1787
0
      if (config->relay.ssl_ctx == NULL) {
1788
0
    sudo_warnx("%s", U_("unable to initialize relay TLS context"));
1789
0
    debug_return_bool(false);
1790
0
      }
1791
0
      break;
1792
0
  }
1793
0
    }
1794
0
#endif /* HAVE_OPENSSL */
1795
1796
    /* Clear store_first if not relaying. */
1797
0
    if (TAILQ_EMPTY(&config->relay.relays.addrs))
1798
0
  config->relay.store_first = false;
1799
1800
    /* Open server log if specified. */
1801
0
    switch (config->server.log_type) {
1802
0
    case SERVER_LOG_SYSLOG:
1803
0
  sudo_warn_set_conversation(logsrvd_conv_syslog);
1804
0
  break;
1805
0
    case SERVER_LOG_FILE:
1806
0
  config->server.log_stream =
1807
0
      logsrvd_open_log_file(config->server.log_file, O_WRONLY|O_APPEND|O_CREAT);
1808
0
  if (config->server.log_stream == NULL)
1809
0
      debug_return_bool(false);
1810
0
  sudo_warn_set_conversation(logsrvd_conv_logfile);
1811
0
  break;
1812
0
    case SERVER_LOG_NONE:
1813
0
  sudo_warn_set_conversation(logsrvd_conv_none);
1814
0
  break;
1815
0
    case SERVER_LOG_STDERR:
1816
  /* Default is stderr. */
1817
0
  sudo_warn_set_conversation(NULL);
1818
0
  break;
1819
0
    default:
1820
0
  sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
1821
0
      "cannot open unknown log type %d", config->eventlog.log_type);
1822
0
  break;
1823
0
    }
1824
1825
    /* Open event log if specified. */
1826
0
    switch (config->eventlog.log_type) {
1827
0
    case EVLOG_SYSLOG:
1828
0
  openlog("sudo", 0, config->syslog.facility);
1829
0
  break;
1830
0
    case EVLOG_FILE:
1831
0
  config->logfile.stream = logsrvd_open_eventlog(config);
1832
0
  if (config->logfile.stream == NULL)
1833
0
      debug_return_bool(false);
1834
0
  break;
1835
0
    case EVLOG_NONE:
1836
0
  break;
1837
0
    default:
1838
0
  sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
1839
0
      "cannot open unknown log type %d", config->eventlog.log_type);
1840
0
  break;
1841
0
    }
1842
1843
    /*
1844
     * Update event and I/O log library config and install the new
1845
     * logsrvd config.  We must not fail past this point or the event
1846
     * and I/O log config will be inconsistent with the logsrvd config.
1847
     */
1848
0
    logsrvd_conf_iolog_setconf(config);
1849
0
    logsrvd_conf_eventlog_setconf(config);
1850
1851
0
    logsrvd_conf_free(logsrvd_config);
1852
0
    logsrvd_config = config;
1853
1854
0
    debug_return_bool(true);
1855
0
}
1856
1857
/*
1858
 * Read .ini style logsrvd.conf file.
1859
 * If path is NULL, use _PATH_SUDO_LOGSRVD_CONF.
1860
 * Note that we use '#' not ';' for the comment character.
1861
 */
1862
bool
1863
logsrvd_conf_read(const char *path)
1864
4.04k
{
1865
4.04k
    struct logsrvd_config *config;
1866
4.04k
    char conf_file[PATH_MAX];
1867
4.04k
    bool ret = false;
1868
4.04k
    FILE *fp = NULL;
1869
4.04k
    int fd = -1;
1870
4.04k
    debug_decl(logsrvd_conf_read, SUDO_DEBUG_UTIL);
1871
1872
4.04k
    config = logsrvd_conf_alloc();
1873
1874
4.04k
    if (path != NULL) {
1875
4.04k
       if (strlcpy(conf_file, path, sizeof(conf_file)) >= sizeof(conf_file))
1876
0
            errno = ENAMETOOLONG;
1877
4.04k
  else
1878
4.04k
      fd = open(conf_file, O_RDONLY);
1879
4.04k
    } else {
1880
0
  fd = sudo_open_conf_path(_PATH_SUDO_LOGSRVD_CONF, conf_file,
1881
0
      sizeof(conf_file), NULL);
1882
0
    }
1883
4.04k
    if (fd != -1)
1884
4.04k
  fp = fdopen(fd, "r");
1885
4.04k
    if (fp == NULL) {
1886
0
  if (path != NULL || errno != ENOENT) {
1887
0
      sudo_warn("%s", conf_file);
1888
0
      goto done;
1889
0
  }
1890
4.04k
    } else {
1891
4.04k
  if (!logsrvd_conf_parse(config, fp, conf_file))
1892
3.24k
      goto done;
1893
4.04k
    }
1894
1895
    /* Install new config */
1896
799
    if (logsrvd_conf_apply(config)) {
1897
0
  config = NULL;
1898
0
  ret = true;
1899
0
    }
1900
1901
4.04k
done:
1902
4.04k
    logsrvd_conf_free(config);
1903
4.04k
    if (fp != NULL)
1904
4.04k
  fclose(fp);
1905
4.04k
    debug_return_bool(ret);
1906
4.04k
}
1907
1908
void
1909
logsrvd_conf_cleanup(void)
1910
0
{
1911
0
    debug_decl(logsrvd_conf_cleanup, SUDO_DEBUG_UTIL);
1912
1913
0
    logsrvd_conf_free(logsrvd_config);
1914
0
    logsrvd_config = NULL;
1915
1916
0
    debug_return;
1917
0
}
1918
1919
void
1920
logsrvd_warn_stderr(bool enabled)
1921
0
{
1922
0
    logsrvd_warn_enable_stderr = enabled;
1923
0
}