/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-02-09 23:23:26 UTC
  • Revision ID: teddy@recompile.se-20190209232326-z1z2kzpgfixz7iaj
Add support for using raw public keys in TLS (RFC 7250)

Since GnuTLS removed support for OpenPGP keys in TLS (RFC 6091), and
no other library supports it, we have to change the protocol to use
something else.  We choose to use "raw public keys" (RFC 7250).  Since
we still use OpenPGP keys to decrypt the secret password, this means
that each client will have two keys: One OpenPGP key and one TLS
public/private key, and the key ID of the latter key is used to
identify clients instead of the fingerprint of the OpenPGP key.

Note that this code is still compatible with GnuTLS before version
3.6.0 (when OpenPGP key support was removed).  This commit merely adds
support for using raw pulic keys instead with GnuTLS 3.6.6. or later.

* DBUS-API (Signals/ClientNotFound): Change name of first parameter
                                     from "Fingerprint" to "KeyID".
  (Mandos Client Interface/Properties/KeyID): New.
* INSTALL: Document conflict with GnuTLS 3.6.0 (which removed OpenPGP
           key support) up until 3.6.6, when support for raw public
           keys was added.  Also document new dependency of client on
           "gnutls-bin" package (for certtool).
* Makefile (run-client): Depend on TLS key files, and also pass them
                         as arguments to client.
  (keydir/tls-privkey.pem, keydir/tls-pubkey.pem): New.
  (confdir/clients.conf): Add dependency on TLS public key.
  (purge-client): Add removal of TLS key files.
* clients.conf ([foo]/key_id, [bar]/key_id): New.
* debian/control (Source: mandos/Build-Depends): Also allow
                                                 libgnutls30 (>= 3.6.6)
  (Package: mandos/Depends): - '' -
  (Package: mandos/Description): Alter description to match new
                                 design.
  (Package: mandos-client/Description): - '' -
  (Package: mandos-client/Depends): Move "gnutls-bin | openssl" to
                                    here from "Recommends".
* debian/mandos-client.README.Debian: Add --tls-privkey and
                                      --tls-pubkey options to test
                                      command.
* debian/mandos-client.postinst (create_key): Renamed to "create_keys"
                                             (all callers changed),
                                             and also create TLS key.
* debian/mandos-client.postrm (purge): Also remove TLS key files.
* intro.xml (DESCRIPTION): Describe new dual-key design.
* mandos (GnuTLS): Define different functions depending on whether
                   support for raw public keys is detected.
  (Client.key_id): New attribute.
  (ClientDBus.KeyID_dbus_property): New method.
  (ProxyClient.__init__): Take new "key_id" parameter.
  (ClientHandler.handle): Use key IDs when using raw public keys and
                          use fingerprints when using OpenPGP keys.
  (ClientHandler.peer_certificate): Also handle raw public keys.
  (ClientHandler.key_id): New.
  (MandosServer.handle_ipc): Pass key ID over the pipe IPC.  Also
                             check for key ID matches when looking up
                             clients.
  (main): Default GnuTLS priority string depends on whether we are
          using raw public keys or not.  When unpickling clients, set
          key_id if not set in the pickle.
  (main/MandosDBusService.ClientNotFound): Change name of first
                                           parameter from
                                           "Fingerprint" to "KeyID".
* mandos-clients.conf.xml (OPTIONS): Document new "key_id" option.
  (OPTIONS/secret): Mention new key ID matchning.
  (EXPANSION/RUNTIME EXPANSION): Add new "key_id" option.
  (EXAMPLE): - '' -
* mandos-ctl (tablewords, main/keywords): Add new "KeyID" property.
* mandos-keygen: Create TLS key files.  New "--tls-keytype" (-T)
                 option.  Alter help text to be more clear about key
                 types.  When in password mode, also output "key_id"
                 option.
* mandos-keygen.xml (SYNOPSIS): Add new "--tls-keytype" (-T) option.
  (DESCRIPTION): Alter to match new dual-key design.
  (OVERVIEW): - '' -
  (FILES): Add TLS key files.
* mandos-options.xml (priority): Document new default priority string
                                 when using raw public keys.
* mandos.xml (NETWORK PROTOCOL): Describe new protocol using key ID.
  (BUGS): Remove issue about checking expire times of OpenPGP keys,
          since TLS public keys do not have expiration times.
  (SECURITY/CLIENT): Alter description to match new design.
  (SEE ALSO/GnuTLS): - '' -
  (SEE ALSO): Add reference to RFC 7250, and alter description of when
              RFC 6091 is used.
* overview.xml: Alter text to match new design.
* plugin-runner.xml (EXAMPLE): Add --tls-pubkey and --tls-privkey
                               options to mandos-client options.
* plugins.d/mandos-client.c: Use raw public keys when compiling with
                             supporting GnuTLS versions. Add new
                             "--tls-pubkey" and "--tls-privkey"
                             options (which do nothing if GnuTLS
                             library does not support raw public
                             keys).  Alter text throughout to reflect
                             new design.  Only generate new DH
                             parameters (based on size of OpenPGP key)
                             when using OpenPGP in TLS.  Default
                             GnuTLS priority string depends on whether
                             we are using raw public keys or not.
