/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

  • Committer: Teddy Hogeborn
  • Date: 2019-08-18 00:42:22 UTC
  • Revision ID: teddy@recompile.se-20190818004222-lfrgtnmqz766a08e
Client: Use the systemd sysusers.d mechanism, if present

* Makefile (install-client-nokey): Also install sysusers.d file, if
                                   $(SYSUSERS) exists.
* sysusers.d-mandos.conf: Adjust comment to match reality.

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 * "browse_callback", and parts of "main".
10
10
 * 
11
11
 * Everything else is
12
 
 * Copyright © 2008-2021 Teddy Hogeborn
13
 
 * Copyright © 2008-2021 Björn Påhlsson
 
12
 * Copyright © 2008-2019 Teddy Hogeborn
 
13
 * Copyright © 2008-2019 Björn Påhlsson
14
14
 * 
15
15
 * This file is part of Mandos.
16
16
 * 
38
38
#define _FILE_OFFSET_BITS 64
39
39
#endif  /* not _FILE_OFFSET_BITS */
40
40
 
41
 
#define _GNU_SOURCE             /* program_invocation_short_name,
42
 
                                   TEMP_FAILURE_RETRY(), O_CLOEXEC,
43
 
                                   scandirat(), asprintf() */
 
41
#define _GNU_SOURCE             /* TEMP_FAILURE_RETRY(), asprintf() */
 
42
 
 
43
#include <stdio.h>              /* fprintf(), stderr, fwrite(),
 
44
                                   stdout, ferror() */
 
45
#include <stdint.h>             /* uint16_t, uint32_t, intptr_t */
 
46
#include <stddef.h>             /* NULL, size_t, ssize_t */
 
47
#include <stdlib.h>             /* free(), EXIT_SUCCESS, srand(),
 
48
                                   strtof(), abort() */
44
49
#include <stdbool.h>            /* bool, false, true */
45
 
#include <argp.h>               /* argp_program_version,
46
 
                                   argp_program_bug_address,
47
 
                                   struct argp_option,
48
 
                                   struct argp_state, argp_error(),
49
 
                                   argp_state_help,
50
 
                                   ARGP_HELP_STD_HELP,
51
 
                                   ARGP_HELP_EXIT_ERR,
52
 
                                   ARGP_HELP_EXIT_OK, ARGP_HELP_USAGE,
53
 
                                   argp_err_exit_status,
54
 
                                   ARGP_ERR_UNKNOWN, struct argp,
55
 
                                   argp_parse(), ARGP_IN_ORDER,
56
 
                                   ARGP_NO_HELP */
57
 
#include <stddef.h>             /* NULL, size_t */
58
 
#include <sys/types.h>          /* uid_t, gid_t, sig_atomic_t,
59
 
                                   seteuid(), setuid(), pid_t,
60
 
                                   setgid(), getuid(), getgid() */
61
 
#include <unistd.h>             /* uid_t, gid_t, TEMP_FAILURE_RETRY(),
62
 
                                   seteuid(), setuid(), close(),
63
 
                                   ssize_t, read(), fork(), setgid(),
64
 
                                   _exit(), dup2(), STDIN_FILENO,
65
 
                                   STDERR_FILENO, STDOUT_FILENO,
66
 
                                   fexecve(), write(), getuid(),
67
 
                                   getgid(), fchown(), symlink(),
68
 
                                   sleep(), unlinkat(), pause() */
69
 
#include <netinet/in.h>         /* in_port_t, struct sockaddr_in6,
70
 
                                   sa_family_t, struct sockaddr_in,
71
 
                                   htons(), IN6_IS_ADDR_LINKLOCAL,
72
 
                                   INET_ADDRSTRLEN, INET6_ADDRSTRLEN,
73
 
                                   ntohl(), IPPROTO_IP */
74
 
#include <time.h>               /* struct timespec, clock_gettime(),
75
 
                                   CLOCK_MONOTONIC, time_t, struct tm,
76
 
                                   gmtime_r(), clock_settime(),
77
 
                                   CLOCK_REALTIME, nanosleep() */
78
 
#include <errno.h>              /* errno,
79
 
                                   program_invocation_short_name,
80
 
                                   EINTR, EINVAL, ENETUNREACH,
 
