/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

  • Committer: Teddy Hogeborn
  • Date: 2012-06-13 22:06:57 UTC
  • mto: (237.7.144 trunk)
  • mto: This revision was merged to the branch mainline in revision 302.
  • Revision ID: teddy@recompile.se-20120613220657-qvq7c7nrndl3t413
* plugins.d/mandos-client.c (get_flags): Don't clobber errno.
  (up_interface): Removed; replaced with "interface_is_up".
  (interface_is_up, interface_is_running,
   lower_privileges_permanently, take_down_interface): New.
  (bring_up_interface): Return "error_t".  Use new functions
                        "interface_is_up", "get_flags", and
                        "interface_is_running".
  (main): Save all interfaces either autodetected or specified with
          --interface in argz vector "interfaces".  Save interfaces to
          take down on exit in argz vector "interfaces_to_take_down".
          Save interface names for DEVICE variable to network hooks as
          argz_vector "interfaces_hooks".  Bug fix: Be privileged
          while stopping network hooks.
* plugins.d/mandos-client.xml (SYNOPSIS): Changed --interface synopsis.
  (DESCRIPTION): Updated to document use of all interfaces.
  (OPTIONS): Updated description of "--interface".
* network-hooks.d/bridge: Parse comma-separated DEVICE environment
                          variable.
* network-hooks.d/openvpn: - '' -
* network-hooks.d/wireless: - '' -

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
                                 */
62
62
#include <inttypes.h>           /* PRIu16, PRIdMAX, intmax_t,
63
63
                                   strtoimax() */
 
64
#include <assert.h>             /* assert() */
64
65
#include <errno.h>              /* perror(), errno,
65
66
                                   program_invocation_short_name */
66
67
#include <time.h>               /* nanosleep(), time(), sleep() */
144
145
/* Doubly linked list that need to be circularly linked when used */
145
146
typedef struct server{
146
147
  const char *ip;
147
 
  in_port_t port;
 
148
  uint16_t port;
148
149
  AvahiIfIndex if_index;
149
150
  int af;
150
151
  struct timespec last_seen;
210
211
}
211
212
 
212
213
/* Add server to set of servers to retry periodically */
213
 
bool add_server(const char *ip, in_port_t port, AvahiIfIndex if_index,
 
214
bool add_server(const char *ip, uint16_t port, AvahiIfIndex if_index,
214
215
                int af){
215
216
  int ret;
216
217
  server *new_server = malloc(sizeof(server));
470
471
}
471
472
 
472
473
static const char * safer_gnutls_strerror(int value){
473
 
  const char *ret = gnutls_strerror(value);
 
474
  const char *ret = gnutls_strerror(value); /* Spurious warning from
 
475
                                               -Wunreachable-code */
474
476
  if(ret == NULL)
475
477
    ret = "(unknown)";
476
478
  return ret;
621
623
                      __attribute__((unused)) const char *txt){}
622
624
 
623
625
/* Called when a Mandos server is found */
624
 
static int start_mandos_communication(const char *ip, in_port_t port,
 
626
static int start_mandos_communication(const char *ip, uint16_t port,
625
627
                                      AvahiIfIndex if_index,
626
628
                                      int af){
627
629
  int ret, tcp_sd = -1;
666
668
  
667
669
  if(debug){
668
670
    fprintf_plus(stderr, "Setting up a TCP connection to %s, port %"
669
 
                 PRIuMAX "\n", ip, (uintmax_t)port);
 
671
                 PRIu16 "\n", ip, port);
670
672
  }
671
673
  
672
674
  tcp_sd = socket(pf, SOCK_STREAM, 0);
703
705
    goto mandos_end;
704
706
  }
705
707
  if(af == AF_INET6){
706
 
    to.in6.sin6_port = htons(port);    
 
708
    to.in6.sin6_port = htons(port); /* Spurious warnings from
 
709
                                       -Wconversion and
 
710
                                       -Wunreachable-code */
 
711
    
707
712
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
708
713
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
709
714
                                -Wunreachable-code*/
733
738
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
734
739
        perror_plus("if_indextoname");
735
740
      } else {
736
 
        fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIuMAX
737
 
                     "\n", ip, interface, (uintmax_t)port);
 
741
        fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIu16
 
742
                     "\n", ip, interface, port);
738
743
      }
739
744
    } else {
740
 
      fprintf_plus(stderr, "Connection to: %s, port %" PRIuMAX "\n",
741
 
                   ip, (uintmax_t)port);
 
745
      fprintf_plus(stderr, "Connection to: %s, port %" PRIu16 "\n",
 
746
                   ip, port);
742
747
    }
743
748
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
744
749
                 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
1005
1010
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags
1006
1011
                             flags,
