284
285
if ((ret = gnutls_global_init ())
285
286
!= GNUTLS_E_SUCCESS) {
286
fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
287
fprintf (stderr, "GnuTLS global_init: %s\n",
288
safer_gnutls_strerror(ret));
293
/* "Use a log level over 10 to enable all debugging options."
291
296
gnutls_global_set_log_level(11);
292
297
gnutls_global_set_log_function(debuggnutls);
295
/* openpgp credentials */
300
/* OpenPGP credentials */
296
301
if ((ret = gnutls_certificate_allocate_credentials (&mc->cred))
297
302
!= GNUTLS_E_SUCCESS) {
298
fprintf (stderr, "memory error: %s\n",
303
fprintf (stderr, "GnuTLS memory error: %s\n",
299
304
safer_gnutls_strerror(ret));
309
314
ret = gnutls_certificate_set_openpgp_key_file
310
315
(mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
311
316
if (ret != GNUTLS_E_SUCCESS) {
313
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
315
ret, pubkeyfile, seckeyfile);
316
fprintf(stdout, "The Error is: %s\n",
318
"Error[%d] while reading the OpenPGP key pair ('%s',"
319
" '%s')\n", ret, pubkeyfile, seckeyfile);
320
fprintf(stdout, "The GnuTLS error is: %s\n",
317
321
safer_gnutls_strerror(ret));
321
//GnuTLS server initialization
322
if ((ret = gnutls_dh_params_init(dh_params))
323
!= GNUTLS_E_SUCCESS) {
324
fprintf (stderr, "Error in dh parameter initialization: %s\n",
325
safer_gnutls_strerror(ret));
325
/* GnuTLS server initialization */
326
ret = gnutls_dh_params_init(dh_params);
327
if (ret != GNUTLS_E_SUCCESS) {
328
fprintf (stderr, "Error in GnuTLS DH parameter initialization:"
329
" %s\n", safer_gnutls_strerror(ret));
329
if ((ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits))
330
!= GNUTLS_E_SUCCESS) {
331
fprintf (stderr, "Error in prime generation: %s\n",
332
ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits);
333
if (ret != GNUTLS_E_SUCCESS) {
334
fprintf (stderr, "Error in GnuTLS prime generation: %s\n",
332
335
safer_gnutls_strerror(ret));
336
339
gnutls_certificate_set_dh_params(mc->cred, *dh_params);
338
// GnuTLS session creation
339
if ((ret = gnutls_init(session, GNUTLS_SERVER))
340
!= GNUTLS_E_SUCCESS){
341
/* GnuTLS session creation */
342
ret = gnutls_init(session, GNUTLS_SERVER);
343
if (ret != GNUTLS_E_SUCCESS){
341
344
fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
342
345
safer_gnutls_strerror(ret));
345
if ((ret = gnutls_priority_set_direct(*session, mc->priority, &err))
346
!= GNUTLS_E_SUCCESS) {
347
fprintf(stderr, "Syntax error at: %s\n", err);
348
fprintf(stderr, "GnuTLS error: %s\n",
349
safer_gnutls_strerror(ret));
350
ret = gnutls_priority_set_direct(*session, mc->priority, &err);
351
if (ret != GNUTLS_E_SUCCESS) {
352
fprintf(stderr, "Syntax error at: %s\n", err);
353
fprintf(stderr, "GnuTLS error: %s\n",
354
safer_gnutls_strerror(ret));
353
if ((ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
355
!= GNUTLS_E_SUCCESS) {
356
fprintf(stderr, "Error setting a credentials set: %s\n",
359
ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
361
if (ret != GNUTLS_E_SUCCESS) {
362
fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
357
363
safer_gnutls_strerror(ret));
442
ret = initgnutls (mc, &session, &dh_params);
458
fprintf(stderr, "Establishing TLS session with %s\n", ip);
448
461
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) tcp_sd);
451
fprintf(stderr, "Establishing TLS session with %s\n", ip);
454
463
ret = gnutls_handshake (session);
456
465
if (ret != GNUTLS_E_SUCCESS){
458
fprintf(stderr, "\n*** Handshake failed ***\n");
467
fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
459
468
gnutls_perror (ret);
465
//Retrieve OpenPGP packet that contains the wanted password
474
/* Read OpenPGP packet that contains the wanted password */
468
477
fprintf(stderr, "Retrieving pgp encrypted password from %s\n",
492
502
case GNUTLS_E_REHANDSHAKE:
493
503
ret = gnutls_handshake (session);
495
fprintf(stderr, "\n*** Handshake failed ***\n");
505
fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
496
506
gnutls_perror (ret);
502
512
fprintf(stderr, "Unknown error while reading data from"
503
" encrypted session with mandos server\n");
513
" encrypted session with Mandos server\n");
505
515
gnutls_bye (session, GNUTLS_SHUT_RDWR);
509
519
buffer_length += (size_t) ret;
524
fprintf(stderr, "Closing TLS session\n");
527
gnutls_bye (session, GNUTLS_SHUT_RDWR);
513
529
if (buffer_length > 0){
514
530
decrypted_buffer_size = pgp_packet_decrypt(buffer,
585
596
char ip[AVAHI_ADDRESS_STR_MAX];
586
597
avahi_address_snprint(ip, sizeof(ip), address);
588
fprintf(stderr, "Mandos server \"%s\" found on %s (%s) on"
589
" port %d\n", name, host_name, ip, port);
599
fprintf(stderr, "Mandos server \"%s\" found on %s (%s, %d) on"
600
" port %d\n", name, host_name, ip, interface, port);
591
602
int ret = start_mandos_communication(ip, port, interface, mc);
618
629
case AVAHI_BROWSER_FAILURE:
620
fprintf(stderr, "(Browser) %s\n",
631
fprintf(stderr, "(Avahi browser) %s\n",
621
632
avahi_strerror(avahi_server_errno(mc->server)));
622
633
avahi_simple_poll_quit(mc->simple_poll);
625
636
case AVAHI_BROWSER_NEW:
626
/* We ignore the returned resolver object. In the callback
627
function we free it. If the server is terminated before
628
the callback function is called the server will free
629
the resolver for us. */
637
/* We ignore the returned Avahi resolver object. In the callback
638
function we free it. If the Avahi server is terminated before
639
the callback function is called the Avahi server will free the
631
642
if (!(avahi_s_service_resolver_new(mc->server, interface,
632
643
protocol, name, type, domain,
633
644
AVAHI_PROTO_INET6, 0,
634
645
resolve_callback, mc)))
635
fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
636
avahi_strerror(avahi_server_errno(mc->server)));
646
fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
647
name, avahi_strerror(avahi_server_errno(mc->server)));
639
650
case AVAHI_BROWSER_REMOVE:
681
693
mandos_context mc = { .simple_poll = NULL, .server = NULL,
682
694
.dh_bits = 1024, .priority = "SECURE256"};
684
debug_int = debug ? 1 : 0;
686
struct option long_options[] = {
687
{"debug", no_argument, &debug_int, 1},
688
{"connect", required_argument, NULL, 'c'},
689
{"interface", required_argument, NULL, 'i'},
690
{"keydir", required_argument, NULL, 'd'},
691
{"seckey", required_argument, NULL, 's'},
692
{"pubkey", required_argument, NULL, 'p'},
693
{"dh-bits", required_argument, NULL, 'D'},
694
{"priority", required_argument, NULL, 'P'},
697
int option_index = 0;
698
ret = getopt_long (argc, argv, "i:", long_options,
725
mc.dh_bits = (unsigned int) strtol(optarg, NULL, 10);
697
/* Temporary int to get the address of for getopt_long */
698
int debug_int = debug ? 1 : 0;
700
struct option long_options[] = {
701
{"debug", no_argument, &debug_int, 1},
702
{"connect", required_argument, NULL, 'c'},
703
{"interface", required_argument, NULL, 'i'},
704
{"keydir", required_argument, NULL, 'd'},
705
{"seckey", required_argument, NULL, 's'},
706
{"pubkey", required_argument, NULL, 'p'},
707
{"dh-bits", required_argument, NULL, 'D'},
708
{"priority", required_argument, NULL, 'P'},
711
int option_index = 0;
712
ret = getopt_long (argc, argv, "i:", long_options,
739
mc.dh_bits = (unsigned int) strtol(optarg, NULL, 10);
746
mc.priority = optarg;
750
/* getopt_long() has already printed a message about the
751
unrcognized option, so just exit. */
728
752
exit(EXIT_FAILURE);
732
mc.priority = optarg;
755
/* Set the global debug flag from the temporary int */
756
debug = debug_int ? true : false;
739
debug = debug_int ? true : false;
741
759
pubkeyfile = combinepath(keydir, pubkeyfile);
742
760
if (pubkeyfile == NULL){
743
761
perror("combinepath");
744
returncode = EXIT_FAILURE;
762
exitcode = EXIT_FAILURE;
748
766
seckeyfile = combinepath(keydir, seckeyfile);
749
767
if (seckeyfile == NULL){
750
768
perror("combinepath");
754
772
if_index = (AvahiIfIndex) if_nametoindex(interface);
784
sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
787
returncode = EXIT_FAILURE;
790
strcpy(network.ifr_name, interface); /* Spurious warning */
791
ret = ioctl(sd, SIOCGIFFLAGS, &network);
794
perror("ioctl SIOCGIFFLAGS");
795
returncode = EXIT_FAILURE;
798
if((network.ifr_flags & IFF_UP) == 0){
799
network.ifr_flags |= IFF_UP;
800
ret = ioctl(sd, SIOCSIFFLAGS, &network);
802
/* If the interface is down, bring it up */
804
sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
807
exitcode = EXIT_FAILURE;
810
strcpy(network.ifr_name, interface); /* Spurious warning */
811
ret = ioctl(sd, SIOCGIFFLAGS, &network);
802
perror("ioctl SIOCSIFFLAGS");
803
returncode = EXIT_FAILURE;
813
perror("ioctl SIOCGIFFLAGS");
814
exitcode = EXIT_FAILURE;
817
if((network.ifr_flags & IFF_UP) == 0){
818
network.ifr_flags |= IFF_UP;
819
ret = ioctl(sd, SIOCSIFFLAGS, &network);
821
perror("ioctl SIOCSIFFLAGS");
822
exitcode = EXIT_FAILURE;
810
830
avahi_set_log_function(empty_log);
813
/* Initialize the psuedo-RNG */
833
/* Initialize the pseudo-RNG for Avahi */
814
834
srand((unsigned int) time(NULL));
816
/* Allocate main loop object */
817
if (!(mc.simple_poll = avahi_simple_poll_new())) {
818
fprintf(stderr, "Failed to create simple poll object.\n");
819
returncode = EXIT_FAILURE;
823
/* Do not publish any local records */
824
avahi_server_config_init(&config);
825
config.publish_hinfo = 0;
826
config.publish_addresses = 0;
827
config.publish_workstation = 0;
828
config.publish_domain = 0;
830
/* Allocate a new server */
831
mc.server=avahi_server_new(avahi_simple_poll_get(mc.simple_poll),
832
&config, NULL, NULL, &error);
834
/* Free the configuration data */
835
avahi_server_config_free(&config);
837
/* Check if creating the server object succeeded */
839
fprintf(stderr, "Failed to create server: %s\n",
836
/* Allocate main Avahi loop object */
837
mc.simple_poll = avahi_simple_poll_new();
838
if (mc.simple_poll == NULL) {
839
fprintf(stderr, "Avahi: Failed to create simple poll"
841
exitcode = EXIT_FAILURE;
846
AvahiServerConfig config;
847
/* Do not publish any local Zeroconf records */
848
avahi_server_config_init(&config);
849
config.publish_hinfo = 0;
850
config.publish_addresses = 0;
851
config.publish_workstation = 0;
852
config.publish_domain = 0;
854
/* Allocate a new server */
855
mc.server = avahi_server_new(avahi_simple_poll_get
856
(mc.simple_poll), &config, NULL,
859
/* Free the Avahi configuration data */
860
avahi_server_config_free(&config);
863
/* Check if creating the Avahi server object succeeded */
864
if (mc.server == NULL) {
865
fprintf(stderr, "Failed to create Avahi server: %s\n",
840
866
avahi_strerror(error));
841
returncode = EXIT_FAILURE;
867
exitcode = EXIT_FAILURE;
845
/* Create the service browser */
871
/* Create the Avahi service browser */
846
872
sb = avahi_s_service_browser_new(mc.server, if_index,
847
873
AVAHI_PROTO_INET6,
848
874
"_mandos._tcp", NULL, 0,
849
875
browse_callback, &mc);
851
877
fprintf(stderr, "Failed to create service browser: %s\n",
852
878
avahi_strerror(avahi_server_errno(mc.server)));
853
returncode = EXIT_FAILURE;
879
exitcode = EXIT_FAILURE;
857
883
/* Run the main loop */
860
fprintf(stderr, "Starting avahi loop search\n");
886
fprintf(stderr, "Starting Avahi loop search\n");
863
889
avahi_simple_poll_loop(mc.simple_poll);
868
894
fprintf(stderr, "%s exiting\n", argv[0]);
871
897
/* Cleanup things */
873
899
avahi_s_service_browser_free(sb);
901
if (mc.server != NULL)
876
902
avahi_server_free(mc.server);
904
if (mc.simple_poll != NULL)
879
905
avahi_simple_poll_free(mc.simple_poll);
880
906
free(pubkeyfile);
881
907
free(seckeyfile);