/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

* plugins.d/mandos-client.c: Use all interfaces.

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;
154
155
 
155
156
/* Used for passing in values through the Avahi callback functions */
156
157
typedef struct {
 
158
  AvahiSimplePoll *simple_poll;
157
159
  AvahiServer *server;
158
160
  gnutls_certificate_credentials_t cred;
159
161
  unsigned int dh_bits;
163
165
  server *current_server;
164
166
} mandos_context;
165
167
 
166
 
/* global so signal handler can reach it*/
167
 
AvahiSimplePoll *simple_poll;
168
 
mandos_context mc = { .server = NULL, .dh_bits = 1024,
169
 
                      .priority = "SECURE256:!CTYPE-X.509:"
170
 
                      "+CTYPE-OPENPGP", .current_server = NULL };
 
168
/* global context so signal handler can reach it*/
 
169
mandos_context mc = { .simple_poll = NULL, .server = NULL,
 
170
                      .dh_bits = 1024, .priority = "SECURE256"
 
171
                      ":!CTYPE-X.509:+CTYPE-OPENPGP",
 
172
                      .current_server = NULL };
171
173
 
172
174
sig_atomic_t quit_now = 0;
173
175
int signal_received = 0;
209
211
}
210
212
 
211
213
/* Add server to set of servers to retry periodically */
212
 
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,
213
215
                int af){
214
216
  int ret;
215
217
  server *new_server = malloc(sizeof(server));
253
255
  gpgme_error_t rc;
254
256
  gpgme_engine_info_t engine_info;
255
257
  
 
258
  
256
259
  /*
257
260
   * Helper function to insert pub and seckey to the engine keyring.
258
261
   */
468
471
}
469
472
 
470
473
static const char * safer_gnutls_strerror(int value){
471
 
  const char *ret = gnutls_strerror(value);
 
474
  const char *ret = gnutls_strerror(value); /* Spurious warning from
 
475
                                               -Wunreachable-code */
472
476
  if(ret == NULL)
473
477
    ret = "(unknown)";
474
478
  return ret;
619
623
                      __attribute__((unused)) const char *txt){}
620
624
 
621
625
/* Called when a Mandos server is found */
622
 
static int start_mandos_communication(const char *ip, in_port_t port,
 
626
static int start_mandos_communication(const char *ip, uint16_t port,
623
627
                                      AvahiIfIndex if_index,
624
628
                                      int af){
625
629
  int ret, tcp_sd = -1;
664
668
  
665
669
  if(debug){
666
670
    fprintf_plus(stderr, "Setting up a TCP connection to %s, port %"
667
 
                 PRIuMAX "\n", ip, (uintmax_t)port);
 
671
                 PRIu16 "\n", ip, port);
668
672
  }
669
673
  
670
674
  tcp_sd = socket(pf, SOCK_STREAM, 0);
701
705
    goto mandos_end;
702
706
  }
703
707
  if(af == AF_INET6){
704
 
    to.in6.sin6_port = htons(port);    
 
708
    to.in6.sin6_port = htons(port); /* Spurious warnings from
 
709
                                       -Wconversion and
 
710
                                       -Wunreachable-code */
 
711
    
705
712
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
706
713
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
707
714
                                -Wunreachable-code*/
731
738
      if(if_indextoname((unsigned int)if_index, interface) == NULL){
732
739
        perror_plus("if_indextoname");
733
740
      } else {
734
 
        fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIuMAX
735
 
                     "\n", ip, interface, (uintmax_t)port);
 
741
        fprintf_plus(stderr, "Connection to: %s%%%s, port %" PRIu16
 
742
                     "\n", ip, interface, port);
736
743
      }
737
744
    } else {
738
 
      fprintf_plus(stderr, "Connection to: %s, port %" PRIuMAX "\n",
739
 
                   ip, (uintmax_t)port);
 
745
      fprintf_plus(stderr, "Connection to: %s, port %" PRIu16 "\n",
 
746
                   ip, port);
740
747
    }
741
748
    char addrstr[(INET_ADDRSTRLEN > INET6_ADDRSTRLEN) ?
742
749
                 INET_ADDRSTRLEN : INET6_ADDRSTRLEN] = "";
