Coverage Report

Created: 2026-02-26 06:07

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