Coverage Report

Created: 2025-10-28 06:13

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