1003
1010
                             AVAHI_GCC_UNUSED AvahiLookupResultFlags
1004
1011
                             flags,
1005
1012
                             AVAHI_GCC_UNUSED void* userdata){
1006
 
  if(r == NULL){
1007
 
    return;
1008
 
  }
 
1013
  assert(r);
1009
1014
  
1010
1015
  /* Called whenever a service has been resolved successfully or
1011
1016
     timed out */
1032
1037
                     PRIdMAX ") on port %" PRIu16 "\n", name,
1033
1038
                     host_name, ip, (intmax_t)interface, port);
1034
1039
      }
1035
 
      int ret = start_mandos_communication(ip, (in_port_t)port,
1036
 
                                           interface,
 
1040
      int ret = start_mandos_communication(ip, port, interface,
1037
1041
                                           avahi_proto_to_af(proto));
1038
1042
      if(ret == 0){
1039
 
        avahi_simple_poll_quit(simple_poll);
 
1043
        avahi_simple_poll_quit(mc.simple_poll);
1040
1044
      } else {
1041
 
        if(not add_server(ip, (in_port_t)port, interface,
 
1045
        if(not add_server(ip, port, interface,
1042
1046
                          avahi_proto_to_af(proto))){
1043
1047
          fprintf_plus(stderr, "Failed to add server \"%s\" to server"
1044
1048
                       " list\n", name);
1059
1063
                            AVAHI_GCC_UNUSED AvahiLookupResultFlags
1060
1064
                            flags,
1061
1065
                            AVAHI_GCC_UNUSED void* userdata){
1062
 
  if(b == NULL){
1063
 
    return;
1064
 
  }
 
1066
  assert(b);
1065
1067
  
1066
1068
  /* Called whenever a new services becomes available on the LAN or
1067
1069
     is removed from the LAN */
1076
1078
    
1077
1079
    fprintf_plus(stderr, "(Avahi browser) %s\n",
1078
1080
                 avahi_strerror(avahi_server_errno(mc.server)));
1079
 
    avahi_simple_poll_quit(simple_poll);
 
1081
    avahi_simple_poll_quit(mc.simple_poll);
1080
1082
    return;
1081
1083
    
1082
1084
  case AVAHI_BROWSER_NEW:
1115
1117
  signal_received = sig;
1116
1118
  int old_errno = errno;
1117
1119
  /* set main loop to exit */
1118
 
  if(simple_poll != NULL){
1119
 
    avahi_simple_poll_quit(simple_poll);
 
1120
  if(mc.simple_poll != NULL){
 
1121
    avahi_simple_poll_quit(mc.simple_poll);
1120
1122
  }
1121
1123
  errno = old_errno;
1122
1124
}
1364
1366
                                         mc.current_server->if_index,
1365
1367
                                         mc.current_server->af);
1366
1368
        if(ret == 0){
1367
 
          avahi_simple_poll_quit(simple_poll);
 
1369
          avahi_simple_poll_quit(mc.simple_poll);
1368
1370
          return 0;
1369
1371
        }
1370
1372
        ret = clock_gettime(CLOCK_MONOTONIC,
1448
1450
  int numhooks = scandir(hookdir, &direntries, runnable_hook,
1449
1451
                         alphasort);
1450
1452
  if(numhooks == -1){
1451
 
    if(errno == ENOENT){
1452
 
      if(debug){
1453
 
        fprintf_plus(stderr, "Network hook directory \"%s\" not"
1454
 
                     " found\n", hookdir);
1455
 
      }
1456
 
    } else {
1457
 
      perror_plus("scandir");
1458
 
    }
 
1453
    perror_plus("scandir");
1459
1454
  } else {
1460
1455
    int devnull = open("/dev/null", O_RDONLY);
1461
1456
    for(int i = 0; i < numhooks; i++){
2019
2014
  
2020
2015
  /* Run network hooks */
2021
2016
  {
2022
 
    
2023
 
    if(interfaces != NULL){
2024
 
      interfaces_hooks = malloc(interfaces_size);
2025
 
      if(interfaces_hooks == NULL){
2026
 
        perror_plus("malloc");
2027
 
        goto end;
2028
 
      }
2029
 
      memcpy(interfaces_hooks, interfaces, interfaces_size);
2030
 
      interfaces_hooks_size = interfaces_size;
2031
 
      argz_stringify(interfaces_hooks, interfaces_hooks_size,
2032
 
                     (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;
2033
2023
    }
2034
 
    if(not run_network_hooks("start", interfaces_hooks != NULL ?
2035
 
                             interfaces_hooks : "", delay)){
 
2024
    argz_stringify(interfaces_hooks, interfaces_hooks_size, (int)',');
 
2025
    if(not run_network_hooks("start", interfaces_hooks, delay)){
2036
2026
      goto end;
2037
2027
    }
2038
2028
  }
2045
2035
     from the signal handler */
2046
2036
  /* Initialize the pseudo-RNG for Avahi */
2047
2037
  srand((unsigned int) time(NULL));
2048
 
  simple_poll = avahi_simple_poll_new();
2049
 
  if(simple_poll == NULL){
 
2038
  mc.simple_poll = avahi_simple_poll_new();
 
2039
  if(mc.simple_poll == NULL){
2050
2040
    fprintf_plus(stderr,
2051
2041
                 "Avahi: Failed to create simple poll object.\n");
2052
2042
    exitcode = EX_UNAVAILABLE;
2235
2225
      goto end;
2236
2226
    }
2237
2227
    
2238
 
    in_port_t port;
 
2228
    uint16_t port;
2239
2229
    errno = 0;
2240
2230
    tmpmax = strtoimax(address+1, &tmp, 10);
2241
2231
    if(errno != 0 or tmp == address+1 or *tmp != '\0'
2242
 
       or tmpmax != (in_port_t)tmpmax){
 
2232
       or tmpmax != (uint16_t)tmpmax){
2243
2233
      fprintf_plus(stderr, "Bad port number\n");
2244
2234
      exitcode = EX_USAGE;
2245
2235
      goto end;
2249
2239
      goto end;
2250
2240
    }
2251
2241
    
2252
 
    port = (in_port_t)tmpmax;
 
2242
    port = (uint16_t)tmpmax;
2253
2243
    *address = '\0';
2254
2244
    /* Colon in address indicates IPv6 */
2255
2245
    int af;
2303
2293
    config.publish_domain = 0;
2304
2294
    
2305
2295
    /* Allocate a new server */
2306
 
    mc.server = avahi_server_new(avahi_simple_poll_get(simple_poll),
2307
 
                                 &config, NULL, NULL, &ret_errno);
 
2296
    mc.server = avahi_server_new(avahi_simple_poll_get
 
2297
                                 (mc.simple_poll), &config, NULL,
 
2298
                                 NULL, &ret_errno);
2308
2299
    
2309
2300
    /* Free the Avahi configuration data */
2310
2301
    avahi_server_config_free(&config);
2343
2334
    fprintf_plus(stderr, "Starting Avahi loop search\n");
2344
2335
  }
2345
2336
 
2346
 
  ret = avahi_loop_with_timeout(simple_poll,
 
2337
  ret = avahi_loop_with_timeout(mc.simple_poll,
2347
2338
                                (int)(retry_interval * 1000));
2348
2339
  if(debug){
2349
2340
    fprintf_plus(stderr, "avahi_loop_with_timeout exited %s\n",
2363
2354
  if(mc.server != NULL)
2364
2355
    avahi_server_free(mc.server);
2365
2356
  
2366
 
  if(simple_poll != NULL)
2367
 
    avahi_simple_poll_free(simple_poll);
 
2357
  if(mc.simple_poll != NULL)
 
2358
    avahi_simple_poll_free(mc.simple_poll);
2368
2359
  
2369
2360
  if(gnutls_initialized){
2370
2361
    gnutls_certificate_free_credentials(mc.cred);
2392
2383
    raise_privileges();
2393
2384
    
2394
2385
    /* Run network hooks */
2395
 
    run_network_hooks("stop", interfaces_hooks != NULL ?
2396
 
                      interfaces_hooks : "", delay);
 
2386
    run_network_hooks("stop", interfaces_hooks, delay);
2397
2387
    
2398
2388
    /* Take down the network interfaces which were brought up */
2399
2389
    {