/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: 2024-09-09 01:36:41 UTC
  • Revision ID: teddy@recompile.se-20240909013641-6zu6kx2f7meu134k
Make all required directories when installing

When installing into a normal system, one can assume that target
directories, such as /usr/bin, already exists.  But when installing
into a subdirectory for the purpose of creating a package, one cannot
assume that all directories already exist.  Therefore, when
installing, we must not check if any directories exist, and must
instead always create any directories we want to install into.

* Makefile (confdir/mandos.conf, confdir/clients.conf, install-html):
  Use the "-D" option to "install" instead of creating the directory
  separately.
  (install-server): Move creation of $(CONFDIR) down to before it is
  needed.  Don't check if the $(TMPFILES) or $(SYSUSERS) directories
  exist; instead create them by using the "-D" option to "install".
  Create the $(PREFIX)/sbin directory.  Always use
  "--target-directory" if possible; i.e. if the file name is the same.
  Create the $(DBUSPOLICYDIR) and $(DESTDIR)/etc/init.d directories by
  using the "-D" option to "install".  Don't check if the $(SYSTEMD)
  directory exists; instead create it by using the "-D" option to
  "install".  Create the $(DESTDIR)/etc/default and $(MANDIR)/man8
  directories by using the "-D" option to "install".  Create the
  $(MANDIR)/man5 directories explicitly.
  (install-client-nokey): Remove unnecessary creation of the
  $(CONFDIR) directory.  Don't check if the $(SYSUSERS) directory
  exists; instead create it by using the "-D" option to "install".
  Move the "--directory" argument to be the first argument, for
  clarity.  Create the $(PREFIX)/sbin directory.  Use the "-D"
  argument to "install" when installing
  $(INITRAMFSTOOLS)/hooks/mandos,
  $(INITRAMFSTOOLS)/conf.d/mandos-conf,
  $(INITRAMFSTOOLS)/conf-hooks.d/zz-mandos,
  $(INITRAMFSTOOLS)/scripts/init-premount/mandos,
  $(INITRAMFSTOOLS)/scripts/local-premount/mandos,
  $(DRACUTMODULE)/ask-password-mandos.path, and
  $(DRACUTMODULE)/dracut-module/ask-password-mandos.service.  Create
  the $(MANDIR)/man8 directory.

Reported-By: Erich Eckner <erich@eckner.net>
Thanks: Erich Eckner <erich@eckner.net> for analysis

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-2018 Teddy Hogeborn
13
 
 * Copyright © 2008-2018 Björn Påhlsson
 
12
 * Copyright © 2008-2022 Teddy Hogeborn
 
13
 * Copyright © 2008-2022 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             /* 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() */
 
41
#define _GNU_SOURCE             /* program_invocation_short_name,
 
42
                                   TEMP_FAILURE_RETRY(), O_CLOEXEC,
 
43
                                   scandirat(), asprintf() */
49
44
#include <stdbool.h>            /* bool, false, true */
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,
 
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,
69
81
                                   EHOSTUNREACH, ECONNREFUSED, EPROTO,
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 */
 
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 */
 
111
#include <grp.h>                /* setgroups() */
95
112
#include <sys/wait.h>           /* waitpid(), WIFEXITED(),
96
 
                                   WEXITSTATUS(), WTERMSIG() */
97
 
#include <grp.h>                /* setgroups() */
98
 
#include <argz.h>               /* argz_add_sep(), argz_next(),
99
 
                                   argz_delete(), argz_append(),
100
 
                                   argz_stringify(), argz_add(),
101
 
                                   argz_count() */
 
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 */
102
132
#include <netdb.h>              /* getnameinfo(), NI_NUMERICHOST,
103
133
                                   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 */
104
138
 
105
139
#ifdef __linux__
106
140
#include <sys/klog.h>           /* klogctl() */
119
153
 
120
154
/* GnuTLS */
121
155
#include <gnutls/gnutls.h>      /* All GnuTLS types, constants and
122
 
                                   functions:
123
 
                                   gnutls_*
124
 
                                   init_gnutls_session(),
125
 
                                   GNUTLS_* */
 
156
                                   functions: gnutls_*, GNUTLS_* */
126
157
#if GNUTLS_VERSION_NUMBER < 0x030600
127
158
#include <gnutls/openpgp.h>
128
159
                         /* gnutls_certificate_set_openpgp_key_file(),
129
160
                            GNUTLS_OPENPGP_FMT_BASE64 */
