Coverage Report

Created: 2025-10-10 07:09

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