/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-08-03 01:09:36 UTC
  • mfrom: (24.1.9 mandos)
  • Revision ID: teddy@fukt.bsnet.se-20080803010936-ujme8tgxceszfbi1
* plugbasedclient.c (main): New "--userid" and "--groupid" options.
                            Take an additional non-option argument and
                            parse it as a plus-separated and -prefixed
                            list of additional options.

* plugins.d/mandosclient.c (DH_BITS): Replaced with
                                      "mandos_context.dh_bits".  All
                                      users changed.
  (certdir): Renamed to "keydir".  All users changed.
  (certfile): Renamed to "pubkeyfile".  All users changed.
  (certkey): Renamed to "seckeyfile".  All users changed.
  (encrypted_session): Replaced with "mandos_context".  All users
                       changed.
  (initgnutls): Take additional "session" and "dh_params" arguments.
                All callers changed.
  (start_mandos_communication): Take additional "mc" argument.  All
                                callers changed.  Print target IPv6
                                address if different than supplied
                                string.
  (simple_poll) Replaced with "mandos_context.simple_poll".  All users
                changed.
  (server): Replaced with "mandos_context.server".  All users changed.
  (main): Default interface to "eth0".  Rename "--certdir" to
          "--keydir", "--certkey" to "--seckey", and "--certfile" to
          "--pubkey".  New options "--dh-bits" and "--priority".  If
          the interface is not up, bring it up.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <stdlib.h>
38
38
#include <time.h>
39
39
#include <net/if.h>             /* if_nametoindex */
 
40
#include <sys/ioctl.h>          // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
 
41
#include <net/if.h>             // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
40
42
 
41
43
#include <avahi-core/core.h>
42
44
#include <avahi-core/lookup.h>
68
70
 
69
71
#define BUFFER_SIZE 256
70
72
 
71
 
static int dh_bits = 1024;
72
 
 
73
73
static const char *keydir = "/conf/conf.d/mandos";
74
74
static const char *pubkeyfile = "pubkey.txt";
75
75
static const char *seckeyfile = "seckey.txt";
76
76
 
77
77
bool debug = false;
78
78
 
79
 
/* Used for  */
 
79
/* Used for passing in values through all the callback functions */
80
80
typedef struct {
81
 
  gnutls_session_t session;
 
81
  AvahiSimplePoll *simple_poll;
 
82
  AvahiServer *server;
82
83
  gnutls_certificate_credentials_t cred;
83
 
  gnutls_dh_params_t dh_params;
84
 
} encrypted_session;
85
 
 
 
84
  unsigned int dh_bits;
 
85
  const char *priority;
 
86
} mandos_context;
86
87
 
87
88
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
88
89
                                   char **new_packet,
253
254
  fprintf(stderr, "%s", string);
254
255
}
255
256
 
256
 