* plugins.d/mandos-client.xml (SYNOPSIS): Add new "--tls-privkey" (-t)
                                          and "--tls-pubkey" (-T)
                                          options.
  (DESCRIPTION): Describe new dual-key design.
  (OPTIONS): Document new "--tls-privkey" (-t) and "--tls-pubkey" (-T)
             options.
  (OPTIONS/--dh-bits): No longer necessarily depends on OpenPGP key
                       size.
  (FILES): Add default locations for TLS public and private key files.
  (EXAMPLE): Use new --tls-pubkey and --tls-privkey options.
  (SECURITY): Alter wording slightly to reflect new dual-key design.
  (SEE ALSO/GnuTLS): Alter description to match new design.
  (SEE ALSO): Add reference to RFC 7250, and alter description of when
              RFC 6091 is used.

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-2020 Teddy Hogeborn
13
 
 * Copyright © 2008-2020 Björn Påhlsson
 
12
 * Copyright © 2008-2018 Teddy Hogeborn
 
13
 * Copyright © 2008-2018 Björn Påhlsson
14
14
 * 
15
15
 * This file is part of Mandos.
16
16
 * 
80
80
#include <unistd.h>             /* close(), SEEK_SET, off_t, write(),
81
81
                                   getuid(), getgid(), seteuid(),
82
82
                                   setgid(), pause(), _exit(),
83
 
                                   unlinkat(), lstat(), symlink() */
 
83
                                   unlinkat() */
84
84
#include <arpa/inet.h>          /* inet_pton(), htons() */
85
85
#include <iso646.h>             /* not, or, and */
86
86
#include <argp.h>               /* struct argp_option, error_t, struct
396
396
        fprintf_plus(stderr,
397
397
                     "Setting system clock to key file mtime");
398
398
      }
399
 
      if(clock_settime(CLOCK_REALTIME, &keystat.st_mtim) != 0){
400
 
        perror_plus("clock_settime");
 
399
      time_t keytime = keystat.st_mtim.tv_sec;
 
400
      if(stime(&keytime) != 0){
 
401
        perror_plus("stime");
401
402
      }
402
403
      ret = lower_privileges();
403
404
      if(ret != 0){
1073
1074
      ret = setgid(0);
1074
1075
      if(ret == -1){
1075
1076
        perror_plus("setgid");
1076
 
        close(devnull);
1077
1077
        _exit(EX_NOPERM);
1078
1078
      }
1079
1079
      /* Reset supplementary groups */
1081
1081
      ret = setgroups(0, NULL);
1082
1082
      if(ret == -1){
1083
1083
        perror_plus("setgroups");
1084
 
        close(devnull);
1085
1084
        _exit(EX_NOPERM);
1086
1085
      }
1087
1086
    }
1088
1087
    ret = dup2(devnull, STDIN_FILENO);
1089
1088
    if(ret == -1){
1090
1089
      perror_plus("dup2(devnull, STDIN_FILENO)");
1091
 
      close(devnull);
1092
1090
      _exit(EX_OSERR);
1093
1091
    }
1094
1092
    ret = close(devnull);
1095
1093
    if(ret == -1){
1096
1094
      perror_plus("close");
 
1095
      _exit(EX_OSERR);
1097
1096
    }
1098
1097
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1099
1098
    if(ret == -1){
1134
1133
  }
1135
1134
  if(pid == -1){
1136
1135
    perror_plus("fork");
1137
 
    close(devnull);
1138
1136
    return false;
1139
1137
  }
1140
 
  ret = close(devnull);
1141
 
  if(ret == -1){
1142
 
    perror_plus("close");
1143
 
  }
1144
1138
  int status;
1145
1139
  pid_t pret = -1;
1146
1140
  errno = 0;
2678
2672
        argp_state_help(state, state->out_stream,
2679
2673
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2680
2674
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
2681
 
        __builtin_unreachable();
2682
2675
      case -3:                  /* --usage */
2683
2676
        argp_state_help(state, state->out_stream,
2684
2677
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2685
 
        __builtin_unreachable();
2686
2678
      case 'V':                 /* --version */
2687
2679
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2688
2680
        exit(argp_err_exit_status);
2715
2707
  }
2716
2708
  
2717
2709
  {
 
2710
    /* Work around Debian bug #633582:
 
2711
       <https://bugs.debian.org/633582> */
 
2712
    
2718
2713
    /* Re-raise privileges */
2719
2714
    ret = raise_privileges();
2720
2715
    if(ret != 0){
2723
2718
    } else {
2724
2719
      struct stat st;
2725
2720
      
2726
 
      /* Work around Debian bug #633582:
2727
 
         <https://bugs.debian.org/633582> */
2728
 
 
2729
2721
      if(strcmp(seckey, PATHDIR "/" SECKEY) == 0){
2730
2722
        int seckey_fd = open(seckey, O_RDONLY);
2731
2723
        if(seckey_fd == -1){
2790
2782
        }
2791
2783
      }
2792
2784
      
2793
 
      /* Work around Debian bug #981302
2794
 
         <https://bugs.debian.org/981302> */
2795
 
      if(lstat("/dev/fd", &st) != 0 and errno == ENOENT){
2796
 
        ret = symlink("/proc/self/fd", "/dev/fd");
2797
 
        if(ret == -1){
2798
 
          perror_plus("Failed to create /dev/fd symlink");
2799
 
        }
2800
 
      }
2801
 
 
2802
2785
      /* Lower privileges */
2803
2786
      ret = lower_privileges();
2804
2787
      if(ret != 0){