/mandos/release

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

« 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
  • mto: (237.7.594 trunk)
  • mto: This revision was merged to the branch mainline in revision 368.
  • 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-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
 * 
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;
396
388
        fprintf_plus(stderr,
397
389
                     "Setting system clock to key file mtime");
398
390
      }
399
 
      if(clock_settime(CLOCK_REALTIME, &keystat.st_mtim) != 0){
400
 
        perror_plus("clock_settime");
 
391
      time_t keytime = keystat.st_mtim.tv_sec;
 
392
      if(stime(&keytime) != 0){
 
393
        perror_plus("stime");
401
394
      }
402
395
      ret = lower_privileges();
403
396
      if(ret != 0){
706
699
                              const char *dhparamsfilename,
707
700
                              mandos_context *mc){
708
701
  int ret;
 
702
  unsigned int uret;
709
703
  
710
704
  if(debug){
711
705
    fprintf_plus(stderr, "Initializing GnuTLS\n");
728
722
  }
729
723
  
730
724
  if(debug){
731
 
    fprintf_plus(stderr, "Attempting to use public key %s and"
732
 
                 " 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",
733
727
                 pubkeyfilename,
734
728
                 seckeyfilename);
735
729
  }
736
730
  
737
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
738
 
  ret = gnutls_certificate_set_rawpk_key_file
739
 
    (mc->cred, pubkeyfilename, seckeyfilename,
740
 
     GNUTLS_X509_FMT_PEM,       /* format */
741
 
     NULL,                      /* pass */
742
 
     /* key_usage */
743
 
     GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT,
744
 
     NULL,                      /* names */
745
 
     0,                         /* names_length */
746
 
     /* privkey_flags */
747
 
     GNUTLS_PKCS_PLAIN | GNUTLS_PKCS_NULL_PASSWORD,
748
 
     0);                        /* pkcs11_flags */
749
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
750
731
  ret = gnutls_certificate_set_openpgp_key_file
751
732
    (mc->cred, pubkeyfilename, seckeyfilename,
752
733
     GNUTLS_OPENPGP_FMT_BASE64);
753
 
#else
754
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
755
 
#endif
756
734
  if(ret != GNUTLS_E_SUCCESS){
757
735
    fprintf_plus(stderr,
758
 
                 "Error[%d] while reading the key pair ('%s',"
 
736
                 "Error[%d] while reading the OpenPGP key pair ('%s',"
759
737
                 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
760
738
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
761
739
                 safer_gnutls_strerror(ret));
832
810
  }
833
811
  if(dhparamsfilename == NULL){
834
812
    if(mc->dh_bits == 0){
835
 
#if GNUTLS_VERSION_NUMBER < 0x030600
836
813
      /* Find out the optimal number of DH bits */
837
814
      /* Try to read the private key file */
838
815
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
918
895
          }
919
896
        }
920
897
      }
921
 
      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);
922
899
      if(uret != 0){
923
900
        mc->dh_bits = uret;
924
901
        if(debug){
936
913
                     safer_gnutls_strerror(ret));
937
914
        goto globalfail;
938
915
      }
939
 
#endif
940
 
    } else {                    /* dh_bits != 0 */
941
 
      if(debug){
942
 
        fprintf_plus(stderr, "DH bits explicitly set to %u\n",
943
 
                     mc->dh_bits);
944
 
      }
945
 
      ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
946
 
      if(ret != GNUTLS_E_SUCCESS){
947
 
        fprintf_plus(stderr, "Error in GnuTLS prime generation (%u"
948
 
                     " bits): %s\n", mc->dh_bits,
949
 
                     safer_gnutls_strerror(ret));
950
 
        goto globalfail;
951
 
      }
952
 
      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;
953
926
    }
954
927
  }
 
928
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
955
929
  
956
930
  return 0;
957
931
  
968
942
  int ret;
969
943
  /* GnuTLS session creation */
970
944
  do {
971
 
    ret = gnutls_init(session, (GNUTLS_SERVER
972
 
#if GNUTLS_VERSION_NUMBER >= 0x030506
973
 
                                | GNUTLS_NO_TICKETS
974
 
#endif
975
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
976
 
                                | GNUTLS_ENABLE_RAWPK
977
 
#endif
978
 
                                ));
 
945
    ret = gnutls_init(session, GNUTLS_SERVER);
979
946
    if(quit_now){
980
947
      return -1;
981
948
    }
1073
1040
      ret = setgid(0);
1074
1041
      if(ret == -1){
1075
1042
        perror_plus("setgid");
1076
 
        close(devnull);
1077
1043
        _exit(EX_NOPERM);
1078
1044
      }
1079
1045
      /* Reset supplementary groups */
1081
1047
      ret = setgroups(0, NULL);
1082
1048
      if(ret == -1){
1083
1049
        perror_plus("setgroups");
1084
 
        close(devnull);
1085
1050
        _exit(EX_NOPERM);
1086
1051
      }
1087
1052
    }
1088
1053
    ret = dup2(devnull, STDIN_FILENO);
