/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: Teddy Hogeborn
  • Date: 2008-07-20 06:33:48 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080720063348-jscgy5p0itrgvlo8
* mandos-clients.conf ([foo]): Uncommented.
  ([foo]/secret): New.
  ([foo]/secfile): Commented out.
  ([foo]/checker): Changed to "fping -q -- %%(fqdn)s".
  ([foo]/timeout): New.

* server.py: New modeline for Python and Emacs.  Set a logging format.
  (Client.__init__): Bug fix: Choose either the value from the options
                     object or pass the argument through string_to_delta
                     for both "timeout" and "interval".
  (Client.checker_callback): Bug fix: Do not log spurious "Checker for
                             <foo> failed" messages.
  (Client.start_checker): Moved "Starting checker" log message down to
                          just before actually starting the subprocess.
                          Do not redirect the subprocesses' stdout to a
                          pipe.
  (peer_certificate, fingerprint): Added docstrings.
  (entry_group_state_changed): Call "killme()" instead of
                               "main_loop.quit()".
  (daemon, killme): New functions.
  (exitstatus, main_loop_started): New global variables.
  (__main__): Removed the "--cert", "--key", "--ca", and "--crl"
              options.  Removed the sleep command from the default
              checker.  Add a console logger in debug mode.  Call
              "killme()" instead of "main_loop.quit()" when there are no
              more clients.  Call "daemon()" if not in debug mode.
              Register "cleanup()" to run at exit.  Ignore some
              signals.  Catch DBusException to detect another running
              server and exit cleanly.  Exit with "exitstatus".
  (cleanup): New function.

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
 
1
14
/***
2
15
  This file is part of avahi.
3
16
 
50
63
#include <errno.h>              /* perror() */
51
64
#include <gpgme.h>
52
65
 
53
 
// getopt long
54
 
#include <getopt.h>
55
66
 
56
67
#ifndef CERT_ROOT
57
68
#define CERT_ROOT "/conf/conf.d/cryptkeyreq/"
61
72
#define BUFFER_SIZE 256
62
73
#define DH_BITS 1024
63
74
 
64
 
bool debug = false;
65
 
char *interface = "eth0";
66
 
 
67
75
typedef struct {
68
76
  gnutls_session_t session;
69
77
  gnutls_certificate_credentials_t cred;
80
88
  size_t new_packet_length = 0;
81
89
  gpgme_engine_info_t engine_info;
82
90
 
83
 
  if (debug){
84
 
    fprintf(stderr, "Attempting to decrypt password from gpg packet\n");
85
 
  }
86
 
  
87
91
  /* Init GPGME */
88
92
  gpgme_check_version(NULL);
89
93
  gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
139
143
            gpgme_strsource(rc), gpgme_strerror(rc));
140
144
    return -1;
141
145
  }
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
 
  }
172
146
  
 
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
 
173
167
  /* Delete the GPGME FILE pointer cryptotext data buffer */
174
168
  gpgme_data_release(dh_crypto);
175
169
  
200
194
    new_packet_length += ret;
201
195
  }
202
196
 
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 */
 
197
   /* Delete the GPGME plaintext data buffer */
212
198
  gpgme_data_release(dh_plain);
213
199
  return new_packet_length;
