/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

merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
8
8
 * includes the following functions: "resolve_callback",
9
9
 * "browse_callback", and parts of "main".
10
10
 * 
11
 
 * Everything else is Copyright © 2007-2008 Teddy Hogeborn and Björn
12
 
 * Påhlsson.
 
11
 * Everything else is
 
12
 * Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
13
13
 * 
14
14
 * This program is free software: you can redistribute it and/or
15
15
 * modify it under the terms of the GNU General Public License as
25
25
 * along with this program.  If not, see
26
26
 * <http://www.gnu.org/licenses/>.
27
27
 * 
28
 
 * Contact the authors at <https://www.fukt.bsnet.se/~belorn/> and
29
 
 * <https://www.fukt.bsnet.se/~teddy/>.
 
28
 * Contact the authors at <mandos@fukt.bsnet.se>.
30
29
 */
31
30
 
32
 
#define _FORTIFY_SOURCE 2
33
 
 
 
31
/* Needed by GPGME, specifically gpgme_data_seek() */
34
32
#define _LARGEFILE_SOURCE
35
33
#define _FILE_OFFSET_BITS 64
36
34
 
73
71
#define BUFFER_SIZE 256
74
72
#define DH_BITS 1024
75
73
 
76
 
const char *certdir = "/conf/conf.d/cryptkeyreq/";
77
 
const char *certfile = "openpgp-client.txt";
78
 
const char *certkey = "openpgp-client-key.txt";
 
74
static const char *certdir = "/conf/conf.d/mandos";
 
75
static const char *certfile = "openpgp-client.txt";
 
76
static const char *certkey = "openpgp-client-key.txt";
79
77
 
80
78
bool debug = false;
81
79
 
86
84
} encrypted_session;
87
85
 
88
86
 
