/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: 2018-08-15 09:26:02 UTC
  • Revision ID: teddy@recompile.se-20180815092602-xoyb5s6gf8376i7u
mandos-client: Set system clock if necessary

* plugins.d/mandos-client.c (init_gpgme/import_key): If the system
  clock is not set, or set to january 1970, set the system clock to
  the more plausible value that is the mtime of the key file.  This is
  required by GnuPG to be able to import the keys.  (We can't pass the
  --ignore-time-conflict or the --ignore-valid-from options though
  GPGME.)

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-2019 Teddy Hogeborn
13
 
 * Copyright © 2008-2019 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
 * 
123
123
                                   gnutls_*
124
124
                                   init_gnutls_session(),
125
125
                                   GNUTLS_* */
126
 
#if GNUTLS_VERSION_NUMBER < 0x030600
127
126
#include <gnutls/openpgp.h>
128
127
                         /* gnutls_certificate_set_openpgp_key_file(),
129
128
                            GNUTLS_OPENPGP_FMT_BASE64 */
130
 
#elif GNUTLS_VERSION_NUMBER >= 0x030606
131
 
#include <gnutls/x509.h>        /* gnutls_pkcs_encrypt_flags_t,
132
 
                                 GNUTLS_PKCS_PLAIN,
133
 
                                 GNUTLS_PKCS_NULL_PASSWORD */
134
 
#endif
135
129
 
136
130
/* GPGME */
137
131
#include <gpgme.h>              /* All GPGME types, constants and
145
139
#define PATHDIR "/conf/conf.d/mandos"
146
140
#define SECKEY "seckey.txt"
147
141
#define PUBKEY "pubkey.txt"
148
 
#define TLS_PRIVKEY "tls-privkey.pem"
149
 
#define TLS_PUBKEY "tls-pubkey.pem"
150
142
#define HOOKDIR "/lib/mandos/network-hooks.d"
151
143
 
152
144
bool debug = false;
707
699
                              const char *dhparamsfilename,
708
700
                              mandos_context *mc){
709
701
  int ret;
 
702
  unsigned int uret;
710
703
  
711
704
  if(debug){
712
705
    fprintf_plus(stderr, "Initializing GnuTLS\n");
729
722
  }
730
723
  
731
724
  if(debug){
732
 
    fprintf_plus(stderr, "Attempting to use public key %s and"
733
 
                 " private key %s as GnuTLS credentials\n",
 
725
    fprintf_plus(stderr, "Attempting to use OpenPGP public key %s and"
 
726
                 " secret key %s as GnuTLS credentials\n",
734
727
                 pubkeyfilename,
735
728
                 seckeyfilename);
736
729
  }
737
730
  
738
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
739
 
  ret = gnutls_certificate_set_rawpk_key_file
740
 
    (mc->cred, pubkeyfilename, seckeyfilename,
741
 
     GNUTLS_X509_FMT_PEM,       /* format */
742
 
     NULL,                      /* pass */
743
 
     /* key_usage */
744
 
     GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
745
 
     NULL,                      /* names */
746
 
     0,                         /* names_length */
747
 
     /* privkey_flags */
748
 
     GNUTLS_PKCS_PLAIN | GNUTLS_PKCS_NULL_PASSWORD,
749
 
     0);                        /* pkcs11_flags */
750
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
751
731
  ret = gnutls_certificate_set_openpgp_key_file
752
732
    (mc->cred, pubkeyfilename, seckeyfilename,
753
733
     GNUTLS_OPENPGP_FMT_BASE64);
754
 
#else
755
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
756
 
#endif
757
734
  if(ret != GNUTLS_E_SUCCESS){
758
735
    fprintf_plus(stderr,
759
 
                 "Error[%d] while reading the key pair ('%s',"
 
736
                 "Error[%d] while reading the OpenPGP key pair ('%s',"
760
737
                 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
761
738
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
762
739
                 safer_gnutls_strerror(ret));
833
810
  }
834
811
  if(dhparamsfilename == NULL){
835
812
    if(mc->dh_bits == 0){
836
 
#if GNUTLS_VERSION_NUMBER < 0x030600
837
813
      /* Find out the optimal number of DH bits */
838
814
      /* Try to read the private key file */
839
815
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
919
895
          }
920
896
        }
921
897
      }
922
 
      unsigned int uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
 
898
      uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
923
899
      if(uret != 0){
924
900
        mc->dh_bits = uret;
925
901
        if(debug){
937
913
                     safer_gnutls_strerror(ret));
938
914
        goto globalfail;
939
915
      }
940
 
#endif
941
 
    } else {                    /* dh_bits != 0 */
942
 
      if(debug){
943
 
        fprintf_plus(stderr, "DH bits explicitly set to %u\n",
944
 
                     mc->dh_bits);
945
 
      }
946
 
      ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
947
 
      if(ret != GNUTLS_E_SUCCESS){
948
 
        fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
949
 
                     " bits): %s\n", mc->dh_bits,
950
 
                     safer_gnutls_strerror(ret));
951
 
        goto globalfail;
952
 
      }