1089
1054
    if(ret == -1){
1090
1055
      perror_plus("dup2(devnull, STDIN_FILENO)");
1091
 
      close(devnull);
1092
1056
      _exit(EX_OSERR);
1093
1057
    }
1094
1058
    ret = close(devnull);
1095
1059
    if(ret == -1){
1096
1060
      perror_plus("close");
 
1061
      _exit(EX_OSERR);
1097
1062
    }
1098
1063
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1099
1064
    if(ret == -1){
1134
1099
  }
1135
1100
  if(pid == -1){
1136
1101
    perror_plus("fork");
1137
 
    close(devnull);
1138
1102
    return false;
1139
1103
  }
1140
 
  ret = close(devnull);
1141
 
  if(ret == -1){
1142
 
    perror_plus("close");
1143
 
  }
1144
1104
  int status;
1145
1105
  pid_t pret = -1;
1146
1106
  errno = 0;
2467
2427
 
2468
2428
int main(int argc, char *argv[]){
2469
2429
  mandos_context mc = { .server = NULL, .dh_bits = 0,
2470
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2471
 
                        .priority = "SECURE128:!CTYPE-X.509"
2472
 
                        ":+CTYPE-RAWPK:!RSA:!VERS-ALL:+VERS-TLS1.3"
2473
 
                        ":%PROFILE_ULTRA",
2474
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
2475
2430
                        .priority = "SECURE256:!CTYPE-X.509"
2476
2431
                        ":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
2477
 
#else
2478
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
2479
 
#endif
2480
2432
                        .current_server = NULL, .interfaces = NULL,
2481
2433
                        .interfaces_size = 0 };
2482
2434
  AvahiSServiceBrowser *sb = NULL;
2493
2445
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2494
2446
  const char *seckey = PATHDIR "/" SECKEY;
2495
2447
  const char *pubkey = PATHDIR "/" PUBKEY;
2496
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2497
 
  const char *tls_privkey = PATHDIR "/" TLS_PRIVKEY;
2498
 
  const char *tls_pubkey = PATHDIR "/" TLS_PUBKEY;
2499
 
#endif
2500
2448
  const char *dh_params_file = NULL;
2501
2449
  char *interfaces_hooks = NULL;
2502
2450
  
2550
2498
      { .name = "pubkey", .key = 'p',
2551
2499
        .arg = "FILE",
2552
2500
        .doc = "OpenPGP public key file base name",
2553
 
        .group = 1 },
2554
 
      { .name = "tls-privkey", .key = 't',
2555
 
        .arg = "FILE",
2556
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2557
 
        .doc = "TLS private key file base name",
2558
 
#else
2559
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2560
 
#endif
2561
 
        .group = 1 },
2562
 
      { .name = "tls-pubkey", .key = 'T',
2563
 
        .arg = "FILE",
2564
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2565
 
        .doc = "TLS public key file base name",
2566
 
#else
2567
 
        .doc = "Dummy; ignored (requires GnuTLS 3.6.6)",
2568
 
#endif
2569
 
        .group = 1 },
 
2501
        .group = 2 },
2570
2502
      { .name = "dh-bits", .key = 129,
2571
2503
        .arg = "BITS",
2572
2504
        .doc = "Bit length of the prime number used in the"
2628
2560
      case 'p':                 /* --pubkey */
2629
2561
        pubkey = arg;
2630
2562
        break;
2631
 
      case 't':                 /* --tls-privkey */
2632
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2633
 
        tls_privkey = arg;
2634
 
#endif
2635
 
        break;
2636
 
      case 'T':                 /* --tls-pubkey */
2637
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
2638
 
        tls_pubkey = arg;
2639
 
#endif
2640
 
        break;
2641
2563
      case 129:                 /* --dh-bits */
2642
2564
        errno = 0;
2643
2565
        tmpmax = strtoimax(arg, &tmp, 10);
2678
2600
        argp_state_help(state, state->out_stream,
2679
2601
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2680
2602
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
2681
 
        __builtin_unreachable();
2682
2603
      case -3:                  /* --usage */
2683
2604
        argp_state_help(state, state->out_stream,
2684
2605
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
2685
 
        __builtin_unreachable();
2686
2606
      case 'V':                 /* --version */
2687
2607
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2688
2608
        exit(argp_err_exit_status);
2999
2919
    goto end;
3000
2920
  }
3001
2921
  
3002
 
#if GNUTLS_VERSION_NUMBER >= 0x030606
3003
 
  ret = init_gnutls_global(tls_pubkey, tls_privkey, dh_params_file, &mc);
3004
 
#elif GNUTLS_VERSION_NUMBER < 0x030600
3005
2922
  ret = init_gnutls_global(pubkey, seckey, dh_params_file, &mc);
3006
 
#else
3007
 
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
3008
 
#endif
3009
2923
  if(ret == -1){
3010
2924
    fprintf_plus(stderr, "init_gnutls_global failed\n");
3011
2925
    exitcode = EX_UNAVAILABLE;