/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/mandosclient.c

  • Committer: Björn Påhlsson
  • Date: 2008-07-21 03:58:36 UTC
  • mfrom: (17 mandos)
  • mto: This revision was merged to the branch mainline in revision 20.
  • Revision ID: belorn@braxen-20080721035836-v7220bmolr608r61
Added getopt_long support for mandosclient and passprompt
Added support for --interface for mandosclient
Added support for --prefix for passprompt

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id$ */
2
 
 
3
 
/* PLEASE NOTE *
4
 
 * This file demonstrates how to use Avahi's core API, this is
5
 
 * the embeddable mDNS stack for embedded applications.
6
 
 *
7
 
 * End user applications should *not* use this API and should use
8
 
 * the D-Bus or C APIs, please see
9
 
 * client-browse-services.c and glib-integration.c
10
 
 * 
11
 
 * I repeat, you probably do *not* want to use this example.
12
 
 */
13
 
 
14
1
/***
15
2
  This file is part of avahi.
16
3
 
63
50
#include <errno.h>              /* perror() */
64
51
#include <gpgme.h>
65
52
 
 
53
// getopt long
 
54
#include <getopt.h>
66
55
 
67
56
#ifndef CERT_ROOT
68
57
#define CERT_ROOT "/conf/conf.d/cryptkeyreq/"
72
61
#define BUFFER_SIZE 256
73
62
#define DH_BITS 1024
74
63
 
 
64
bool debug = false;
 
65
char *interface = "eth0";
 
66
 
75
67
typedef struct {
76
68
  gnutls_session_t session;
77
69
  gnutls_certificate_credentials_t cred;
88
80
  size_t new_packet_length = 0;
89
81
  gpgme_engine_info_t engine_info;
90
82
 
 
83
  if (debug){
 
84
    fprintf(stderr, "Attempting to decrypt password from gpg packet\n");
 
85
  }
 
86
  
91
87
  /* Init GPGME */
92
88
  gpgme_check_version(NULL);
93
89
  gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
143
139
            gpgme_strsource(rc), gpgme_strerror(rc));
144
140
    return -1;
145
141
  }
 
142
 
 
143
  if(debug){
 
144
    fprintf(stderr, "decryption of gpg packet succeeded\n");
 
145
  }
 
146
 
 
147
  if (debug){
 
148
    gpgme_decrypt_result_t result;
 
149
    result = gpgme_op_decrypt_result(ctx);
 
150
    if (result == NULL){
 
151
      fprintf(stderr, "gpgme_op_decrypt_result failed\n");
 
152
    } else {
 
153
      fprintf(stderr, "Unsupported algorithm: %s\n", result->unsupported_algorithm);
 
154
      fprintf(stderr, "Wrong key usage: %d\n", result->wrong_key_usage);
 
155
      if(result->file_name != NULL){
 
156
        fprintf(stderr, "File name: %s\n", result->file_name);
 
157
      }
 
158
      gpgme_recipient_t recipient;
 
159
      recipient = result->recipients;
 
160
      if(recipient){
 
161
        while(recipient != NULL){
 
162
          fprintf(stderr, "Public key algorithm: %s\n",
 
163
                  gpgme_pubkey_algo_name(recipient->pubkey_algo));
 
164
          fprintf(stderr, "Key ID: %s\n", recipient->keyid);
 
165
          fprintf(stderr, "Secret key available: %s\n",
 
166
                  recipient->status == GPG_ERR_NO_SECKEY ? "No" : "Yes");
 
167
          recipient = recipient->next;
 
168
        }
 
169
      }
 
170
    }
 
171
  }
146
172
  
147
 
/*   gpgme_decrypt_result_t result; */
148
 
/*   result = gpgme_op_decrypt_result(ctx); */
149
 
/*   fprintf(stderr, "Unsupported algorithm: %s\n", result->unsupported_algorithm); */
150
 
/*   fprintf(stderr, "Wrong key usage: %d\n", result->wrong_key_usage); */
151
 
/*   if(result->file_name != NULL){ */
152
 
/*     fprintf(stderr, "File name: %s\n", result->file_name); */
153
 
/*   } */
154
 
/*   gpgme_recipient_t recipient; */
155
 
/*   recipient = result->recipients; */
156
 
/*   if(recipient){ */
157
 
/*     while(recipient != NULL){ */
158
 
/*       fprintf(stderr, "Public key algorithm: %s\n", */
159
 
/*            gpgme_pubkey_algo_name(recipient->pubkey_algo)); */
160
 
/*       fprintf(stderr, "Key ID: %s\n", recipient->keyid); */
161
 
/*       fprintf(stderr, "Secret key available: %s\n", */
162
 
/*            recipient->status == GPG_ERR_NO_SECKEY ? "No" : "Yes"); */
163
 
/*       recipient = recipient->next; */
164
 
/*     } */
165
 