50
#include <string.h>             /* strcmp(), strlen(), strerror(),
 
51
                                   asprintf(), strncpy(), strsignal()
 
52
                                */
 
53
#include <sys/ioctl.h>          /* ioctl */
 
54
#include <sys/types.h>          /* socket(), inet_pton(), sockaddr,
 
55
                                   sockaddr_in6, PF_INET6,
 
56
                                   SOCK_STREAM, uid_t, gid_t, open(),
 
57
                                   opendir(), DIR */
 
58
#include <sys/stat.h>           /* open(), S_ISREG */
 
59
#include <sys/socket.h>         /* socket(), struct sockaddr_in6,
 
60
                                   inet_pton(), connect(),
 
61
                                   getnameinfo() */
 
62
#include <fcntl.h>              /* open(), unlinkat(), AT_REMOVEDIR */
 
63
#include <dirent.h>             /* opendir(), struct dirent, readdir()
 
64
                                 */
 
65
#include <inttypes.h>           /* PRIu16, PRIdMAX, intmax_t,
 
66
                                   strtoimax() */
 
67
#include <errno.h>              /* perror(), errno, EINTR, EINVAL,
 
68
                                   EAI_SYSTEM, ENETUNREACH,
81
69
                                   EHOSTUNREACH, ECONNREFUSED, EPROTO,
82
 
                                   EIO, ENOENT, ENXIO, error_t,
83
 
                                   ENOMEM, EISDIR, ENOTEMPTY */
84
 
#include <stdio.h>              /* fprintf(), stderr, perror(), FILE,
85
 
                                   vfprintf(), off_t, SEEK_SET,
86
 
                                   stdout, fwrite(), ferror(),
87
 
                                   fflush(), asprintf() */
88
 
#include <stdarg.h>             /* va_list, va_start(), vfprintf() */
89
 
#include <stdlib.h>             /* realloc(), free(), malloc(),
90
 
                                   getenv(), EXIT_FAILURE, setenv(),
91
 
                                   EXIT_SUCCESS, strtof(), strtod(),
92
 
                                   srand(), mkdtemp(), abort() */
93
 
#include <string.h>             /* strdup(), strcmp(), strlen(),
94
 
                                   strerror(), strncpy(), strspn(),
95
 
                                   memcpy(), strrchr(), strchr(),
96
 
                                   strsignal() */
97
 
#include <fcntl.h>              /* open(), O_RDONLY, O_DIRECTORY,
98
 
                                   O_PATH, O_CLOEXEC, openat(),
99
 
                                   O_NOFOLLOW, AT_REMOVEDIR */
100
 
#include <iso646.h>             /* or, and, not */
101
 
#include <sys/stat.h>           /* struct stat, fstat(), fstatat(),
102
 
                                   S_ISREG(), S_IXUSR, S_IXGRP,
103
 
                                   S_IXOTH, lstat() */
104
 
#include <net/if.h>             /* IF_NAMESIZE, if_indextoname(),
105
 
                                   if_nametoindex(), SIOCGIFFLAGS,
106
 
                                   IFF_LOOPBACK, IFF_POINTOPOINT,
107
 
                                   IFF_BROADCAST, IFF_NOARP, IFF_UP,
108
 
                                   IFF_RUNNING, SIOCSIFFLAGS */
109
 
#include <sysexits.h>           /* EX_NOPERM, EX_OSERR,
110
 
                                   EX_UNAVAILABLE, EX_USAGE */
 
70
                                   EIO, ENOENT, ENXIO, ENOMEM, EISDIR,
 
71
                                   ENOTEMPTY,
 
72
                                   program_invocation_short_name */
 
73
#include <time.h>               /* nanosleep(), time(), sleep() */
 
74
#include <net/if.h>             /* ioctl, ifreq, SIOCGIFFLAGS, IFF_UP,
 
75
                                   SIOCSIFFLAGS, if_indextoname(),
 
76
                                   if_nametoindex(), IF_NAMESIZE */
 
77
#include <netinet/in.h>         /* IN6_IS_ADDR_LINKLOCAL,
 
78
                                   INET_ADDRSTRLEN, INET6_ADDRSTRLEN
 
79
                                */
 