1007
1012
                             AVAHI_GCC_UNUSED void* userdata){
1008
 
  if(r == NULL){
1009
 
    return;
1010
 
  }
 
1013
  assert(r);
1011
1014
  
1012
1015
  /* Called whenever a service has been resolved successfully or
1013
1016
     timed out */
1034
1037
                     PRIdMAX ") on port %" PRIu16 "\n", name,
1035
1038
                     host_name, ip, (intmax_t)interface, port);
1036
1039
      }
1037
 
      int ret = start_mandos_communication(ip, (in_port_t)port,
1038
 
                                           interface,
 
1040
      int ret = start_mandos_communication(ip, port, interface,
1039
1041
                                           avahi_proto_to_af(proto));
1040
1042
      if(ret == 0){
1041
1043
        avahi_simple_poll_quit(mc.simple_poll);
1042
1044
      } else {
1043
 
        if(not add_server(ip, (in_port_t)port, interface,
 
1045
        if(not add_server(ip, port, interface,
1044
1046
                          avahi_proto_to_af(proto))){
1045
1047
          fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1046
1048
                       " list\n", name);
1061
1063
                            AVAHI_GCC_UNUSED AvahiLookupResultFlags
1062
1064
                            flags,
1063
1065
                            AVAHI_GCC_UNUSED void* userdata){
1064
 
  if(b == NULL){
1065
 
    return;
1066
 
  }
 
1066
  assert(b);
1067
1067
  
1068
1068
  /* Called whenever a new services becomes available on the LAN or
1069
1069
     is removed from the LAN */
1450
1450
  int numhooks = scandir(hookdir, &direntries, runnable_hook,
1451
1451
                         alphasort);
1452
1452
  if(numhooks == -1){
1453
 
    if(errno == ENOENT){
1454
 
      if(debug){
1455
 
        fprintf_plus(stderr, "Network hook directory \"%s\" not"
1456
 
                     " found\n", hookdir);
1457
 
      }
1458
 
    } else {
1459
 
      perror_plus("scandir");
1460
 
    }
 
1453
    perror_plus("scandir");
1461
1454
  } else {
1462
1455
    int devnull = open("/dev/null", O_RDONLY);
1463
1456
    for(int i = 0; i < numhooks; i++){
2021
2014
  
2022
2015
  /* Run network hooks */
2023
2016
  {
2024
 
    
2025
 
    if(interfaces != NULL){
2026
 
      interfaces_hooks = malloc(interfaces_size);
2027
 
      if(interfaces_hooks == NULL){
2028
 
        perror_plus("malloc");
2029
 
        goto end;
2030
 
      }
2031
 
      memcpy(interfaces_hooks, interfaces, interfaces_size);
2032
 
      interfaces_hooks_size = interfaces_size;
2033
 
      argz_stringify(interfaces_hooks, interfaces_hooks_size,
2034
 
                     (int)',');
 
2017
    ret_errno = argz_append(&interfaces_hooks, &interfaces_hooks_size,
 
2018
                            interfaces, interfaces_size);
 
2019
    if(ret_errno != 0){
 
2020
      errno = ret_errno;
 
2021
      perror_plus("argz_append");
 
2022
      goto end;
2035
2023
    }
2036
 
    if(not run_network_hooks("start", interfaces_hooks != NULL ?
2037
 
                             interfaces_hooks : "", delay)){
 
2024
    argz_stringify(interfaces_hooks, interfaces_hooks_size, (int)',');
 
2025
    if(not run_network_hooks("start", interfaces_hooks, delay)){
2038
2026
      goto end;
2039
2027
    }
2040
2028
  }
2237
2225
      goto end;
2238
2226
    }
2239
2227
    
2240
 
    in_port_t port;
 
2228
    uint16_t port;
2241
2229
    errno = 0;
2242
2230
    tmpmax = strtoimax(address+1, &tmp, 10);
2243
2231
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
2244
 
       or tmpmax != (in_port_t)tmpmax){
 
2232
       or tmpmax != (uint16_t)tmpmax){
2245
2233
      fprintf_plus(stderr, "Bad port number\n");
2246
2234
      exitcode = EX_USAGE;
2247
2235
      goto end;
2251
2239
      goto end;
2252
2240
    }
2253
2241
    
2254
 
    port = (in_port_t)tmpmax;
 
2242
    port = (uint16_t)tmpmax;
2255
2243
    *address = '\0';
2256
2244
    /* Colon in address indicates IPv6 */
2257
2245
    int af;
2395
2383
    raise_privileges();
2396
2384
    
2397
2385
    /* Run network hooks */
2398
 
    run_network_hooks("stop", interfaces_hooks != NULL ?
2399
 
                      interfaces_hooks : "", delay);
 
2386
    run_network_hooks("stop", interfaces_hooks, delay);
2400
2387
    
2401
2388
    /* Take down the network interfaces which were brought up */
2402
2389
    {