/*   } */
166
 
 
167
173
  /* Delete the GPGME FILE pointer cryptotext data buffer */
168
174
  gpgme_data_release(dh_crypto);
169
175
  
194
200
    new_packet_length += ret;
195
201
  }
196
202
 
197
 
   /* Delete the GPGME plaintext data buffer */
 
203
  /* FIXME: check characters before printing to screen so to not print
 
204
     terminal control characters */
 
205
  /*   if(debug){ */
 
206
  /*     fprintf(stderr, "decrypted password is: "); */
 
207
  /*     fwrite(*new_packet, 1, new_packet_length, stderr); */
 
208
  /*     fprintf(stderr, "\n"); */
 
209
  /*   } */
 
210
  
 
211
  /* Delete the GPGME plaintext data buffer */
198
212
  gpgme_data_release(dh_plain);
199
213
  return new_packet_length;
200
214
}
213
227
int initgnutls(encrypted_session *es){
214
228
  const char *err;
215
229
  int ret;
 
230
 
 
231
  if(debug){
 
232
    fprintf(stderr, "Initializing gnutls\n");
 
233
  }
 
234
 
216
235
  
217
236
  if ((ret = gnutls_global_init ())
218
237
      != GNUTLS_E_SUCCESS) {
220
239
    return -1;
221
240
  }
222
241
 
223
 
  /* Uncomment to enable full debuggin on the gnutls library */
224
 
  /*   gnutls_global_set_log_level(11); */
225
 
  /*   gnutls_global_set_log_function(debuggnutls); */
226
 
 
 
242
  if (debug){
 
243
    gnutls_global_set_log_level(11);
 
244
    gnutls_global_set_log_function(debuggnutls);
 
245
  }
 
246
  
227
247
 
228
248
  /* openpgp credentials */
229
249
  if ((ret = gnutls_certificate_allocate_credentials (&es->cred))
232
252
    return -1;
233
253
  }
234
254
 
 
255
  if(debug){
 
256
    fprintf(stderr, "Attempting to use openpgp certificate %s"
 
257
            " and keyfile %s as gnutls credentials\n", CERTFILE, KEYFILE);
 
258
  }
 
259
 
235
260
  ret = gnutls_certificate_set_openpgp_key_file
236
261
    (es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
237
262
  if (ret != GNUTLS_E_SUCCESS) {
305
330
  ssize_t decrypted_buffer_size;
306
331
  int retval = 0;
307
332
 
 
333
  if(debug){
 
334
    fprintf(stderr, "Setting up a tcp connection to %s\n", ip);
 
335
  }
308
336
  
309
337
  tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
310
338
  if(tcp_sd < 0) {
311
339
    perror("socket");
312
340
    return -1;
313
341
  }
314
 
  
315
 
  ret = setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
 
342
 
 
343
  if(debug){
 
344
    fprintf(stderr, "Binding to interface %s\n", interface);
 
345
  }
 
346
 
 
347
  ret = setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, interface, 5);
316
348
  if(tcp_sd < 0) {
317
349
    perror("setsockopt bindtodevice");
318
350
    return -1;
330
362
    return -1;
331
363
  }
332
364
  to.sin6_port = htons(port);
333
 
  to.sin6_scope_id = if_nametoindex("eth0");
 
365
  to.sin6_scope_id = if_nametoindex(interface);
 
366
 
 
367
  if(debug){
 
368
    fprintf(stderr, "Connection to: %s\n", ip);
 
369
  }
334
370
  
335
371
  ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
336
372
  if (ret < 0){
347
383
  
348
384
  gnutls_transport_set_ptr (es.session, (gnutls_transport_ptr_t) tcp_sd);
349
385
 
 
386
  if(debug){
 
387
    fprintf(stderr, "Establishing tls session with %s\n", ip);
 
388
  }
 
389
 
 
390
  
350
391
  ret = gnutls_handshake (es.session);
351
392
  
352
393
  if (ret != GNUTLS_E_SUCCESS){
356
397
    goto exit;
357
398
  }
358
399
 
359
 
  //retrive password
 
400
  //Retrieve gpg packet that contains the wanted password
 
401
 
 
402
  if(debug){
 
403
    fprintf(stderr, "Retrieving pgp encrypted password from %s\n", ip);
 
404
  }
 
405
 
360
406
  while(true){
361
407
    if (buffer_length + BUFFER_SIZE > buffer_capacity){
362
408
      buffer = realloc(buffer, buffer_capacity + BUFFER_SIZE);
396
442
      buffer_length += ret;
397
443
    }
398
444
  }
399
 
 
 
445
  
400
446
  if (buffer_length > 0){
401
 
    if ((decrypted_buffer_size = gpg_packet_decrypt(buffer, buffer_length, &decrypted_buffer, CERT_ROOT)) == 0){
402
 
      retval = -1;
403
 
    } else {
 
447
    if ((decrypted_buffer_size = gpg_packet_decrypt(buffer, buffer_length, &decrypted_buffer, CERT_ROOT)) >= 0){
404
448
      fwrite (decrypted_buffer, 1, decrypted_buffer_size, stdout);
405
449
      free(decrypted_buffer);
 
450
    } else {
 
451
      retval = -1;
406
452
    }
407
453
  }
408
454
 
 
455
  //shutdown procedure
 
456
 
 
457
  if(debug){
 
458
    fprintf(stderr, "Closing tls session\n");
 
459
  }
 
460
 
409
461
  free(buffer);
410
 
 
411
 
  //shutdown procedure
412
462
  gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
413
463
 exit:
414
464
  close(tcp_sd);
448
498
        case AVAHI_RESOLVER_FOUND: {
449
499
          char ip[AVAHI_ADDRESS_STR_MAX];
450
500
            avahi_address_snprint(ip, sizeof(ip), address);
 
501
            if(debug){
 
502
              fprintf(stderr, "Mandos server found at %s on port %d\n", ip, port);
 
503
            }
451
504
            int ret = start_mandos_communcation(ip, port);
452
505
            if (ret == 0){
453
506
              exit(EXIT_SUCCESS);
507
560
    AvahiServerConfig config;
508
561
    AvahiSServiceBrowser *sb = NULL;
509
562
    int error;
510
 
    int ret = 1;
511
 
 
512
 
    avahi_set_log_function(empty_log);
 
563
    int ret;
 
564
    int returncode = EXIT_SUCCESS;
 
565
 
 
566
    while (true){
 
567
      static struct option long_options[] = {
 
568
        {"debug", no_argument, (int *)&debug, 1},
 
569
        {"interface", required_argument, 0, 'i'},
 
570
        {0, 0, 0, 0} };
 
571
 
 
572
      int option_index = 0;
 
573
      ret = getopt_long (argc, argv, "i:", long_options, &option_index);
 
574
 
 
575
      if (ret == -1){
 
576
        break;
 
577
      }
 
578
      
 
579
      switch(ret){
 
580
      case 0:
 
581
        break;
 
582
      case 'i':
 
583
        interface = optarg;
 
584
        break;
 
585
      default:
 
586
        exit(EXIT_FAILURE);
 
587
      }
 
588
    }
 
589
    
 
590
    if (not debug){
 
591
      avahi_set_log_function(empty_log);
 
592
    }
513
593
    
514
594
    /* Initialize the psuedo-RNG */
515
595
    srand(time(NULL));
517
597
    /* Allocate main loop object */
518
598
    if (!(simple_poll = avahi_simple_poll_new())) {
519
599
        fprintf(stderr, "Failed to create simple poll object.\n");
520
 
        goto fail;
 
600
        
 
601
        goto exit;
521
602
    }
522
603
 
523
604
    /* Do not publish any local records */
527
608
    config.publish_workstation = 0;
528
609
    config.publish_domain = 0;
529
610
 
530
 
/*     /\* Set a unicast DNS server for wide area DNS-SD *\/ */
531
 
/*     avahi_address_parse("193.11.177.11", AVAHI_PROTO_UNSPEC, &config.wide_area_servers[0]); */
532
 
/*     config.n_wide_area_servers = 1; */
533
 
/*     config.enable_wide_area = 1; */
534
 
    
535
611
    /* Allocate a new server */
536
612
    server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
537
613
 
538
614
    /* Free the configuration data */
539
615
    avahi_server_config_free(&config);
540
616
 
541
 
    /* Check wether creating the server object succeeded */
 
617
    /* Check if creating the server object succeeded */
542
618
    if (!server) {
543
619
        fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
544
 
        goto fail;
 
620
        returncode = EXIT_FAILURE;
 
621
        goto exit;
545
622
    }
546
623
    
547
624
    /* Create the service browser */
548
625
    if (!(sb = avahi_s_service_browser_new(server, if_nametoindex("eth0"), AVAHI_PROTO_INET6, "_mandos._tcp", NULL, 0, browse_callback, server))) {
549
626
        fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
550
 
        goto fail;
 
627
        returncode = EXIT_FAILURE;
 
628
        goto exit;
551
629
    }
552
630
    
553
631
    /* Run the main loop */
 
632
 
 
633
    if (debug){
 
634
      fprintf(stderr, "Starting avahi loop search\n");
 
635
    }
 
636
    
554
637
    avahi_simple_poll_loop(simple_poll);
555
638
    
556
 
    ret = 0;
557
 
    
558
 
fail:
 
639
exit:
 
640
 
 
641
    if (debug){
 
642
      fprintf(stderr, "%s exiting\n", argv[0]);
 
643
    }
559
644
    
560
645
    /* Cleanup things */
561
646
    if (sb)
567
652
    if (simple_poll)
568
653
        avahi_simple_poll_free(simple_poll);
569
654
 
570
 
    return ret;
 
655
    return returncode;
571
656
}