80
#include <unistd.h>             /* close(), SEEK_SET, off_t, write(),
 
81
                                   getuid(), getgid(), seteuid(),
 
82
                                   setgid(), pause(), _exit(),
 
83
                                   unlinkat() */
 
84
#include <arpa/inet.h>          /* inet_pton(), htons() */
 
85
#include <iso646.h>             /* not, or, and */
 
86
#include <argp.h>               /* struct argp_option, error_t, struct
 
87
                                   argp_state, struct argp,
 
88
                                   argp_parse(), ARGP_KEY_ARG,
 
89
                                   ARGP_KEY_END, ARGP_ERR_UNKNOWN */
 
90
#include <signal.h>             /* sigemptyset(), sigaddset(),
 
91
                                   sigaction(), SIGTERM, sig_atomic_t,
 
92
                                   raise() */
 
93
#include <sysexits.h>           /* EX_OSERR, EX_USAGE, EX_UNAVAILABLE,
 
94
                                   EX_NOHOST, EX_IOERR, EX_PROTOCOL */
 
95
#include <sys/wait.h>           /* waitpid(), WIFEXITED(),
 
96
                                   WEXITSTATUS(), WTERMSIG() */
111
97
#include <grp.h>                /* setgroups() */
112
 
#include <sys/wait.h>           /* waitpid(), WIFEXITED(),
113
 
                                   WEXITSTATUS(), WIFSIGNALED(),
114
 
                                   WTERMSIG() */
115
 
#include <signal.h>             /* kill(), SIGTERM, struct sigaction,
116
 
                                   SIG_DFL, sigemptyset(),
117
 
                                   sigaddset(), SIGINT, SIGHUP,
118
 
                                   SIG_IGN, raise() */
119
 
#include <sys/socket.h>         /* struct sockaddr_storage, AF_INET6,
120
 
                                   PF_INET6, AF_INET, PF_INET,
121
 
                                   socket(), SOCK_STREAM,
122
 
                                   SOCK_CLOEXEC, struct sockaddr,
123
 
                                   connect(), SOCK_DGRAM */
124
 
#include <argz.h>               /* argz_next(), argz_add_sep(),
125
 
                                   argz_delete(), argz_stringify(),
126
 
                                   argz_add(), argz_count() */
127
 
#include <inttypes.h>           /* PRIuMAX, uintmax_t, uint32_t,
128
 
                                   PRIdMAX, PRIu16, intmax_t,
129
 
                                   strtoimax() */
130
 
#include <arpa/inet.h>          /* inet_pton() */
131
 
#include <stdint.h>             /* uint32_t, intptr_t, uint16_t */
 
98
#include <argz.h>               /* argz_add_sep(), argz_next(),
 
99
                                   argz_delete(), argz_append(),
 
100
                                   argz_stringify(), argz_add(),
 
101
                                   argz_count() */
132
102
#include <netdb.h>              /* getnameinfo(), NI_NUMERICHOST,
133
103
                                   EAI_SYSTEM, gai_strerror() */
134
 
#include <sys/ioctl.h>          /* ioctl() */
135
 
#include <dirent.h>             /* struct dirent, scandirat(),
136
 
                                   alphasort(), scandir() */
137
 
#include <limits.h>             /* INT_MAX */
138
104
 
139
105
#ifdef __linux__
140
106
#include <sys/klog.h>           /* klogctl() */
153
119
 
154
120
/* GnuTLS */
155
121
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and
156
 
                                   functions: gnutls_*, GNUTLS_* */
 
122
                                   functions:
 
123
                                   gnutls_*
 
124
                                   init_gnutls_session(),
 
125
                                   GNUTLS_* */
157
126
#if GNUTLS_VERSION_NUMBER < 0x030600
158
127
#include <gnutls/openpgp.h>
159
128
                         /* gnutls_certificate_set_openpgp_key_file(),
160
129
                            GNUTLS_OPENPGP_FMT_BASE64 */
161
130
#elif GNUTLS_VERSION_NUMBER >= 0x030606
162
 
#include <gnutls/x509.h>        /* GNUTLS_PKCS_PLAIN,
163
 
                                   GNUTLS_PKCS_NULL_PASSWORD */
 
