Coverage Report

Created: 2026-10-17 06:18

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