64
58
#include <string.h> /* memset */
65
59
#include <arpa/inet.h> /* inet_pton() */
66
60
#include <iso646.h> /* not */
67
#include <net/if.h> /* IF_NAMESIZE */
68
#include <argp.h> /* struct argp_option,
69
struct argp_state, struct argp,
72
63
#include <errno.h> /* perror() */
75
69
#define BUFFER_SIZE 256
71
static int dh_bits = 1024;
73
static const char *keydir = "/conf/conf.d/mandos";
74
static const char *pubkeyfile = "pubkey.txt";
75
static const char *seckeyfile = "seckey.txt";
77
77
bool debug = false;
78
static const char *keydir = "/conf/conf.d/mandos";
79
static const char mandos_protocol_version[] = "1";
80
const char *argp_program_version = "mandosclient 0.9";
81
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
83
/* Used for passing in values through the Avahi callback functions */
85
AvahiSimplePoll *simple_poll;
81
gnutls_session_t session;
87
82
gnutls_certificate_credentials_t cred;
89
83
gnutls_dh_params_t dh_params;
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.
98
size_t adjustbuffer(char **buffer, size_t buffer_length,
99
size_t buffer_capacity){
100
if (buffer_length + BUFFER_SIZE > buffer_capacity){
101
*buffer = realloc(*buffer, buffer_capacity + BUFFER_SIZE);
105
buffer_capacity += BUFFER_SIZE;
107
return buffer_capacity;
111
* Decrypt OpenPGP data using keyrings in HOMEDIR.
112
* Returns -1 on error
114
static ssize_t pgp_packet_decrypt (const char *cryptotext,
87
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
117
89
const char *homedir){
118
90
gpgme_data_t dh_crypto, dh_plain;
122
size_t plaintext_capacity = 0;
123
ssize_t plaintext_length = 0;
94
ssize_t new_packet_capacity = 0;
95
ssize_t new_packet_length = 0;
124
96
gpgme_engine_info_t engine_info;
127
fprintf(stderr, "Trying to decrypt OpenPGP data\n");
99
fprintf(stderr, "Trying to decrypt OpenPGP packet\n");
197
/* Delete the GPGME FILE pointer cryptotext data buffer */
198
gpgme_data_release(dh_crypto);
229
200
/* Seek back to the beginning of the GPGME plaintext data buffer */
230
201
if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){
231
202
perror("pgpme_data_seek");
232
plaintext_length = -1;
238
plaintext_capacity = adjustbuffer(plaintext,
239
(size_t)plaintext_length,
241
if (plaintext_capacity == 0){
242
perror("adjustbuffer");
243
plaintext_length = -1;
207
if (new_packet_length + BUFFER_SIZE > new_packet_capacity){
208
*new_packet = realloc(*new_packet,
209
(unsigned int)new_packet_capacity
211
if (*new_packet == NULL){
215
new_packet_capacity += BUFFER_SIZE;
247
ret = gpgme_data_read(dh_plain, *plaintext + plaintext_length,
218
ret = gpgme_data_read(dh_plain, *new_packet + new_packet_length,
249
220
/* Print the data, if any */
255
225
perror("gpgme_data_read");
256
plaintext_length = -1;
259
plaintext_length += ret;
228
new_packet_length += ret;
263
fprintf(stderr, "Decrypted password is: ");
264
for(ssize_t i = 0; i < plaintext_length; i++){
265
fprintf(stderr, "%02hhX ", (*plaintext)[i]);
267
fprintf(stderr, "\n");
272
/* Delete the GPGME cryptotext data buffer */
273
gpgme_data_release(dh_crypto);
231
/* FIXME: check characters before printing to screen so to not print
232
terminal control characters */
234
/* fprintf(stderr, "decrypted password is: "); */
235
/* fwrite(*new_packet, 1, new_packet_length, stderr); */
236
/* fprintf(stderr, "\n"); */
275
239
/* Delete the GPGME plaintext data buffer */
276
240
gpgme_data_release(dh_plain);
277
return plaintext_length;
241
return new_packet_length;
280
244
static const char * safer_gnutls_strerror (int value) {
332
289
ret = gnutls_certificate_set_openpgp_key_file
333
(mc->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
290
(es->cred, pubkeyfile, seckeyfile, GNUTLS_OPENPGP_FMT_BASE64);
334
291
if (ret != GNUTLS_E_SUCCESS) {
336
"Error[%d] while reading the OpenPGP key pair ('%s',"
337
" '%s')\n", ret, pubkeyfile, seckeyfile);
338
fprintf(stdout, "The GnuTLS error is: %s\n",
293
(stderr, "Error[%d] while reading the OpenPGP key pair ('%s',"
295
ret, pubkeyfile, seckeyfile);
296
fprintf(stdout, "The Error is: %s\n",
339
297
safer_gnutls_strerror(ret));
343
/* GnuTLS server initialization */
344
ret = gnutls_dh_params_init(&mc->dh_params);
345
if (ret != GNUTLS_E_SUCCESS) {
346
fprintf (stderr, "Error in GnuTLS DH parameter initialization:"
347
" %s\n", safer_gnutls_strerror(ret));
350
ret = gnutls_dh_params_generate2(mc->dh_params, mc->dh_bits);
351
if (ret != GNUTLS_E_SUCCESS) {
352
fprintf (stderr, "Error in GnuTLS prime generation: %s\n",
353
safer_gnutls_strerror(ret));
357
gnutls_certificate_set_dh_params(mc->cred, mc->dh_params);
363
gnutls_certificate_free_credentials (mc->cred);
364
gnutls_global_deinit ();
369
static int init_gnutls_session(mandos_context *mc,
370
gnutls_session_t *session){
372
/* GnuTLS session creation */
373
ret = gnutls_init(session, GNUTLS_SERVER);
374
if (ret != GNUTLS_E_SUCCESS){
301
//GnuTLS server initialization
302
if ((ret = gnutls_dh_params_init (&es->dh_params))
303
!= GNUTLS_E_SUCCESS) {
304
fprintf (stderr, "Error in dh parameter initialization: %s\n",
305
safer_gnutls_strerror(ret));
309
if ((ret = gnutls_dh_params_generate2 (es->dh_params, dh_bits))
310
!= GNUTLS_E_SUCCESS) {
311
fprintf (stderr, "Error in prime generation: %s\n",
312
safer_gnutls_strerror(ret));
316
gnutls_certificate_set_dh_params (es->cred, es->dh_params);
318
// GnuTLS session creation
319
if ((ret = gnutls_init (&es->session, GNUTLS_SERVER))
320
!= GNUTLS_E_SUCCESS){
375
321
fprintf(stderr, "Error in GnuTLS session initialization: %s\n",
376
322
safer_gnutls_strerror(ret));
381
ret = gnutls_priority_set_direct(*session, mc->priority, &err);
382
if (ret != GNUTLS_E_SUCCESS) {
383
fprintf(stderr, "Syntax error at: %s\n", err);
384
fprintf(stderr, "GnuTLS error: %s\n",
385
safer_gnutls_strerror(ret));
386
gnutls_deinit (*session);
325
if ((ret = gnutls_priority_set_direct (es->session, "NORMAL", &err))
326
!= GNUTLS_E_SUCCESS) {
327
fprintf(stderr, "Syntax error at: %s\n", err);
328
fprintf(stderr, "GnuTLS error: %s\n",
329
safer_gnutls_strerror(ret));
391
ret = gnutls_credentials_set(*session, GNUTLS_CRD_CERTIFICATE,
393
if (ret != GNUTLS_E_SUCCESS) {
394
fprintf(stderr, "Error setting GnuTLS credentials: %s\n",
333
if ((ret = gnutls_credentials_set
334
(es->session, GNUTLS_CRD_CERTIFICATE, es->cred))
335
!= GNUTLS_E_SUCCESS) {
336
fprintf(stderr, "Error setting a credentials set: %s\n",
395
337
safer_gnutls_strerror(ret));
396
gnutls_deinit (*session);
400
341
/* ignore client certificate if any. */
401
gnutls_certificate_server_set_request (*session,
342
gnutls_certificate_server_set_request (es->session,
402
343
GNUTLS_CERT_IGNORE);
404
gnutls_dh_set_prime_bits (*session, mc->dh_bits);
345
gnutls_dh_set_prime_bits (es->session, dh_bits);
409
/* Avahi log function callback */
410
350
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
411
351
__attribute__((unused)) const char *txt){}
413
/* Called when a Mandos server is found */
414
353
static int start_mandos_communication(const char *ip, uint16_t port,
415
AvahiIfIndex if_index,
354
AvahiIfIndex if_index){
418
union { struct sockaddr in; struct sockaddr_in6 in6; } to;
356
struct sockaddr_in6 to;
357
encrypted_session es;
419
358
char *buffer = NULL;
420
359
char *decrypted_buffer;
421
360
size_t buffer_length = 0;
422
361
size_t buffer_capacity = 0;
423
362
ssize_t decrypted_buffer_size;
426
365
char interface[IF_NAMESIZE];
427
gnutls_session_t session;
429
ret = init_gnutls_session (mc, &session);
435
368
fprintf(stderr, "Setting up a tcp connection to %s, port %d\n",
441
374
perror("socket");
446
if(if_indextoname((unsigned int)if_index, interface) == NULL){
378
if(if_indextoname((unsigned int)if_index, interface) == NULL){
447
380
perror("if_indextoname");
450
386
fprintf(stderr, "Binding to interface %s\n", interface);
453
389
memset(&to,0,sizeof(to)); /* Spurious warning */
454
to.in6.sin6_family = AF_INET6;
455
/* It would be nice to have a way to detect if we were passed an
456
IPv4 address here. Now we assume an IPv6 address. */
457
ret = inet_pton(AF_INET6, ip, &to.in6.sin6_addr);
390
to.sin6_family = AF_INET6;
391
ret = inet_pton(AF_INET6, ip, &to.sin6_addr);
459
393
perror("inet_pton");
463
397
fprintf(stderr, "Bad address: %s\n", ip);
466
to.in6.sin6_port = htons(port); /* Spurious warning */
400
to.sin6_port = htons(port); /* Spurious warning */
468
to.in6.sin6_scope_id = (uint32_t)if_index;
402
to.sin6_scope_id = (uint32_t)if_index;
471
405
fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
472
406
char addrstr[INET6_ADDRSTRLEN] = "";
473
if(inet_ntop(to.in6.sin6_family, &(to.in6.sin6_addr), addrstr,
407
if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr,
474
408
sizeof(addrstr)) == NULL){
475
409
perror("inet_ntop");
477
411
if(strcmp(addrstr, ip) != 0){
478
fprintf(stderr, "Canonical address form: %s\n", addrstr);
412
fprintf(stderr, "Canonical address form: %s\n",
413
addrstr, ntohs(to.sin6_port));
483
ret = connect(tcp_sd, &to.in, sizeof(to));
418
ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
485
420
perror("connect");
489
const char *out = mandos_protocol_version;
492
size_t out_size = strlen(out);
493
ret = TEMP_FAILURE_RETRY(write(tcp_sd, out + written,
494
out_size - written));
500
written += (size_t)ret;
501
if(written < out_size){
504
if (out == mandos_protocol_version){
424
ret = initgnutls (&es);
430
gnutls_transport_set_ptr (es.session,
431
(gnutls_transport_ptr_t) tcp_sd);
514
434
fprintf(stderr, "Establishing TLS session with %s\n", ip);
517
gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) tcp_sd);
519
ret = gnutls_handshake (session);
437
ret = gnutls_handshake (es.session);
521
439
if (ret != GNUTLS_E_SUCCESS){
523
fprintf(stderr, "*** GnuTLS Handshake failed ***\n");
441
fprintf(stderr, "\n*** Handshake failed ***\n");
524
442
gnutls_perror (ret);
530
/* Read OpenPGP packet that contains the wanted password */
448
//Retrieve OpenPGP packet that contains the wanted password
533
451
fprintf(stderr, "Retrieving pgp encrypted password from %s\n",
554
473
case GNUTLS_E_AGAIN:
556
475
case GNUTLS_E_REHANDSHAKE:
557
ret = gnutls_handshake (session);
476
ret = gnutls_handshake (es.session);
559
fprintf(stderr, "*** GnuTLS Re-handshake failed ***\n");
478
fprintf(stderr, "\n*** Handshake failed ***\n");
560
479
gnutls_perror (ret);
566
485
fprintf(stderr, "Unknown error while reading data from"
567
" encrypted session with Mandos server\n");
486
" encrypted session with mandos server\n");
569
gnutls_bye (session, GNUTLS_SHUT_RDWR);
488
gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
573
492
buffer_length += (size_t) ret;
578
fprintf(stderr, "Closing TLS session\n");
581
gnutls_bye (session, GNUTLS_SHUT_RDWR);
583
496
if (buffer_length > 0){
584
497
decrypted_buffer_size = pgp_packet_decrypt(buffer,
586
499
&decrypted_buffer,
588
501
if (decrypted_buffer_size >= 0){
590
502
while(written < (size_t) decrypted_buffer_size){
591
503
ret = (int)fwrite (decrypted_buffer + written, 1,
592
504
(size_t)decrypted_buffer_size - written,
610
/* Shutdown procedure */
525
fprintf(stderr, "Closing TLS session\n");
529
gnutls_bye (es.session, GNUTLS_SHUT_RDWR);
615
gnutls_deinit (session);
532
gnutls_deinit (es.session);
533
gnutls_certificate_free_credentials (es.cred);
534
gnutls_global_deinit ();
619
static void resolve_callback(AvahiSServiceResolver *r,
620
AvahiIfIndex interface,
621
AVAHI_GCC_UNUSED AvahiProtocol protocol,
622
AvahiResolverEvent event,
626
const char *host_name,
627
const AvahiAddress *address,
629
AVAHI_GCC_UNUSED AvahiStringList *txt,
630
AVAHI_GCC_UNUSED AvahiLookupResultFlags
633
mandos_context *mc = userdata;
538
static AvahiSimplePoll *simple_poll = NULL;
539
static AvahiServer *server = NULL;
541
static void resolve_callback(
542
AvahiSServiceResolver *r,
543
AvahiIfIndex interface,
544
AVAHI_GCC_UNUSED AvahiProtocol protocol,
545
AvahiResolverEvent event,
549
const char *host_name,
550
const AvahiAddress *address,
552
AVAHI_GCC_UNUSED AvahiStringList *txt,
553
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
554
AVAHI_GCC_UNUSED void* userdata) {
634
556
assert(r); /* Spurious warning */
636
558
/* Called whenever a service has been resolved successfully or
661
583
avahi_s_service_resolver_free(r);
664
static void browse_callback( AvahiSServiceBrowser *b,
665
AvahiIfIndex interface,
666
AvahiProtocol protocol,
667
AvahiBrowserEvent event,
671
AVAHI_GCC_UNUSED AvahiLookupResultFlags
674
mandos_context *mc = userdata;
675
assert(b); /* Spurious warning */
677
/* Called whenever a new services becomes available on the LAN or
678
is removed from the LAN */
682
case AVAHI_BROWSER_FAILURE:
684
fprintf(stderr, "(Avahi browser) %s\n",
685
avahi_strerror(avahi_server_errno(mc->server)));
686
avahi_simple_poll_quit(mc->simple_poll);
689
case AVAHI_BROWSER_NEW:
690
/* We ignore the returned Avahi resolver object. In the callback
691
function we free it. If the Avahi server is terminated before
692
the callback function is called the Avahi server will free the
695
if (!(avahi_s_service_resolver_new(mc->server, interface,
696
protocol, name, type, domain,
697
AVAHI_PROTO_INET6, 0,
698
resolve_callback, mc)))
699
fprintf(stderr, "Avahi: Failed to resolve service '%s': %s\n",
700
name, avahi_strerror(avahi_server_errno(mc->server)));
703
case AVAHI_BROWSER_REMOVE:
706
case AVAHI_BROWSER_ALL_FOR_NOW:
707
case AVAHI_BROWSER_CACHE_EXHAUSTED:
709
fprintf(stderr, "No Mandos server found, still searching...\n");
586
static void browse_callback(
587
AvahiSServiceBrowser *b,
588
AvahiIfIndex interface,
589
AvahiProtocol protocol,
590
AvahiBrowserEvent event,
594
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
597
AvahiServer *s = userdata;
598
assert(b); /* Spurious warning */
600
/* Called whenever a new services becomes available on the LAN or
601
is removed from the LAN */
605
case AVAHI_BROWSER_FAILURE:
607
fprintf(stderr, "(Browser) %s\n",
608
avahi_strerror(avahi_server_errno(server)));
609
avahi_simple_poll_quit(simple_poll);
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. */
618
if (!(avahi_s_service_resolver_new(s, interface, protocol, name,
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)));
626
case AVAHI_BROWSER_REMOVE:
629
case AVAHI_BROWSER_ALL_FOR_NOW:
630
case AVAHI_BROWSER_CACHE_EXHAUSTED:
715
635
/* Combines file name and path and returns the malloced new
725
memcpy(tmp, first, f_len); /* Spurious warning */
645
memcpy(tmp, first, f_len);
727
647
tmp[f_len] = '/';
729
memcpy(tmp + f_len + 1, second, s_len); /* Spurious warning */
649
memcpy(tmp + f_len + 1, second, s_len);
731
651
tmp[f_len + 1 + s_len] = '\0';
736
int main(int argc, char *argv[]){
656
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char*argv[]) {
657
AvahiServerConfig config;
737
658
AvahiSServiceBrowser *sb = NULL;
740
int exitcode = EXIT_SUCCESS;
741
const char *interface = "eth0";
742
struct ifreq network;
662
int returncode = EXIT_SUCCESS;
663
const char *interface = NULL;
664
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
746
665
char *connect_to = NULL;
747
AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
748
const char *pubkeyfile = "pubkey.txt";
749
const char *seckeyfile = "seckey.txt";
750
mandos_context mc = { .simple_poll = NULL, .server = NULL,
751
.dh_bits = 1024, .priority = "SECURE256"};
752
bool gnutls_initalized = false;
755
struct argp_option options[] = {
756
{ .name = "debug", .key = 128,
757
.doc = "Debug mode", .group = 3 },
758
{ .name = "connect", .key = 'c',
760
.doc = "Connect directly to a sepcified mandos server",
762
{ .name = "interface", .key = 'i',
764
.doc = "Interface that Avahi will conntect through",
766
{ .name = "keydir", .key = 'd',
768
.doc = "Directory where the openpgp keyring is",
770
{ .name = "seckey", .key = 's',
772
.doc = "Secret openpgp key for gnutls authentication",
774
{ .name = "pubkey", .key = 'p',
776
.doc = "Public openpgp key for gnutls authentication",
778
{ .name = "dh-bits", .key = 129,
780
.doc = "dh-bits to use in gnutls communication",
782
{ .name = "priority", .key = 130,
784
.doc = "GNUTLS priority", .group = 1 },
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. */
814
mc.dh_bits = (unsigned int) strtol(arg, NULL, 10);
829
return ARGP_ERR_UNKNOWN;
834
struct argp argp = { .options = options, .parser = parse_opt,
836
.doc = "Mandos client -- Get and decrypt"
837
" passwords from mandos server" };
838
argp_parse (&argp, argc, argv, 0, 0, NULL);
667
debug_int = debug ? 1 : 0;
669
static struct option long_options[] = {
670
{"debug", no_argument, &debug_int, 1},
671
{"connect", required_argument, NULL, 'C'},
672
{"interface", required_argument, NULL, 'i'},
673
{"keydir", required_argument, NULL, 'd'},
674
{"seckey", required_argument, NULL, 'c'},
675
{"pubkey", required_argument, NULL, 'k'},
676
{"dh-bits", required_argument, NULL, 'D'},
679
int option_index = 0;
680
ret = getopt_long (argc, argv, "i:", long_options,
706
dh_bits = atoi(optarg);
714
debug = debug_int ? true : false;
841
716
pubkeyfile = combinepath(keydir, pubkeyfile);
842
717
if (pubkeyfile == NULL){
843
718
perror("combinepath");
844
exitcode = EXIT_FAILURE;
848
seckeyfile = combinepath(keydir, seckeyfile);
849
if (seckeyfile == NULL){
850
perror("combinepath");
854
ret = init_gnutls_global(&mc, pubkeyfile, seckeyfile);
856
fprintf(stderr, "init_gnutls_global\n");
859
gnutls_initalized = true;
875
if_index = (AvahiIfIndex) if_nametoindex(interface);
877
fprintf(stderr, "No such interface: \"%s\"\n", interface);
722
if(interface != NULL){
723
if_index = (AvahiIfIndex) if_nametoindex(interface);
725
fprintf(stderr, "No such interface: \"%s\"\n", interface);
881
730
if(connect_to != NULL){
884
733
char *address = strrchr(connect_to, ':');
885
734
if(address == NULL){
886
735
fprintf(stderr, "No colon in address\n");
887
exitcode = EXIT_FAILURE;
891
739
uint16_t port = (uint16_t) strtol(address+1, NULL, 10);
893
741
perror("Bad port number");
894
exitcode = EXIT_FAILURE;
898
745
address = connect_to;
899
ret = start_mandos_communication(address, port, if_index, &mc);
746
ret = start_mandos_communication(address, port, if_index);
901
exitcode = EXIT_FAILURE;
903
exitcode = EXIT_SUCCESS;
908
/* If the interface is down, bring it up */
910
sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
913
exitcode = EXIT_FAILURE;
916
strcpy(network.ifr_name, interface); /* Spurious warning */
917
ret = ioctl(sd, SIOCGIFFLAGS, &network);
919
perror("ioctl SIOCGIFFLAGS");
920
exitcode = EXIT_FAILURE;
923
if((network.ifr_flags & IFF_UP) == 0){
924
network.ifr_flags |= IFF_UP;
925
ret = ioctl(sd, SIOCSIFFLAGS, &network);
927
perror("ioctl SIOCSIFFLAGS");
928
exitcode = EXIT_FAILURE;
754
seckeyfile = combinepath(keydir, seckeyfile);
755
if (seckeyfile == NULL){
756
perror("combinepath");
936
761
avahi_set_log_function(empty_log);
939
/* Initialize the pseudo-RNG for Avahi */
764
/* Initialize the psuedo-RNG */
940
765
srand((unsigned int) time(NULL));
942
/* Allocate main Avahi loop object */
943
mc.simple_poll = avahi_simple_poll_new();
944
if (mc.simple_poll == NULL) {
945
fprintf(stderr, "Avahi: Failed to create simple poll"
947
exitcode = EXIT_FAILURE;
952
AvahiServerConfig config;
953
/* Do not publish any local Zeroconf records */
954
avahi_server_config_init(&config);
955
config.publish_hinfo = 0;
956
config.publish_addresses = 0;
957
config.publish_workstation = 0;
958
config.publish_domain = 0;
960
/* Allocate a new server */
961
mc.server = avahi_server_new(avahi_simple_poll_get
962
(mc.simple_poll), &config, NULL,
965
/* Free the Avahi configuration data */
966
avahi_server_config_free(&config);
969
/* Check if creating the Avahi server object succeeded */
970
if (mc.server == NULL) {
971
fprintf(stderr, "Failed to create Avahi server: %s\n",
767
/* Allocate main loop object */
768
if (!(simple_poll = avahi_simple_poll_new())) {
769
fprintf(stderr, "Failed to create simple poll object.\n");
774
/* Do not publish any local records */
775
avahi_server_config_init(&config);
776
config.publish_hinfo = 0;
777
config.publish_addresses = 0;
778
config.publish_workstation = 0;
779
config.publish_domain = 0;
781
/* Allocate a new server */
782
server = avahi_server_new(avahi_simple_poll_get(simple_poll),
783
&config, NULL, NULL, &error);
785
/* Free the configuration data */
786
avahi_server_config_free(&config);
788
/* Check if creating the server object succeeded */
790
fprintf(stderr, "Failed to create server: %s\n",
972
791
avahi_strerror(error));
973
exitcode = EXIT_FAILURE;
792
returncode = EXIT_FAILURE;
977
/* Create the Avahi service browser */
978
sb = avahi_s_service_browser_new(mc.server, if_index,
796
/* Create the service browser */
797
sb = avahi_s_service_browser_new(server, if_index,
979
798
AVAHI_PROTO_INET6,
980
799
"_mandos._tcp", NULL, 0,
981
browse_callback, &mc);
800
browse_callback, server);
983
802
fprintf(stderr, "Failed to create service browser: %s\n",
984
avahi_strerror(avahi_server_errno(mc.server)));
985
exitcode = EXIT_FAILURE;
803
avahi_strerror(avahi_server_errno(server)));
804
returncode = EXIT_FAILURE;
989
808
/* Run the main loop */
992
fprintf(stderr, "Starting Avahi loop search\n");
811
fprintf(stderr, "Starting avahi loop search\n");
995
avahi_simple_poll_loop(mc.simple_poll);
814
avahi_simple_poll_loop(simple_poll);
1000
819
fprintf(stderr, "%s exiting\n", argv[0]);
1003
822
/* Cleanup things */
1005
824
avahi_s_service_browser_free(sb);
1007
if (mc.server != NULL)
1008
avahi_server_free(mc.server);
827
avahi_server_free(server);
1010
if (mc.simple_poll != NULL)
1011
avahi_simple_poll_free(mc.simple_poll);
830
avahi_simple_poll_free(simple_poll);
1012
831
free(pubkeyfile);
1013
832
free(seckeyfile);
1015
if (gnutls_initalized){
1016
gnutls_certificate_free_credentials (mc.cred);
1017
gnutls_global_deinit ();