/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/password-request.c

merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
75
75
#define BUFFER_SIZE 256
76
76
 
77
77
bool debug = false;
78
 
const char *keydir = "/conf/conf.d/mandos";
 
78
static const char *keydir = "/conf/conf.d/mandos";
 
79
static const char mandos_protocol_version[] = "1";
79
80
const char *argp_program_version = "mandosclient 0.9";
80
81
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
81
 
const char mandos_protocol_version[] = "1";
82
82
 
83
 
/* Used for passing in values through all the callback functions */
 
83
/* Used for passing in values through the Avahi callback functions */
84
84
typedef struct {
85
85
  AvahiSimplePoll *simple_poll;
86
86
  AvahiServer *server;
90
90
  const char *priority;
91
91
} mandos_context;
92
92
 
 
93
/*
 
94
 * Make room in "buffer" for at least BUFFER_SIZE additional bytes.
 
95
 * "buffer_capacity" is how much is currently allocated,
 
96
 * "buffer_length" is how much is already used.
 
97
 */
93
98
size_t adjustbuffer(char **buffer, size_t buffer_length,
94
99
                  size_t buffer_capacity){
95
100
  if (buffer_length + BUFFER_SIZE > buffer_capacity){
230
235
  
231
236
  *plaintext = NULL;
232
237
  while(true){
233
 
    plaintext_capacity = adjustbuffer(plaintext, (size_t)plaintext_length,
 
238
    plaintext_capacity = adjustbuffer(plaintext,
 
239
                                      (size_t)plaintext_length,
234
240
                                      plaintext_capacity);
235
241
    if (plaintext_capacity == 0){
236
242
        perror("adjustbuffer");
313
319
      != GNUTLS_E_SUCCESS) {
314
320
    fprintf (stderr, "GnuTLS memory error: %s\n",
315
321
             safer_gnutls_strerror(ret));
 
322
    gnutls_global_deinit ();
316
323
    return -1;
317
324
  }
318
325
  
330
337
            " '%s')\n", ret, pubkeyfile, seckeyfile);
331
338
    fprintf(stdout, "The GnuTLS error is: %s\n",
332
339
            safer_gnutls_strerror(ret));
333
 
    return -1;
 
340
    goto globalfail;
334
341
  }
335
342
  
336
343
  /* GnuTLS server initialization */
338
345
  if (ret != GNUTLS_E_SUCCESS) {
339
346
    fprintf (stderr, "Error in GnuTLS DH parameter initialization:"
340
347
             " %s\n", safer_gnutls_strerror(ret));
341
 
    return -1;
 
348
    goto globalfail;
342
349
  }
343
350
  ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
344
351
  if (ret != GNUTLS_E_SUCCESS) {
345
352
    fprintf (stderr, "Error in GnuTLS prime generation: %s\n",
346
353
             safer_gnutls_strerror(ret));
347
 
    return -1;
 
354
    goto globalfail;
348
355
  }
349
356
  
350
357
  gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
351
358
 
352
359
  return 0;
 
360
 
 
361
 globalfail:
 
362
 
 
363
  gnutls_certificate_free_credentials (mc->cred);
 
364
  gnutls_global_deinit ();
 
365
  return -1;
 
366
 
353
367
}
354
368
 
355
 
static int init_gnutls_session(mandos_context *mc, gnutls_session_t *session){
 
369
static int init_gnutls_session(mandos_context *mc,
 
370
                               gnutls_session_t *session){
356
371
  int ret;
357
372
  /* GnuTLS session creation */
358
373
  ret = gnutls_init(session, GNUTLS_SERVER);
368
383
      fprintf(stderr, "Syntax error at: %s\n", err);
369
384
      fprintf(stderr, "GnuTLS error: %s\n",
370
385
              safer_gnutls_strerror(ret));
 
386
      gnutls_deinit (*session);
371
387
      return -1;
372
388
    }
373
389
  }
377
393
  if (ret != GNUTLS_E_SUCCESS) {
378
394
    fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
379
395
            safer_gnutls_strerror(ret));
 
396
    gnutls_deinit (*session);
380
397
    return -1;
381
398
  }
382
399
  
398
415
                                      AvahiIfIndex if_index,