131
#include <gnutls/x509.h>        /* gnutls_pkcs_encrypt_flags_t,
 
132
                                 GNUTLS_PKCS_PLAIN,
 
133
                                 GNUTLS_PKCS_NULL_PASSWORD */
164
134
#endif
165
135
 
166
136
/* GPGME */
167
137
#include <gpgme.h>              /* All GPGME types, constants and
168
138
                                   functions:
169
 
                                   gpgme_*, GPG_ERR_NO_*,
170
 
                                   GPGME_IMPORT_*
171
 
                                   GPGME_PROTOCOL_OpenPGP */
 
139
                                   gpgme_*
 
140
                                   GPGME_PROTOCOL_OpenPGP,
 
141
                                   GPG_ERR_NO_* */
172
142
 
173
143
#define BUFFER_SIZE 256
174
144
 
426
396
        fprintf_plus(stderr,
427
397
                     "Setting system clock to key file mtime");
428
398
      }
429
 
      if(clock_settime(CLOCK_REALTIME, &keystat.st_mtim) != 0){
430
 
        perror_plus("clock_settime");
 
399
      time_t keytime = keystat.st_mtim.tv_sec;
 
400
      if(stime(&keytime) != 0){
 
401
        perror_plus("stime");
431
402
      }
432
403
      ret = lower_privileges();
433
404
      if(ret != 0){
1103
1074
      ret = setgid(0);
1104
1075
      if(ret == -1){
1105
1076
        perror_plus("setgid");
1106
 
        close(devnull);
1107
1077
        _exit(EX_NOPERM);
1108
1078
      }
1109
1079
      /* Reset supplementary groups */
1111
1081
      ret = setgroups(0, NULL);
1112
1082
      if(ret == -1){
1113
1083
        perror_plus("setgroups");
1114
 
        close(devnull);
1115
1084
        _exit(EX_NOPERM);
1116
1085
      }
1117
1086
    }
1118
1087
    ret = dup2(devnull, STDIN_FILENO);
1119
1088
    if(ret == -1){
1120
1089
      perror_plus("dup2(devnull, STDIN_FILENO)");
1121
 
      close(devnull);
1122
1090
      _exit(EX_OSERR);
1123
1091
    }
1124
1092
    ret = close(devnull);
1125
1093
    if(ret == -1){
1126
1094
      perror_plus("close");
 
1095
      _exit(EX_OSERR);
1127
1096
    }
1128
1097
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1129
1098
    if(ret == -1){
1164
1133
  }
1165
1134
  if(pid == -1){
1166
1135
    perror_plus("fork");
1167
 
    close(devnull);
1168
1136
    return false;
1169
1137
  }
1170
 
  ret = close(devnull);
1171
 
  if(ret == -1){
1172
 
    perror_plus("close");
1173
 
  }
1174
1138
  int status;
1175
1139
  pid_t pret = -1;
1176
1140
  errno = 0;
2745
2709
  }
2746
2710
  
2747
2711
  {
 
2712
    /* Work around Debian bug #633582:
 
2713
       <https://bugs.debian.org/633582> */
 
2714
    
2748
2715
    /* Re-raise privileges */
2749
2716
    ret = raise_privileges();
2750
2717
    if(ret != 0){
2753
2720
    } else {
2754
2721
      struct stat st;
2755
2722
      
2756
 
      /* Work around Debian bug #633582:
2757
 
         <https://bugs.debian.org/633582> */
2758
 
 
2759
2723
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2760
2724
        int seckey_fd = open(seckey, O_RDONLY);
2761
2725
        if(seckey_fd == -1){
2820
2784
        }
2821
2785
      }
2822
2786
      
2823
 
      /* Work around Debian bug #981302
2824
 
         <https://bugs.debian.org/981302> */
2825
 
      if(lstat("/dev/fd", &st) != 0 and errno == ENOENT){
2826
 
        ret = symlink("/proc/self/fd", "/dev/fd");
2827
 
        if(ret == -1){
2828
 
          perror_plus("Failed to create /dev/fd symlink");
2829
 
        }
2830
 
      }
2831
 
 
2832
2787
      /* Lower privileges */
2833
2788
      ret = lower_privileges();
2834
2789
      if(ret != 0){