953
 
      gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
 
916
    } else if(debug){
 
917
      fprintf_plus(stderr, "DH bits explicitly set to %u\n",
 
918
                   mc->dh_bits);
 
919
    }
 
920
    ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
 
921
    if(ret != GNUTLS_E_SUCCESS){
 
922
      fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
 
923
                   " bits): %s\n", mc->dh_bits,
 
924
                   safer_gnutls_strerror(ret));
 
925
      goto globalfail;
954
926
    }
955
927
  }
 
928
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
956
929
  
957
930
  return 0;
958
931
  
969
942
  int ret;
970
943
  /* GnuTLS session creation */
971
944
  do {
972
 
    ret = gnutls_init(session, (GNUTLS_SERVER
973
 
#if GNUTLS_VERSION_NUMBER >= 0x030506
974
 
                                | GNUTLS_NO_TICKETS
975
 
#endif
976
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
977
 
                                | GNUTLS_ENABLE_RAWPK
978
 
#endif
979
 
                                ));
 
945
    ret = gnutls_init(session, GNUTLS_SERVER);
980
946
    if(quit_now){
981
947
      return -1;
982
948
    }
1074
1040
      ret = setgid(0);
1075
1041
      if(ret == -1){
1076
1042
        perror_plus("setgid");
1077
 
        close(devnull);
1078
1043
        _exit(EX_NOPERM);
1079
1044
      }
1080
1045
      /* Reset supplementary groups */
1082
1047
      ret = setgroups(0, NULL);
1083
1048
      if(ret == -1){
1084
1049
        perror_plus("setgroups");
1085
 
        close(devnull);
1086
1050
        _exit(EX_NOPERM);
1087
1051
      }
1088
1052
    }
1089
1053
    ret = dup2(devnull, STDIN_FILENO);
1090
1054
    if(ret == -1){
1091
1055
      perror_plus("dup2(devnull, STDIN_FILENO)");
1092
 
      close(devnull);
1093
1056
      _exit(EX_OSERR);
1094
1057
    }
1095
1058
    ret = close(devnull);
1096
1059
    if(ret == -1){
1097
1060
      perror_plus("close");
 
1061
      _exit(EX_OSERR);
1098
1062
    }
1099
1063
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1100
1064
    if(ret == -1){
1135
1099
  }
1136
1100
  if(pid == -1){
1137
1101
    perror_plus("fork");
1138
 
    close(devnull);
1139
1102
    return false;
1140
1103
  }
1141
 
  ret = close(devnull);
1142
 
  if(ret == -1){
1143
 
    perror_plus("close");
1144
 
  }
1145
1104
  int status;
1146
1105
  pid_t pret = -1;