89
 
ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
90
 
                            char **new_packet, const char *homedir){
 
87
static ssize_t pgp_packet_decrypt (char *packet, size_t packet_size,
 
88
                                   char **new_packet,
 
89
                                   const char *homedir){
91
90
  gpgme_data_t dh_crypto, dh_plain;
92
91
  gpgme_ctx_t ctx;
93
92
  gpgme_error_t rc;
249
248
  return ret;
250
249
}
251
250
 
252
 
void debuggnutls(__attribute__((unused)) int level,
253
 
                 const char* string){
 
251
static void debuggnutls(__attribute__((unused)) int level,
 
252
                        const char* string){
254
253
  fprintf(stderr, "%s", string);
255
254
}
256
255
 
257
 
int initgnutls(encrypted_session *es){
 
256
static int initgnutls(encrypted_session *es){
258
257
  const char *err;
259
258
  int ret;
260
259
  
348
347
  return 0;
349
348
}
350
349
 
351
 
void empty_log(__attribute__((unused)) AvahiLogLevel level,
352
 
               __attribute__((unused)) const char *txt){}
 
350
static void empty_log(__attribute__((unused)) AvahiLogLevel level,
 
351
                      __attribute__((unused)) const char *txt){}
353
352
 
354
 
int start_mandos_communication(const char *ip, uint16_t port,
355
 
                               unsigned int if_index){
 
353
static int start_mandos_communication(const char *ip, uint16_t port,
 
354
                                      AvahiIfIndex if_index){
356
355
  int ret, tcp_sd;
357
356
  struct sockaddr_in6 to;
358
357
  encrypted_session es;
366
365
  char interface[IF_NAMESIZE];
367
366
  
368
367
  if(debug){
369
 
    fprintf(stderr, "Setting up a tcp connection to %s\n", ip);
 
368
    fprintf(stderr, "Setting up a tcp connection to %s, port %d\n",
 
369
            ip, port);
370
370
  }
371
371
  
372
372
  tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
376
376
  }
377
377
 
378
378
  if(debug){
379
 
    if(if_indextoname(if_index, interface) == NULL){
 
379
    if(if_indextoname((unsigned int)if_index, interface) == NULL){
380
380
      if(debug){
381
381
        perror("if_indextoname");
382
382
      }
402
402
  to.sin6_scope_id = (uint32_t)if_index;
403
403
  
404
404
  if(debug){
405
 
    fprintf(stderr, "Connection to: %s\n", ip);
 
405
    fprintf(stderr, "Connection to: %s, port %d\n", ip, port);
 
406
/*     char addrstr[INET6_ADDRSTRLEN]; */
 
407
/*     if(inet_ntop(to.sin6_family, &(to.sin6_addr), addrstr, */
 
408
/*               sizeof(addrstr)) == NULL){ */
 
409
/*       perror("inet_ntop"); */
 
410
/*     } else { */
 
411
/*       fprintf(stderr, "Really connecting to: %s, port %d\n", */
 
412
/*            addrstr, ntohs(to.sin6_port)); */
 
413
/*     } */
406
414
  }
407
415
  
408
416
  ret = connect(tcp_sd, (struct sockaddr *) &to, sizeof(to));
489
497
                                               &decrypted_buffer,
490
498
                                               certdir);
491
499
    if (decrypted_buffer_size >= 0){
492
 
      while(written < (size_t)decrypted_buffer_size){
 
500
      while(written < (size_t) decrypted_buffer_size){
493
501
        ret = (int)fwrite (decrypted_buffer + written, 1,
494
502
                           (size_t)decrypted_buffer_size - written,
495
503
                           stdout);
564
572
        fprintf(stderr, "Mandos server \"%s\" found on %s (%s) on"
565
573
                " port %d\n", name, host_name, ip, port);
566
574
      }
567
 
      int ret = start_mandos_communication(ip, port,
568
 
                                           (unsigned int) interface);
 
575
      int ret = start_mandos_communication(ip, port, interface);
569
576
      if (ret == 0){
570
577
        exit(EXIT_SUCCESS);
571
578
      }
623
630
    }
624
631
}
625
632
 
626
 
/* combinds file name and path and returns the malloced new string. som sane checks could/should be added */
627
 
const char *combinepath(const char *first, const char *second){
628
 
  char *tmp;
629
 
  tmp = malloc(strlen(first) + strlen(second) + 2);
 
633
/* Combines file name and path and returns the malloced new
 
634
   string. some sane checks could/should be added */
 
635
static const char *combinepath(const char *first, const char *second){
 
636
  size_t f_len = strlen(first);
 
637
  size_t s_len = strlen(second);
 
638
  char *tmp = malloc(f_len + s_len + 2);
630
639
  if (tmp == NULL){
631
 
    perror("malloc");
632
640
    return NULL;
633
641
  }
634
 
  strcpy(tmp, first);
635
 
  if (first[0] != '\0' and first[strlen(first) - 1] != '/'){
636
 
    strcat(tmp, "/");
637
 
  }
638
 
  strcat(tmp, second);
 
642
  if(f_len > 0){
 
643
    memcpy(tmp, first, f_len);
 
644
  }
 
645
  tmp[f_len] = '/';
 
646
  if(s_len > 0){
 
647
    memcpy(tmp + f_len + 1, second, s_len);
 
648
  }
 
649
  tmp[f_len + 1 + s_len] = '\0';
639
650
  return tmp;
640
651
}
641
652
 
649
660
    const char *interface = "eth0";
650
661
    struct ifreq network;
651
662
    int sd;
 
663
    char *connect_to = NULL;
 
664
    AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
652
665
    
653
666
    while (true){
654
667
      static struct option long_options[] = {
655
668
        {"debug", no_argument, (int *)&debug, 1},
 
669
        {"connect", required_argument, 0, 'C'},
656
670
        {"interface", required_argument, 0, 'i'},
657
671
        {"certdir", required_argument, 0, 'd'},
658
672
        {"certkey", required_argument, 0, 'c'},
673
687
      case 'i':
674
688
        interface = optarg;
675
689
        break;
 
690
      case 'C':
 
691
        connect_to = optarg;
 
692
        break;
676
693
      case 'd':
677
694
        certdir = optarg;
678
695
        break;
686
703
        exit(EXIT_FAILURE);
687
704
      }
688
705
    }
689
 
 
 
706
    
690
707
    certfile = combinepath(certdir, certfile);
691
708
    if (certfile == NULL){
 
709
      perror("combinepath");
692
710
      returncode = EXIT_FAILURE;
693
711
      goto exit;
694
712
    }
695
 
    
 
713
 
696
714
    certkey = combinepath(certdir, certkey);
697
715
    if (certkey == NULL){
 
716
      perror("combinepath");
698
717
      returncode = EXIT_FAILURE;
699
718
      goto exit;
700
719
    }
701
 
 
 
720
    
 
721
    if_index = (AvahiIfIndex) if_nametoindex(interface);
 
722
    if(if_index == 0){
 
723
      fprintf(stderr, "No such interface: \"%s\"\n", interface);
 
724
      exit(EXIT_FAILURE);
 
725
    }
 
726
    
 
727
    if(connect_to != NULL){
 
728
      /* Connect directly, do not use Zeroconf */
 
729
      /* (Mainly meant for debugging) */
 
730
      char *address = strrchr(connect_to, ':');
 
731
      if(address == NULL){
 
732
        fprintf(stderr, "No colon in address\n");
 
733
        exit(EXIT_FAILURE);
 
734
      }
 
735
      errno = 0;
 
736
      uint16_t port = (uint16_t) strtol(address+1, NULL, 10);
 
737
      if(errno){
 
738
        perror("Bad port number");
 
739
        exit(EXIT_FAILURE);
 
740
      }
 
741
      *address = '\0';
 
742
      address = connect_to;
 
743
      ret = start_mandos_communication(address, port, if_index);
 
744
      if(ret < 0){
 
745
        exit(EXIT_FAILURE);
 
746
      } else {
 
747
        exit(EXIT_SUCCESS);
 
748
      }
 
749
    }
 
750
    
702
751
    sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
703
752
    if(sd < 0) {
704
753
      perror("socket");
761
810
    }
762
811
    
763
812
    /* Create the service browser */
764
 
    sb = avahi_s_service_browser_new(server,
765
 
                                     (AvahiIfIndex)
766
 
                                     if_nametoindex(interface),
 
813
    sb = avahi_s_service_browser_new(server, if_index,
767
814
                                     AVAHI_PROTO_INET6,
768
815
                                     "_mandos._tcp", NULL, 0,
769
816
                                     browse_callback, server);