Coverage Report

Created: 2025-12-28 06:49

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