214
200
}
227
213
int initgnutls(encrypted_session *es){
228
214
  const char *err;
229
215
  int ret;
230
 
 
231
 
  if(debug){
232
 
    fprintf(stderr, "Initializing gnutls\n");
233
 
  }
234
 
 
235
216
  
236
217
  if ((ret = gnutls_global_init ())
237
218
      != GNUTLS_E_SUCCESS) {
239
220
    return -1;
240
221
  }
241
222
 
242
 
  if (debug){
243
 
    gnutls_global_set_log_level(11);
244
 
    gnutls_global_set_log_function(debuggnutls);
245
 
  }
246
 
  
 
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
 
247
227
 
248
228
  /* openpgp credentials */
249
229
  if ((ret = gnutls_certificate_allocate_credentials (&es->cred))
252
232
    return -1;
253
233
  }
254
234
 
255
 
  if(debug){
256
 
    fprintf(stderr, "Attempting to use openpgp certificate %s"
257
 
            " and keyfile %s as gnutls credentials\n", CERTFILE, KEYFILE);
258
 
  }
259
 
 
260
235
  ret = gnutls_certificate_set_openpgp_key_file
261
236
    (es->cred, CERTFILE, KEYFILE, GNUTLS_OPENPGP_FMT_BASE64);
262
237
  if (ret != GNUTLS_E_SUCCESS) {
330
305
  ssize_t decrypted_buffer_size;
331
306
  int retval = 0;
332
307
 
333
 
  if(debug){
334
 
    fprintf(stderr, "Setting up a tcp connection to %s\n", ip);
335
 
  }
336
308
  
337
309
  tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
338
310
  if(tcp_sd < 0) {
339
311
    perror("socket");
340
312
    return -1;
341
313
  }
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);
 
314
  
 
315
  ret = setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
348
316
  if(tcp_sd < 0) {
349
317
    perror("setsockopt bindtodevice");
350
318
    return -1;
362
330
    return -1;
363
331
  }
364
332
  to.sin6_port = htons(port);
365
 
  to.sin6_scope_id = if_nametoindex(interface);
366
 
 
367
 
  if(debug){
368
 
    fprintf(stderr, "Connection to: %s\n", ip);
369
 
  }
 
333
  to.sin6_scope_id = if_nametoindex("eth0");
370
334
  
371
335
  ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
372
336
  if (ret < 0){
383
347
  
384
348
  gnutls_transport_set_ptr (es.session, (gnutls_transport_ptr_t) tcp_sd);
385
349
 
386
 
  if(debug){
387
 
    fprintf(stderr, "Establishing tls session with %s\n", ip);
388
 
  }
389
 
 
390
 
  
391
350
  ret = gnutls_handshake (es.session);
392
351
  
393
352
  if (ret != GNUTLS_E_SUCCESS){
397
356
    goto exit;
398
357
  }
399
358
 
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
 
 
 
359
  //retrive password
406
360
  while(true){
407
361
    if (buffer_length + BUFFER_SIZE > buffer_capacity){
408
362
      buffer = realloc(buffer, buffer_capacity + BUFFER_SIZE);
442
396
      buffer_length += ret;
443
397
    }
444
398
  }
445
 
  
 
399
 
446
400
  if (buffer_length > 0){
447
 
    if ((decrypted_buffer_size = gpg_packet_decrypt(buffer, buffer_length, &decrypted_buffer, CERT_ROOT)) >= 0){
 
401
    if ((decrypted_buffer_size = gpg_packet_decrypt(buffer, buffer_length, &decrypted_buffer, CERT_ROOT)) == 0){
 
402
      retval = -1;
 
403
    } else {
448
404
      fwrite (decrypted_buffer, 1, decrypted_buffer_size, stdout);
449
405
      free(decrypted_buffer);
450
 
    } else {
451
 
      retval = -1;
452
406
    }
453
407
  }
454
408
 
 
409
  free(buffer);
 
410
 
455
411
  //shutdown procedure
456
 
 
457
 
  if(debug){
458
 
    fprintf(stderr, "Closing tls session\n");
459
 
  }
460
 
 
461
 
  free(buffer);
462
412
  gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
463
413
 exit:
464
414
  close(tcp_sd);
498
448
        case AVAHI_RESOLVER_FOUND: {
499
449
          char ip[AVAHI_ADDRESS_STR_MAX];
500
450
            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
 
            }
504
451
            int ret = start_mandos_communcation(ip, port);
505
452
            if (ret == 0){
506
453
              exit(EXIT_SUCCESS);
560
507
    AvahiServerConfig config;
561
508
    AvahiSServiceBrowser *sb = NULL;
562
509
    int error;
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
 
    }
 
510
    int ret = 1;
 
511
 
 
512
    avahi_set_log_function(empty_log);
593
513
    
594
514
    /* Initialize the psuedo-RNG */
595
515
    srand(time(NULL));
597
517
    /* Allocate main loop object */
598
518
    if (!(simple_poll = avahi_simple_poll_new())) {
599
519
        fprintf(stderr, "Failed to create simple poll object.\n");
600
 
        
601
 
        goto exit;
 
520
        goto fail;
602
521
    }
603
522
 
604
523
    /* Do not publish any local records */
608
527
    config.publish_workstation = 0;
609
528
    config.publish_domain = 0;
610
529
 
 
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
    
611
535
    /* Allocate a new server */
612
536
    server = avahi_server_new(avahi_simple_poll_get(simple_poll), &config, NULL, NULL, &error);
613
537
 
614
538
    /* Free the configuration data */
615
539
    avahi_server_config_free(&config);
616
540
 
617
 
    /* Check if creating the server object succeeded */
 
541
    /* Check wether creating the server object succeeded */
618
542
    if (!server) {
619
543
        fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
620
 
        returncode = EXIT_FAILURE;
621
 
        goto exit;
 
544
        goto fail;
622
545
    }
623
546
    
624
547
    /* Create the service browser */
625
548
    if (!(sb = avahi_s_service_browser_new(server, if_nametoindex("eth0"), AVAHI_PROTO_INET6, "_mandos._tcp", NULL, 0, browse_callback, server))) {
626
549
        fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_server_errno(server)));
627
 
        returncode = EXIT_FAILURE;
628
 
        goto exit;
 
550
        goto fail;
629
551
    }
630
552
    
631
553
    /* Run the main loop */
632
 
 
633
 
    if (debug){
634
 
      fprintf(stderr, "Starting avahi loop search\n");
635
 
    }
636
 
    
637
554
    avahi_simple_poll_loop(simple_poll);
638
555
    
639
 
exit:
640
 
 
641
 
    if (debug){
642
 
      fprintf(stderr, "%s exiting\n", argv[0]);
643
 
    }
 
556
    ret = 0;
 
557
    
 
558
fail:
644
559
    
645
560
    /* Cleanup things */
646
561
    if (sb)
652
567
    if (simple_poll)
653
568
        avahi_simple_poll_free(simple_poll);
654
569
 
655
 
    return returncode;
 
570
    return ret;
656
571
}