1147
1106
  errno = 0;
2468
2427
 
2469
2428
int main(int argc, char *argv[]){
2470
2429
  mandos_context mc = { .server = NULL, .dh_bits = 0,
2471
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2472
 
                        .priority = "SECURE128:!CTYPE-X.509"
2473
 
                        ":+CTYPE-RAWPK:!RSA:!VERS-ALL:+VERS-TLS1.3"
2474
 
                        ":%PROFILE_ULTRA",
2475
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
2476
2430
                        .priority = "SECURE256:!CTYPE-X.509"
2477
2431
                        ":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
2478
 
#else
2479
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
2480
 
#endif
2481
2432
                        .current_server = NULL, .interfaces = NULL,
2482
2433
                        .interfaces_size = 0 };
2483
2434
  AvahiSServiceBrowser *sb = NULL;
2494
2445
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2495
2446
  const char *seckey = PATHDIR "/" SECKEY;
2496
2447
  const char *pubkey = PATHDIR "/" PUBKEY;
2497
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2498
 
  const char *tls_privkey = PATHDIR "/" TLS_PRIVKEY;
2499
 
  const char *tls_pubkey = PATHDIR "/" TLS_PUBKEY;
2500
 
#endif
2501
2448
  const char *dh_params_file = NULL;
2502
2449
  char *interfaces_hooks = NULL;
2503
2450
  
2551
2498
      { .name = "pubkey", .key = 'p',
2552
2499
        .arg = "FILE",
2553
2500
        .doc = "OpenPGP public key file base name",
2554
 
        .group = 1 },
2555
 
      { .name = "tls-privkey", .key = 't',
2556
 
        .arg = "FILE",
2557
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2558
 
        .doc = "TLS private key file base name",
2559
 
#else
2560
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2561
 
#endif
2562
 
        .group = 1 },
2563
 
      { .name = "tls-pubkey", .key = 'T',
2564
 
        .arg = "FILE",
2565
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2566
 
        .doc = "TLS public key file base name",
2567
 
#else
2568
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2569
 
#endif
2570
 
        .group = 1 },
 
2501
        .group = 2 },
2571
2502
      { .name = "dh-bits", .key = 129,
2572
2503
        .arg = "BITS",
2573
2504
        .doc = "Bit length of the prime number used in the"
2629
2560
      case 'p':                 /* --pubkey */
2630
2561
        pubkey = arg;
2631
2562
        break;
2632
 
      case 't':                 /* --tls-privkey */
2633
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2634
 
        tls_privkey = arg;
2635
 
#endif
2636
 
        break;
2637
 
      case 'T':                 /* --tls-pubkey */
2638
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2639
 
        tls_pubkey = arg;
2640
 
#endif
2641
 
        break;
2642
2563
      case 129:                 /* --dh-bits */
2643
2564
        errno = 0;
2644
2565
        tmpmax = strtoimax(arg, &tmp, 10);
2679
2600
        argp_state_help(state, state->out_stream,
2680
2601
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2681
2602
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
2682
 
        __builtin_unreachable();
2683
2603
      case -3:                  /* --usage */
2684
2604
        argp_state_help(state, state->out_stream,
2685
2605
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2686
 
        __builtin_unreachable();
2687
2606
      case 'V':                 /* --version */
2688
2607
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2689
2608
        exit(argp_err_exit_status);
3000
2919
    goto end;
3001
2920
  }
3002
2921
  
3003
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
3004
 
  ret = init_gnutls_global(tls_pubkey, tls_privkey, dh_params_file, &mc);
3005
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
3006
2922
  ret = init_gnutls_global(pubkey, seckey, dh_params_file, &mc);
3007
 
#else
3008
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
3009
 
#endif
3010
2923
  if(ret == -1){
3011
2924
    fprintf_plus(stderr, "init_gnutls_global failed\n");
3012
2925
    exitcode = EX_UNAVAILABLE;