130
161
#elif GNUTLS_VERSION_NUMBER >= 0x030606
131
 
#include <gnutls/x509.h>        /* gnutls_pkcs_encrypt_flags_t,
132
 
                                 GNUTLS_PKCS_PLAIN,
133
 
                                 GNUTLS_PKCS_NULL_PASSWORD */
 
162
#include <gnutls/x509.h>        /* GNUTLS_PKCS_PLAIN,
 
163
                                   GNUTLS_PKCS_NULL_PASSWORD */
134
164
#endif
135
165
 
136
166
/* GPGME */
137
167
#include <gpgme.h>              /* All GPGME types, constants and
138
168
                                   functions:
139
 
                                   gpgme_*
140
 
                                   GPGME_PROTOCOL_OpenPGP,
141
 
                                   GPG_ERR_NO_* */
 
169
                                   gpgme_*, GPG_ERR_NO_*,
 
170
                                   GPGME_IMPORT_*
 
171
                                   GPGME_PROTOCOL_OpenPGP */
142
172
 
143
173
#define BUFFER_SIZE 256
144
174
 
396
426
        fprintf_plus(stderr,
397
427
                     "Setting system clock to key file mtime");
398
428
      }
399
 
      time_t keytime = keystat.st_mtim.tv_sec;
400
 
      if(stime(&keytime) != 0){
401
 
        perror_plus("stime");
 
429
      if(clock_settime(CLOCK_REALTIME, &keystat.st_mtim) != 0){
 
430
        perror_plus("clock_settime");
402
431
      }
403
432
      ret = lower_privileges();
404
433
      if(ret != 0){
1074
1103
      ret = setgid(0);
1075
1104
      if(ret == -1){
1076
1105
        perror_plus("setgid");
 
1106
        close(devnull);
1077
1107
        _exit(EX_NOPERM);
1078
1108
      }
1079
1109
      /* Reset supplementary groups */
1081
1111
      ret = setgroups(0, NULL);
1082
1112
      if(ret == -1){
1083
1113
        perror_plus("setgroups");
 
1114
        close(devnull);
1084
1115
        _exit(EX_NOPERM);
1085
1116
      }
1086
1117
    }
1087
1118
    ret = dup2(devnull, STDIN_FILENO);
1088
1119
    if(ret == -1){
1089
1120
      perror_plus("dup2(devnull, STDIN_FILENO)");
 
1121
      close(devnull);
1090
1122
      _exit(EX_OSERR);
1091
1123
    }
1092
1124
    ret = close(devnull);
1093
1125
    if(ret == -1){
1094
1126
      perror_plus("close");
1095
 
      _exit(EX_OSERR);
1096
1127
    }
1097
1128
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1098
1129
    if(ret == -1){
1133
1164
  }
1134
1165
  if(pid == -1){
1135
1166
    perror_plus("fork");
 
1167
    close(devnull);
1136
1168
    return false;
1137
1169
  }
 
1170
  ret = close(devnull);
 
1171
  if(ret == -1){
 
1172
    perror_plus("close");
 
1173
  }
1138
1174
  int status;
1139
1175
  pid_t pret = -1;
1140
1176
  errno = 0;
2672
2708
        argp_state_help(state, state->out_stream,
2673
2709
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2674
2710
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
 
2711
        __builtin_unreachable();
2675
2712
      case -3:                  /* --usage */
2676
2713
        argp_state_help(state, state->out_stream,
2677
2714
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
 
2715
        __builtin_unreachable();
2678
2716
      case 'V':                 /* --version */
2679
2717
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2680
2718
        exit(argp_err_exit_status);
2707
2745
  }
2708
2746
  
2709
2747
  {
2710
 
    /* Work around Debian bug #633582:
2711
 
       <https://bugs.debian.org/633582> */
2712
 
    
2713
2748
    /* Re-raise privileges */
2714
2749
    ret = raise_privileges();
2715
2750
    if(ret != 0){
2718
2753
    } else {
2719
2754
      struct stat st;
2720
2755
      
 
2756
      /* Work around Debian bug #633582:
 
2757
         <https://bugs.debian.org/633582> */
 
2758
 
2721
2759
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2722
2760
        int seckey_fd = open(seckey, O_RDONLY);
2723
2761
        if(seckey_fd == -1){
2782
2820
        }
2783
2821
      }
2784
2822
      
 
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
 
2785
2832
      /* Lower privileges */
2786
2833
      ret = lower_privileges();
2787
2834
      if(ret != 0){