static int initgnutls(encrypted_session *es){
 
257
static int initgnutls(mandos_context *mc, gnutls_session_t *session,
 
258
                      gnutls_dh_params_t *dh_params){
257
259
  const char *err;
258
260
  int ret;
259
261
  
266
268
    fprintf (stderr, "global_init: %s\n", safer_gnutls_strerror(ret));
267
269
    return -1;
268
270
  }
269
 
 
 
271
  
270
272
  if (debug){
271
273
    gnutls_global_set_log_level(11);
272
274
    gnutls_global_set_log_function(debuggnutls);
273
275
  }
274
276
  
275
277
  /* openpgp credentials */
276
 
  if ((ret = gnutls_certificate_allocate_credentials (&es->cred))
 
278
  if ((ret = gnutls_certificate_allocate_credentials (&mc->cred))
277
279
      != GNUTLS_E_SUCCESS) {
278
280
    fprintf (stderr, "memory error: %s\n",
279
281
             safer_gnutls_strerror(ret));
287
289
  }
288
290
  
289
291
  ret = gnutls_certificate_set_openpgp_key_file
290
 
    (es->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
 
292
    (mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
291
293
  if (ret != GNUTLS_E_SUCCESS) {
292
294
    fprintf
293
295
      (stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
299
301
  }
300
302
  
301
303
  //GnuTLS server initialization
302
 
  if ((ret = gnutls_dh_params_init (&es->dh_params))
 
304
  if ((ret = gnutls_dh_params_init(dh_params))
303
305
      != GNUTLS_E_SUCCESS) {
304
306
    fprintf (stderr, "Error in dh parameter initialization: %s\n",
305
307
             safer_gnutls_strerror(ret));
306
308
    return -1;
307
309
  }
308
310
  
309
 
  if ((ret = gnutls_dh_params_generate2 (es->dh_params, dh_bits))
 
311
  if ((ret = gnutls_dh_params_generate2(*dh_params, mc->dh_bits))
310
312
      != GNUTLS_E_SUCCESS) {
311
313
    fprintf (stderr, "Error in prime generation: %s\n",
312
314
             safer_gnutls_strerror(ret));
313
315
    return -1;
314
316
  }
315
317
  
316
 
  gnutls_certificate_set_dh_params (es->cred, es->dh_params);
 
318
  gnutls_certificate_set_dh_params(mc->cred, *dh_params);
317
319
  
318
320
  // GnuTLS session creation
319
 
  if ((ret = gnutls_init (&es->session, GNUTLS_SERVER))
 
321
  if ((ret = gnutls_init(session, GNUTLS_SERVER))
320
322
      != GNUTLS_E_SUCCESS){
321
323
    fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
322
324
            safer_gnutls_strerror(ret));
323
325
  }
324
326
  
325
 
  if ((ret = gnutls_priority_set_direct (es->session, "NORMAL", &err))
 
327
  if ((ret = gnutls_priority_set_direct(*session, mc->priority, &err))
326
328
      != GNUTLS_E_SUCCESS) {
327
329
    fprintf(stderr, "Syntax error at: %s\n", err);
328
330
    fprintf(stderr, "GnuTLS error: %s\n",
330
332
    return -1;
331
333
  }
332
334
  
333
 
  if ((ret = gnutls_credentials_set
334
 
       (es->session, GNUTLS_CRD_CERTIFICATE, es->cred))
 
335
  if ((ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
 
336
                                    mc->cred))
335
337
      != GNUTLS_E_SUCCESS) {
336
338
    fprintf(stderr, "Error setting a credentials set: %s\n",
337
339
            safer_gnutls_strerror(ret));
339
341
  }
340
342
  
341
343
  /* ignore client certificate if any. */
342
 
  gnutls_certificate_server_set_request (es->session,
 
344
  gnutls_certificate_server_set_request (*session,
343
345
                                         GNUTLS_CERT_IGNORE);
344
346
  
345
 
  gnutls_dh_set_prime_bits (es->session, dh_bits);
 
347
  gnutls_dh_set_prime_bits (*session, mc->dh_bits);
346
348
  
347
349
  return 0;
348
350
}
351
353
                      __attribute__((unused)) const char *txt){}
352
354
 
353
355
static int start_mandos_communication(const char *ip, uint16_t port,
354
 
                                      AvahiIfIndex if_index){
 
356
                                      AvahiIfIndex if_index,
 
357
                                      mandos_context *mc){
355
358
  int ret, tcp_sd;
356
359
  struct sockaddr_in6 to;
357
 
  encrypted_session es;
358
360
  char *buffer = NULL;
359
361
  char *decrypted_buffer;
360
362
  size_t buffer_length = 0;
363
365
  size_t written = 0;
364
366
  int retval = 0;
365
367
  char interface[IF_NAMESIZE];
 
368
  gnutls_session_t session;
 
369
  gnutls_dh_params_t dh_params;
366
370
  
367
371
  if(debug){
368
372
    fprintf(stderr, "Setting up a tcp connection to %s, port %d\n",
374
378
    perror("socket");
375
379
    return -1;
376
380
  }
377
 
  
378
 
  if(if_indextoname((unsigned int)if_index, interface) == NULL){
379
 
    if(debug){
 
381
 
 
382
  if(debug){
 
383
    if(if_indextoname((unsigned int)if_index, interface) == NULL){
380
384
      perror("if_indextoname");
 
385
      return -1;
381
386
    }
382
 
    return -1;
383
 
  }
384
 
  
385
 
  if(debug){
386
387
    fprintf(stderr, "Binding to interface %s\n", interface);
387
388
  }
388
389
  
392
393
  if (ret < 0 ){
393
394
    perror("inet_pton");
394
395
    return -1;
395
 
  }  
 
396
  }
396
397
  if(ret == 0){
397
398
    fprintf(stderr, "Bad address: %s\n", ip);
398
399
    return -1;
409
410
      perror("inet_ntop");
410
411
    } else {
411
412
      if(strcmp(addrstr, ip) != 0){
412
 
        fprintf(stderr, "Canonical address form: %s\n",
413
 
                addrstr, ntohs(to.sin6_port));
 
413
        fprintf(stderr, "Canonical address form: %s\n", addrstr);
414
414
      }
415
415
    }
416
416
  }
421
421
    return -1;
422
422
  }
423
423
  
424
 
  ret = initgnutls (&es);
 
424
  ret = initgnutls (mc, &session, &dh_params);
425
425
  if (ret != 0){
426
426
    retval = -1;
427
427
    return -1;
428
428
  }
429
429
  
430
 
  gnutls_transport_set_ptr (es.session,
431
 
                            (gnutls_transport_ptr_t) tcp_sd);
 
430
  gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) tcp_sd);
432
431
  
433
432
  if(debug){
434
433
    fprintf(stderr, "Establishing TLS session with %s\n", ip);
435
434
  }
436
435
  
437
 
  ret = gnutls_handshake (es.session);
 
436
  ret = gnutls_handshake (session);
438
437
  
439
438
  if (ret != GNUTLS_E_SUCCESS){
440
439
    if(debug){
462
461
      buffer_capacity += BUFFER_SIZE;
463
462
    }
464
463
    
465
 
    ret = gnutls_record_recv
466
 
      (es.session, buffer+buffer_length, BUFFER_SIZE);
 
464
    ret = gnutls_record_recv(session, buffer+buffer_length,
 
465
                             BUFFER_SIZE);
467
466
    if (ret == 0){
468
467
      break;
469
468
    }
473
472
      case GNUTLS_E_AGAIN:
474
473
        break;
475
474
      case GNUTLS_E_REHANDSHAKE:
476
 
        ret = gnutls_handshake (es.session);
 
475
        ret = gnutls_handshake (session);
477
476
        if (ret < 0){
478
477
          fprintf(stderr, "\n*** Handshake failed ***\n");
479
478
          gnutls_perror (ret);
485
484
        fprintf(stderr, "Unknown error while reading data from"
486
485
                " encrypted session with mandos server\n");
487
486
        retval = -1;
488
 
        gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
 
487
        gnutls_bye (session, GNUTLS_SHUT_RDWR);
489
488
        goto exit;
490
489
      }
491
490
    } else {
526
525
  }
527
526
 
528
527
  free(buffer);
529
 
  gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
 
528
  gnutls_bye (session, GNUTLS_SHUT_RDWR);
530
529
 exit:
531
530
  close(tcp_sd);
532
 
  gnutls_deinit (es.session);
533
 
  gnutls_certificate_free_credentials (es.cred);
 
531
  gnutls_deinit (session);
 
532
  gnutls_certificate_free_credentials (mc->cred);
534
533
  gnutls_global_deinit ();
535
534
  return retval;
536
535
}
537
536
 
538
 
static AvahiSimplePoll *simple_poll = NULL;
539
 
static AvahiServer *server = NULL;
540
 
 
541
 
static void resolve_callback(
542
 
    AvahiSServiceResolver *r,
543
 
    AvahiIfIndex interface,
544
 
    AVAHI_GCC_UNUSED AvahiProtocol protocol,
545
 
    AvahiResolverEvent event,
546
 
    const char *name,
547
 
    const char *type,
548
 
    const char *domain,
549
 
    const char *host_name,
550
 
    const AvahiAddress *address,
551
 
    uint16_t port,
552
 
    AVAHI_GCC_UNUSED AvahiStringList *txt,
553
 
    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
554
 
    AVAHI_GCC_UNUSED void* userdata) {
555
 
    
 
537
static void resolve_callback( AvahiSServiceResolver *r,
 
538
                              AvahiIfIndex interface,
 
539
                              AVAHI_GCC_UNUSED AvahiProtocol protocol,
 
540
                              AvahiResolverEvent event,
 
541
                              const char *name,
 
542
                              const char *type,
 
543
                              const char *domain,
 
544
                              const char *host_name,
 
545
                              const AvahiAddress *address,
 
546
                              uint16_t port,
 
547
                              AVAHI_GCC_UNUSED AvahiStringList *txt,
 
548
                              AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
 
549
                              void* userdata) {
 
550
  mandos_context *mc = userdata;
556
551
  assert(r);                    /* Spurious warning */
557
552
  
558
553
  /* Called whenever a service has been resolved successfully or
563
558
  case AVAHI_RESOLVER_FAILURE:
564
559
    fprintf(stderr, "(Resolver) Failed to resolve service '%s' of"
565
560
            " type '%s' in domain '%s': %s\n", name, type, domain,
566
 
            avahi_strerror(avahi_server_errno(server)));
 
561
            avahi_strerror(avahi_server_errno(mc->server)));
567
562
    break;
568
563
    
569
564
  case AVAHI_RESOLVER_FOUND:
574
569
        fprintf(stderr, "Mandos server \"%s\" found on %s (%s) on"
575
570
                " port %d\n", name, host_name, ip, port);
576
571
      }
577
 
      int ret = start_mandos_communication(ip, port, interface);
 
572
      int ret = start_mandos_communication(ip, port, interface, mc);
578
573
      if (ret == 0){
579
574
        exit(EXIT_SUCCESS);
580
575
      }
583
578
  avahi_s_service_resolver_free(r);
584
579
}
585
580
 
586
 
static void browse_callback(
587
 
    AvahiSServiceBrowser *b,
588
 
    AvahiIfIndex interface,
589
 
    AvahiProtocol protocol,
590
 
    AvahiBrowserEvent event,
591
 
    const char *name,
592
 
    const char *type,
593
 
    const char *domain,
594
 
    AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
595
 
    void* userdata) {
596
 
    
597
 
    AvahiServer *s = userdata;
598
 
    assert(b);                  /* Spurious warning */
599
 
    
600
 
    /* Called whenever a new services becomes available on the LAN or
601
 
       is removed from the LAN */
602
 
    
603
 
    switch (event) {
604
 
    default:
605
 
    case AVAHI_BROWSER_FAILURE:
606
 
      
607
 
      fprintf(stderr, "(Browser) %s\n",
608
 
              avahi_strerror(avahi_server_errno(server)));
609
 
      avahi_simple_poll_quit(simple_poll);
610
 
      return;
611
 
      
612
 
    case AVAHI_BROWSER_NEW:
613
 
      /* We ignore the returned resolver object. In the callback
614
 
         function we free it. If the server is terminated before
615
 
         the callback function is called the server will free
616
 
         the resolver for us. */
617
 
      
618
 
      if (!(avahi_s_service_resolver_new(s, interface, protocol, name,
619
 
                                         type, domain,
620
 
                                         AVAHI_PROTO_INET6, 0,
621
 
                                         resolve_callback, s)))
622
 
        fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
623
 
                avahi_strerror(avahi_server_errno(s)));
624
 
      break;
625
 
      
626
 
    case AVAHI_BROWSER_REMOVE:
627
 
      break;
628
 
      
629
 
    case AVAHI_BROWSER_ALL_FOR_NOW:
630
 
    case AVAHI_BROWSER_CACHE_EXHAUSTED:
631
 
      break;
632
 
    }
 
581
static void browse_callback( AvahiSServiceBrowser *b,
 
582
                             AvahiIfIndex interface,
 
583
                             AvahiProtocol protocol,
 
584
                             AvahiBrowserEvent event,
 
585
                             const char *name,
 
586
                             const char *type,
 
587
                             const char *domain,
 
588
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
 
589
                             void* userdata) {
 
590
  mandos_context *mc = userdata;
 
591
  assert(b);                    /* Spurious warning */
 
592
  
 
593
  /* Called whenever a new services becomes available on the LAN or
 
594
     is removed from the LAN */
 
595
  
 
596
  switch (event) {
 
597
  default:
 
598
  case AVAHI_BROWSER_FAILURE:
 
599
    
 
600
    fprintf(stderr, "(Browser) %s\n",
 
601
            avahi_strerror(avahi_server_errno(mc->server)));
 
602
    avahi_simple_poll_quit(mc->simple_poll);
 
603
    return;
 
604
    
 
605
  case AVAHI_BROWSER_NEW:
 
606
    /* We ignore the returned resolver object. In the callback
 
607
       function we free it. If the server is terminated before
 
608
       the callback function is called the server will free
 
609
       the resolver for us. */
 
610
    
 
611
    if (!(avahi_s_service_resolver_new(mc->server, interface, protocol, name,
 
612
                                       type, domain,
 
613
                                       AVAHI_PROTO_INET6, 0,
 
614
                                       resolve_callback, mc)))
 
615
      fprintf(stderr, "Failed to resolve service '%s': %s\n", name,
 
616
              avahi_strerror(avahi_server_errno(mc->server)));
 
617
    break;
 
618
    
 
619
  case AVAHI_BROWSER_REMOVE:
 
620
    break;
 
621
    
 
622
  case AVAHI_BROWSER_ALL_FOR_NOW:
 
623
  case AVAHI_BROWSER_CACHE_EXHAUSTED:
 
624
    break;
 
625
  }
633
626
}
634
627
 
635
628
/* Combines file name and path and returns the malloced new
642
635
    return NULL;
643
636
  }
644
637
  if(f_len > 0){
645
 
    memcpy(tmp, first, f_len);
 
638
    memcpy(tmp, first, f_len);  /* Spurious warning */
646
639
  }
647
640
  tmp[f_len] = '/';
648
641
  if(s_len > 0){
649
 
    memcpy(tmp + f_len + 1, second, s_len);
 
642
    memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
650
643
  }
651
644
  tmp[f_len + 1 + s_len] = '\0';
652
645
  return tmp;
658
651
    AvahiSServiceBrowser *sb = NULL;
659
652
    int error;
660
653
    int ret;
661
 
    int debug_int = 0;
 
654
    int debug_int;
662
655
    int returncode = EXIT_SUCCESS;
663
 
    const char *interface = NULL;
 
656
    const char *interface = "eth0";
 
657
    struct ifreq network;
 
658
    int sd;
 
659
    char *connect_to = NULL;
664
660
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
665
 
    char *connect_to = NULL;
 
661
    mandos_context mc = { .simple_poll = NULL, .server = NULL,
 
662
                          .dh_bits = 1024, .priority = "SECURE256"};
666
663
    
667
664
    debug_int = debug ? 1 : 0;
668
665
    while (true){
669
 
      static struct option long_options[] = {
 
666
      struct option long_options[] = {
670
667
        {"debug", no_argument, &debug_int, 1},
671
 
        {"connect", required_argument, NULL, 'C'},
 
668
        {"connect", required_argument, NULL, 'c'},
672
669
        {"interface", required_argument, NULL, 'i'},
673
670
        {"keydir", required_argument, NULL, 'd'},
674
 
        {"seckey", required_argument, NULL, 'c'},
675
 
        {"pubkey", required_argument, NULL, 'k'},
 
671
        {"seckey", required_argument, NULL, 's'},
 
672
        {"pubkey", required_argument, NULL, 'p'},
676
673
        {"dh-bits", required_argument, NULL, 'D'},
 
674
        {"priority", required_argument, NULL, 'P'},
677
675
        {0, 0, 0, 0} };
678
676
      
679
677
      int option_index = 0;
690
688
      case 'i':
691
689
        interface = optarg;
692
690
        break;
693
 
      case 'C':
 
691
      case 'c':
694
692
        connect_to = optarg;
695
693
        break;
696
694
      case 'd':
697
695
        keydir = optarg;
698
696
        break;
699
 
      case 'c':
 
697
      case 'p':
700
698
        pubkeyfile = optarg;
701
699
        break;
702
 
      case 'k':
 
700
      case 's':
703
701
        seckeyfile = optarg;
704
702
        break;
705
703
      case 'D':
706
 
        dh_bits = atoi(optarg);
 
704
        errno = 0;
 
705
        mc.dh_bits = (unsigned int) strtol(optarg, NULL, 10);
 
706
        if (errno){
 
707
          perror("strtol");
 
708
          exit(EXIT_FAILURE);
 
709
        }
 
710
        break;
 
711
      case 'P':
 
712
        mc.priority = optarg;
707
713
        break;
708
714
      case '?':
709
 
        break
710
715
      default:
711
716
        exit(EXIT_FAILURE);
712
717
      }
716
721
    pubkeyfile = combinepath(keydir, pubkeyfile);
717
722
    if (pubkeyfile == NULL){
718
723
      perror("combinepath");
719
 
      goto exit;
720
 
    }
721
 
    
722
 
    if(interface != NULL){
723
 
      if_index = (AvahiIfIndex) if_nametoindex(interface);
724
 
      if(if_index == 0){
725
 
        fprintf(stderr, "No such interface: \"%s\"\n", interface);
726
 
        exit(EXIT_FAILURE);
727
 
      }
 
724
      returncode = EXIT_FAILURE;
 
725
      goto exit;
 
726
    }
 
727
    
 
728
    seckeyfile = combinepath(keydir, seckeyfile);
 
729
    if (seckeyfile == NULL){
 
730
      perror("combinepath");
 
731
      goto exit;
 
732
    }
 
733
    
 
734
    if_index = (AvahiIfIndex) if_nametoindex(interface);
 
735
    if(if_index == 0){
 
736
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
 
737
      exit(EXIT_FAILURE);
728
738
    }
729
739
    
730
740
    if(connect_to != NULL){
743
753
      }
744
754
      *address = '\0';
745
755
      address = connect_to;
746
 
      ret = start_mandos_communication(address, port, if_index);
 
756
      ret = start_mandos_communication(address, port, if_index, &mc);
747
757
      if(ret < 0){
748
758
        exit(EXIT_FAILURE);
749
759
      } else {
751
761
      }
752
762
    }
753
763
    
754
 
    seckeyfile = combinepath(keydir, seckeyfile);
755
 
    if (seckeyfile == NULL){
756
 
      perror("combinepath");
757
 
      goto exit;
758
 
    }
 
764
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
 
765
    if(sd < 0) {
 
766
      perror("socket");
 
767
      returncode = EXIT_FAILURE;
 
768
      goto exit;
 
769
    }
 
770
    strcpy(network.ifr_name, interface); /* Spurious warning */
 
771
    ret = ioctl(sd, SIOCGIFFLAGS, &network);
 
772
    if(ret == -1){
 
773
      
 
774
      perror("ioctl SIOCGIFFLAGS");
 
775
      returncode = EXIT_FAILURE;
 
776
      goto exit;
 
777
    }
 
778
    if((network.ifr_flags & IFF_UP) == 0){
 
779
      network.ifr_flags |= IFF_UP;
 
780
      ret = ioctl(sd, SIOCSIFFLAGS, &network);
 
781
      if(ret == -1){
 
782
        perror("ioctl SIOCSIFFLAGS");
 
783
        returncode = EXIT_FAILURE;
 
784
        goto exit;
 
785
      }
 
786
    }
 
787
    close(sd);
759
788
    
760
789
    if (not debug){
761
790
      avahi_set_log_function(empty_log);
765
794
    srand((unsigned int) time(NULL));
766
795
 
767
796
    /* Allocate main loop object */
768
 
    if (!(simple_poll = avahi_simple_poll_new())) {
 
797
    if (!(mc.simple_poll = avahi_simple_poll_new())) {
769
798
        fprintf(stderr, "Failed to create simple poll object.\n");
770
 
        
 
799
        returncode = EXIT_FAILURE;
771
800
        goto exit;
772
801
    }
773
802
 
779
808
    config.publish_domain = 0;
780
809
 
781
810
    /* Allocate a new server */
782
 
    server = avahi_server_new(avahi_simple_poll_get(simple_poll),
783
 
                              &config, NULL, NULL, &error);
784
 
 
 
811
    mc.server=avahi_server_new(avahi_simple_poll_get(mc.simple_poll),
 
812
                               &config, NULL, NULL, &error);
 
813
    
785
814
    /* Free the configuration data */
786
815
    avahi_server_config_free(&config);
787
 
 
 
816
    
788
817
    /* Check if creating the server object succeeded */
789
 
    if (!server) {
 
818
    if (!mc.server) {
790
819
        fprintf(stderr, "Failed to create server: %s\n",
791
820
                avahi_strerror(error));
792
821
        returncode = EXIT_FAILURE;
794
823
    }
795
824
    
796
825
    /* Create the service browser */
797
 
    sb = avahi_s_service_browser_new(server, if_index,
 
826
    sb = avahi_s_service_browser_new(mc.server, if_index,
798
827
                                     AVAHI_PROTO_INET6,
799
828
                                     "_mandos._tcp", NULL, 0,
800
 
                                     browse_callback, server);
 
829
                                     browse_callback, &mc);
801
830
    if (!sb) {
802
831
        fprintf(stderr, "Failed to create service browser: %s\n",
803
 
                avahi_strerror(avahi_server_errno(server)));
 
832
                avahi_strerror(avahi_server_errno(mc.server)));
804
833
        returncode = EXIT_FAILURE;
805
834
        goto exit;
806
835
    }
811
840
      fprintf(stderr, "Starting avahi loop search\n");
812
841
    }
813
842
    
814
 
    avahi_simple_poll_loop(simple_poll);
 
843
    avahi_simple_poll_loop(mc.simple_poll);
815
844
    
816
845
 exit:
817
846
 
823
852
    if (sb)
824
853
        avahi_s_service_browser_free(sb);
825
854
    
826
 
    if (server)
827
 
        avahi_server_free(server);
 
855
    if (mc.server)
 
856
        avahi_server_free(mc.server);
828
857
 
829
 
    if (simple_poll)
830
 
        avahi_simple_poll_free(simple_poll);
 
858
    if (mc.simple_poll)
 
859
        avahi_simple_poll_free(mc.simple_poll);
831
860
    free(pubkeyfile);
832
861
    free(seckeyfile);
833
862