/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 at recompile
  • Date: 2020-12-03 20:30:45 UTC
  • Revision ID: teddy@recompile.se-20201203203045-iqd6nq9y5nwalh1x
Minor fix of a test function

In dracut-module/password-agent, the test function
test_send_password_to_socket_EMSGSIZE() (which tests that the
send_password_to_socket() task function aborts properly when getting
EMSGSIZE when writing to the password socket), part of the test code
is supposed to find a message size which definitely does trigger
EMSGSIZE when send()ing to a socket.  Without a "break" in the proper
place, however, the size given is always exactly 1024 bytes too large.

This is very probably not a problem, since a too large message will
still be too large if it is increased by 1024 bytes, and send(2) in
practice checks the size before reading the buffer.  The biggest issue
would be if some version of send(2) would try to look at the last 1024
bytes of the message buffer before checking the message size; this
would then lead to a buffer over-read when running this test function.
(But even then there would be no security implications since the tests
are not run in the normal operation of the program.)

* dracut-module/password-agent.c
  (test_send_password_to_socket_EMSGSIZE): Break out early when ssret
  < 0 and errno == EMSGSIZE; don't allow loop to increase message_size
  again.

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-2020 Teddy Hogeborn
 
13
 * Copyright © 2008-2020 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
126
127
#include <gnutls/openpgp.h>
127
128
                         /* gnutls_certificate_set_openpgp_key_file(),
128
129
                            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
129
135
 
130
136
/* GPGME */
131
137
#include <gpgme.h>              /* All GPGME types, constants and
139
145
#define PATHDIR "/conf/conf.d/mandos"
140
146
#define SECKEY "seckey.txt"
141
147
#define PUBKEY "pubkey.txt"
 
148
#define TLS_PRIVKEY "tls-privkey.pem"
 
149
#define TLS_PUBKEY "tls-pubkey.pem"
142
150
#define HOOKDIR "/lib/mandos/network-hooks.d"
143
151
 
144
152
bool debug = false;
388
396
        fprintf_plus(stderr,
389
397
                     "Setting system clock to key file mtime");
390
398
      }
391
 
      time_t keytime = keystat.st_mtim.tv_sec;
392
 
      if(stime(&keytime) != 0){
393
 
        perror_plus("stime");
 
399
      if(clock_settime(CLOCK_REALTIME, &keystat.st_mtim) != 0){
 
400
        perror_plus("clock_settime");
394
401
      }
395
402
      ret = lower_privileges();
396
403
      if(ret != 0){
699
706
                              const char *dhparamsfilename,
700
707
                              mandos_context *mc){
701
708
  int ret;
702
 
  unsigned int uret;
703
709
  
704
710
  if(debug){
705
711
    fprintf_plus(stderr, "Initializing GnuTLS\n");
722
728
  }
723
729
  
724
730
  if(debug){
725
 
    fprintf_plus(stderr, "Attempting to use OpenPGP public key %s and"
726
 
                 " secret key %s as GnuTLS credentials\n",
 
731
    fprintf_plus(stderr, "Attempting to use public key %s and"
 
732
                 " private key %s as GnuTLS credentials\n",
727
733
                 pubkeyfilename,
728
734
                 seckeyfilename);
729
735
  }
730
736
  
 
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
731
750
  ret = gnutls_certificate_set_openpgp_key_file
732
751
    (mc->cred, pubkeyfilename, seckeyfilename,
733
752
     GNUTLS_OPENPGP_FMT_BASE64);
 
753
#else
 
754
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
 
755
#endif
734
756
  if(ret != GNUTLS_E_SUCCESS){
735
757
    fprintf_plus(stderr,
736
 
                 "Error[%d] while reading the OpenPGP key pair ('%s',"
 
758
                 "Error[%d] while reading the key pair ('%s',"
737
759
                 " '%s')\n", ret, pubkeyfilename, seckeyfilename);
738
760
    fprintf_plus(stderr, "The GnuTLS error is: %s\n",
739
761
                 safer_gnutls_strerror(ret));
810
832
  }
811
833
  if(dhparamsfilename == NULL){
812
834
    if(mc->dh_bits == 0){
 
835
#if GNUTLS_VERSION_NUMBER < 0x030600
813
836
      /* Find out the optimal number of DH bits */
814
837
      /* Try to read the private key file */
815
838
      gnutls_datum_t buffer = { .data = NULL, .size = 0 };
895
918
          }
896
919
        }
897
920
      }
898
 
      uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
 
921
      unsigned int uret = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param);
899
922
      if(uret != 0){
900
923
        mc->dh_bits = uret;
901
924
        if(debug){
913
936
                     safer_gnutls_strerror(ret));
914
937
        goto globalfail;
915
938
      }
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;
 
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);
926
953
    }