399
416
                                      mandos_context *mc){
400
417
  int ret, tcp_sd;
401
 
  struct sockaddr_in6 to;
 
418
  union { struct sockaddr in; struct sockaddr_in6 in6; } to;
402
419
  char *buffer = NULL;
403
420
  char *decrypted_buffer;
404
421
  size_t buffer_length = 0;
408
425
  int retval = 0;
409
426
  char interface[IF_NAMESIZE];
410
427
  gnutls_session_t session;
411
 
  gnutls_dh_params_t dh_params;
412
428
  
413
429
  ret = init_gnutls_session (mc, &session);
414
430
  if (ret != 0){
435
451
  }
436
452
  
437
453
  memset(&to,0,sizeof(to));     /* Spurious warning */
438
 
  to.sin6_family = AF_INET6;
 
454
  to.in6.sin6_family = AF_INET6;
439
455
  /* It would be nice to have a way to detect if we were passed an
440
456
     IPv4 address here.   Now we assume an IPv6 address. */
441
 
  ret = inet_pton(AF_INET6, ip, &to.sin6_addr);
 
457
  ret = inet_pton(AF_INET6, ip, &to.in6.sin6_addr);
442
458
  if (ret < 0 ){
443
459
    perror("inet_pton");
444
460
    return -1;
447
463
    fprintf(stderr, "Bad address: %s\n", ip);
448
464
    return -1;
449
465
  }
450
 
  to.sin6_port = htons(port);   /* Spurious warning */
 
466
  to.in6.sin6_port = htons(port);       /* Spurious warning */
451
467
  
452
 
  to.sin6_scope_id = (uint32_t)if_index;
 
468
  to.in6.sin6_scope_id = (uint32_t)if_index;
453
469
  
454
470
  if(debug){
455
471
    fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
456
472
    char addrstr[INET6_ADDRSTRLEN] = "";
457
 
    if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr,
 
473
    if(inet_ntop(to.in6.sin6_family, &(to.in6.sin6_addr), addrstr,
458
474
                 sizeof(addrstr)) == NULL){
459
475
      perror("inet_ntop");
460
476
    } else {
464
480
    }
465
481
  }
466
482
  
467
 
  ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
 
483
  ret = connect(tcp_sd, &to.in, sizeof(to));
468
484
  if (ret < 0){
469
485
    perror("connect");
470
486
    return -1;
519
535
  }
520
536
 
521
537
  while(true){
522
 
    buffer_capacity = adjustbuffer(&buffer, buffer_length, buffer_capacity);
 
538
    buffer_capacity = adjustbuffer(&buffer, buffer_length,
 
539
                                   buffer_capacity);
523
540
    if (buffer_capacity == 0){
524
541
      perror("adjustbuffer");
525
542
      retval = -1;
596
613
  free(buffer);
597
614
  close(tcp_sd);
598
615
  gnutls_deinit (session);
599
 
  gnutls_certificate_free_credentials (mc->cred);
600
 
  gnutls_global_deinit ();
601
616
  return retval;
602
617
}
603
618
 
734
749
    const char *seckeyfile = "seckey.txt";
735
750
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
736
751
                          .dh_bits = 1024, .priority = "SECURE256"};
 
752
    bool gnutls_initalized = false;
737
753
    
738
754
    {
739
755
      struct argp_option options[] = {
741
757
          .doc = "Debug mode", .group = 3 },
742
758
        { .name = "connect", .key = 'c',
743
759
          .arg = "IP",
744
 
          .doc = "Connect directly to a sepcified mandos server", .group = 1 },
 
760
          .doc = "Connect directly to a sepcified mandos server",
 
761
          .group = 1 },
745
762
        { .name = "interface", .key = 'i',
746
763
          .arg = "INTERFACE",
747
 
          .doc = "Interface that Avahi will conntect through", .group = 1 },
 
764
          .doc = "Interface that Avahi will conntect through",
 
765
          .group = 1 },
748
766
        { .name = "keydir", .key = 'd',
749
767
          .arg = "KEYDIR",
750
 
          .doc = "Directory where the openpgp keyring is", .group = 1 },
 
768
          .doc = "Directory where the openpgp keyring is",
 
769
          .group = 1 },
751
770
        { .name = "seckey", .key = 's',
752
771
          .arg = "SECKEY",
753
 
          .doc = "Secret openpgp key for gnutls authentication", .group = 1 },
 
772
          .doc = "Secret openpgp key for gnutls authentication",
 
773
          .group = 1 },
754
774
        { .name = "pubkey", .key = 'p',
755
775
          .arg = "PUBKEY",
756
 
          .doc = "Public openpgp key for gnutls authentication", .group = 2 },
 
776
          .doc = "Public openpgp key for gnutls authentication",
 
777
          .group = 2 },
757
778
        { .name = "dh-bits", .key = 129,
758
779
          .arg = "BITS",
759
 
          .doc = "dh-bits to use in gnutls communication", .group = 2 },
 
780
          .doc = "dh-bits to use in gnutls communication",
 
781
          .group = 2 },
760
782
        { .name = "priority", .key = 130,
761
783
          .arg = "PRIORITY",
762
784
          .doc = "GNUTLS priority", .group = 1 },
764
786
      };
765
787
 
766
788
      
767
 
      error_t parse_opt (int key, char *arg, struct argp_state *state) {
768
 
        /* Get the INPUT argument from `argp_parse', which we know is a
769
 
           pointer to our plugin list pointer. */
 
789
      error_t parse_opt (int key, char *arg,
 
790
                         struct argp_state *state) {
 
791
        /* Get the INPUT argument from `argp_parse', which we know is
 
792
           a pointer to our plugin list pointer. */
770
793
        switch (key) {
771
794
        case 128:
772
795
          debug = true;
810
833
 
811
834
      struct argp argp = { .options = options, .parser = parse_opt,
812
835
                           .args_doc = "",
813
 
                           .doc = "Mandos client -- Get and decrypt passwords from mandos server" };
 
836
                           .doc = "Mandos client -- Get and decrypt"
 
837
                           " passwords from mandos server" };
814
838
      argp_parse (&argp, argc, argv, 0, 0, NULL);
815
839
    }
816
840
      
831
855
    if (ret == -1){
832
856
      fprintf(stderr, "init_gnutls_global\n");
833
857
      goto end;
 
858
    } else {
 
859
      gnutls_initalized = true;
834
860
    }
835
861
 
836
862
    uid = getuid();
985
1011
        avahi_simple_poll_free(mc.simple_poll);
986
1012
    free(pubkeyfile);
987
1013
    free(seckeyfile);
 
1014
 
 
1015
    if (gnutls_initalized){
 
1016
      gnutls_certificate_free_credentials (mc.cred);
 
1017
      gnutls_global_deinit ();
 
1018
    }
988
1019
    
989
1020
    return exitcode;
990
1021
}