927
954
  }
928
 
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
929
955
  
930
956
  return 0;
931
957
  
942
968
  int ret;
943
969
  /* GnuTLS session creation */
944
970
  do {
945
 
    ret = gnutls_init(session, GNUTLS_SERVER);
 
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
                                ));
946
979
    if(quit_now){
947
980
      return -1;
948
981
    }
1040
1073
      ret = setgid(0);
1041
1074
      if(ret == -1){
1042
1075
        perror_plus("setgid");
 
1076
        close(devnull);
1043
1077
        _exit(EX_NOPERM);
1044
1078
      }
1045
1079
      /* Reset supplementary groups */
1047
1081
      ret = setgroups(0, NULL);
1048
1082
      if(ret == -1){
1049
1083
        perror_plus("setgroups");
 
1084
        close(devnull);
1050
1085
        _exit(EX_NOPERM);
1051
1086
      }
1052
1087
    }
1053
1088
    ret = dup2(devnull, STDIN_FILENO);
1054
1089
    if(ret == -1){
1055
1090
      perror_plus("dup2(devnull, STDIN_FILENO)");
 
1091
      close(devnull);
1056
1092
      _exit(EX_OSERR);
1057
1093
    }
1058
1094
    ret = close(devnull);
1059
1095
    if(ret == -1){
1060
1096
      perror_plus("close");
1061
 
      _exit(EX_OSERR);
1062
1097
    }
1063
1098
    ret = dup2(STDERR_FILENO, STDOUT_FILENO);
1064
1099
    if(ret == -1){
1099
1134
  }
1100
1135
  if(pid == -1){
1101
1136
    perror_plus("fork");
 
1137
    close(devnull);
1102
1138
    return false;
1103
1139
  }
 
1140
  ret = close(devnull);
 
1141
  if(ret == -1){
 
1142
    perror_plus("close");
 
1143
  }
1104
1144
  int status;
1105
1145
  pid_t pret = -1;
1106
1146
  errno = 0;
2427
2467
 
2428
2468
int main(int argc, char *argv[]){
2429
2469
  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
2430
2475
                        .priority = "SECURE256:!CTYPE-X.509"
2431
2476
                        ":+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256",
 
2477
#else
 
2478
#error "Needs GnuTLS 3.6.6 or later, or before 3.6.0"
 
2479
#endif
2432
2480
                        .current_server = NULL, .interfaces = NULL,
2433
2481
                        .interfaces_size = 0 };
2434
2482
  AvahiSServiceBrowser *sb = NULL;
2445
2493
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
2446
2494
  const char *seckey = PATHDIR "/" SECKEY;
2447
2495
  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
2448
2500
  const char *dh_params_file = NULL;
2449
2501
  char *interfaces_hooks = NULL;
2450
2502
  
2498
2550
      { .name = "pubkey", .key = 'p',
2499
2551
        .arg = "FILE",
2500
2552
        .doc = "OpenPGP public key file base name",
2501
 
        .group = 2 },
 
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 },
2502
2570
      { .name = "dh-bits", .key = 129,
2503
2571
        .arg = "BITS",
2504
2572
        .doc = "Bit length of the prime number used in the"
2560
2628
      case 'p':                 /* --pubkey */
2561
2629
        pubkey = arg;
2562
2630
        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;
2563
2641
      case 129:                 /* --dh-bits */
2564
2642
        errno = 0;
2565
2643
        tmpmax = strtoimax(arg, &tmp, 10);
2600
2678
        argp_state_help(state, state->out_stream,
2601
2679
                        (ARGP_HELP_STD_HELP | ARGP_HELP_EXIT_ERR)
2602
2680
                        & ~(unsigned int)ARGP_HELP_EXIT_OK);
 
2681
        __builtin_unreachable();
2603
2682
      case -3:                  /* --usage */
2604
2683
        argp_state_help(state, state->out_stream,
2605
2684
                        ARGP_HELP_USAGE | ARGP_HELP_EXIT_ERR);
 
2685
        __builtin_unreachable();
2606
2686
      case 'V':                 /* --version */
2607
2687
        fprintf_plus(state->out_stream, "%s\n", argp_program_version);
2608
2688
        exit(argp_err_exit_status);
2919
2999
    goto end;
2920
3000
  }
2921
3001
  
 
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
2922
3005
  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
2923
3009
  if(ret == -1){
2924
3010
    fprintf_plus(stderr, "init_gnutls_global failed\n");
2925
3011
    exitcode = EX_UNAVAILABLE;