/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: 2014-03-05 21:47:03 UTC
  • mto: (237.7.272 trunk)
  • mto: This revision was merged to the branch mainline in revision 311.
  • Revision ID: teddy@recompile.se-20140305214703-c5ulnh1c9i51yzl9
* Makefile (WARN): Re-add "-Wunreachable-code".
  (.PHONY): Update; add "mostlyclean", "maintainer-clean",
            "install-html", and "install-client-nokey".

Show diffs side-by-side

added added

removed removed

Lines of Context:
9
9
 * "browse_callback", and parts of "main".
10
10
 * 
11
11
 * Everything else is
12
 
 * Copyright © 2008-2012 Teddy Hogeborn
13
 
 * Copyright © 2008-2012 Björn Påhlsson
 
12
 * Copyright © 2008-2013 Teddy Hogeborn
 
13
 * Copyright © 2008-2013 Björn Påhlsson
14
14
 * 
15
15
 * This program is free software: you can redistribute it and/or
16
16
 * modify it under the terms of the GNU General Public License as
161
161
  const char *priority;
162
162
  gpgme_ctx_t ctx;
163
163
  server *current_server;
 
164
  char *interfaces;
 
165
  size_t interfaces_size;
164
166
} mandos_context;
165
167
 
166
168
/* global so signal handler can reach it*/
185
187
  
186
188
  TEMP_FAILURE_RETRY(fprintf(stream, "Mandos plugin %s: ",
187
189
                             program_invocation_short_name));
188
 
  return TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
 
190
  return (int)TEMP_FAILURE_RETRY(vfprintf(stream, format, ap));
189
191
}
190
192
 
191
193
/*
657
659
    return -1;
658
660
  }
659
661
  
 
662
  /* If the interface is specified and we have a list of interfaces */
 
663
  if(if_index != AVAHI_IF_UNSPEC and mc->interfaces != NULL){
 
664
    /* Check if the interface is one of the interfaces we are using */
 
665
    bool match = false;
 
666
    {
 
667
      char *interface = NULL;
 
668
      while((interface=argz_next(mc->interfaces, mc->interfaces_size,
 
669
                                 interface))){
 
670
        if(if_nametoindex(interface) == (unsigned int)if_index){
 
671
          match = true;
 
672
          break;
 
673
        }
 
674
      }
 
675
    }
 
676
    if(not match){
 
677
      /* This interface does not match any in the list, so we don't
 
678
         connect to the server */
 
679
      if(debug){
 
680
        char interface[IF_NAMESIZE];
 
681
        if(if_indextoname((unsigned int)if_index, interface) == NULL){
 
682
          perror_plus("if_indextoname");
 
683
        } else {
 
684
          fprintf_plus(stderr, "Skipping server on non-used interface"
 
685
                       " \"%s\"\n",
 
686
                       if_indextoname((unsigned int)if_index,
 
687
                                      interface));
 
688
        }
 
689
      }
 
690
      return -1;
 
691
    }
 
692
  }
 
693
  
660
694
  ret = init_gnutls_session(&session, mc);
661
695
  if(ret != 0){
662
696
    return -1;
702
736
  }
703
737
  if(af == AF_INET6){
704
738
    to.in6.sin6_port = htons(port);    
 
739
#ifdef __GNUC__
 
740
#pragma GCC diagnostic push
 
741
#pragma GCC diagnostic ignored "-Wstrict-aliasing"
 
742
#endif
705
743
    if(IN6_IS_ADDR_LINKLOCAL /* Spurious warnings from */
706
 
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower and
707
 
                                -Wunreachable-code*/
 
744
       (&to.in6.sin6_addr)){ /* -Wstrict-aliasing=2 or lower */
 
745
#ifdef __GNUC__
 
746
#pragma GCC diagnostic pop
 
747
#endif
708
748
      if(if_index == AVAHI_IF_UNSPEC){
709
749
        fprintf_plus(stderr, "An IPv6 link-local address is"
710
750
                     " incomplete without a network interface\n");
715
755
      to.in6.sin6_scope_id = (uint32_t)if_index;
716
756
    }
717
757
  } else {
718
 
    to.in.sin_port = htons(port); /* Spurious warnings from
719
 
                                     -Wconversion and
720
 
                                     -Wunreachable-code */
 
758
    to.in.sin_port = htons(port);
721
759
  }
722
760
  
723
761
  if(quit_now){
1755
1793
int main(int argc, char *argv[]){
1756
1794
  mandos_context mc = { .server = NULL, .dh_bits = 1024,
1757
1795
                        .priority = "SECURE256:!CTYPE-X.509:"
1758
 
                        "+CTYPE-OPENPGP", .current_server = NULL };
 
1796
                        "+CTYPE-OPENPGP", .current_server = NULL, 
 
1797
                        .interfaces = NULL, .interfaces_size = 0 };
1759
1798
  AvahiSServiceBrowser *sb = NULL;
1760
1799
  error_t ret_errno;
1761
1800
  int ret;
1762
1801
  intmax_t tmpmax;
1763
1802
  char *tmp;
1764
1803
  int exitcode = EXIT_SUCCESS;
1765
 
  char *interfaces = NULL;
1766
 
  size_t interfaces_size = 0;
1767
1804
  char *interfaces_to_take_down = NULL;
1768
1805
  size_t interfaces_to_take_down_size = 0;
1769
1806
  char tempdir[] = "/tmp/mandosXXXXXX";
1869
1906
        connect_to = arg;
1870
1907
        break;
1871
1908
      case 'i':                 /* --interface */
1872
 
        ret_errno = argz_add_sep(&interfaces, &interfaces_size, arg,
1873
 
                                 (int)',');
 
1909
        ret_errno = argz_add_sep(&mc.interfaces, &mc.interfaces_size,
 
1910
                                 arg, (int)',');
1874
1911
        if(ret_errno != 0){
1875
1912
          argp_error(state, "%s", strerror(ret_errno));
1876
1913
        }
2003
2040
      }
2004
2041
    
2005
2042
      /* Lower privileges */
2006
 
      errno = 0;
2007
 
      ret = seteuid(uid);
2008
 
      if(ret == -1){
2009
 
        perror_plus("seteuid");
2010
 
      }
 
2043
      lower_privileges();
2011
2044
    }
2012
2045
  }
2013
2046
  
2014
 
  /* Remove empty interface names */
 
2047
  /* Remove invalid interface names (except "none") */
2015
2048
  {
2016
2049
    char *interface = NULL;
2017
 
    while((interface = argz_next(interfaces, interfaces_size,
 
2050
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
2018
2051
                                 interface))){
2019
 
      if(if_nametoindex(interface) == 0){
2020
 
        if(interface[0] != '\0' and strcmp(interface, "none") != 0){
 
2052
      if(strcmp(interface, "none") != 0
 
2053
         and if_nametoindex(interface) == 0){
 
2054
        if(interface[0] != '\0'){
2021
2055
          fprintf_plus(stderr, "Not using nonexisting interface"
2022
2056
                       " \"%s\"\n", interface);
2023
2057
        }
2024
 
        argz_delete(&interfaces, &interfaces_size, interface);
 
2058
        argz_delete(&mc.interfaces, &mc.interfaces_size, interface);
2025
2059
        interface = NULL;
2026
2060
      }
2027
2061
    }
2029
2063
  
2030
2064
  /* Run network hooks */
2031
2065
  {
2032
 
    
2033
 
    if(interfaces != NULL){
2034
 
      interfaces_hooks = malloc(interfaces_size);
 
2066
    if(mc.interfaces != NULL){
 
2067
      interfaces_hooks = malloc(mc.interfaces_size);
2035
2068
      if(interfaces_hooks == NULL){
2036
2069
        perror_plus("malloc");
2037
2070
        goto end;
2038
2071
      }
2039
 
      memcpy(interfaces_hooks, interfaces, interfaces_size);
2040
 
      interfaces_hooks_size = interfaces_size;
 
2072
      memcpy(interfaces_hooks, mc.interfaces, mc.interfaces_size);
 
2073
      interfaces_hooks_size = mc.interfaces_size;
2041
2074
      argz_stringify(interfaces_hooks, interfaces_hooks_size,
2042
2075
                     (int)',');
2043
2076
    }
2127
2160
  }
2128
2161
  
2129
2162
  /* If no interfaces were specified, make a list */
2130
 
  if(interfaces == NULL){
 
2163
  if(mc.interfaces == NULL){
2131
2164
    struct dirent **direntries;
2132
2165
    /* Look for any good interfaces */
2133
2166
    ret = scandir(sys_class_net, &direntries, good_interface,
2135
2168
    if(ret >= 1){
2136
2169
      /* Add all found interfaces to interfaces list */
2137
2170
      for(int i = 0; i < ret; ++i){
2138
 
        ret_errno = argz_add(&interfaces, &interfaces_size,
 
2171
        ret_errno = argz_add(&mc.interfaces, &mc.interfaces_size,
2139
2172
                             direntries[i]->d_name);
2140
2173
        if(ret_errno != 0){
2141
2174
          perror_plus("argz_add");
2155
2188
    }
2156
2189
  }
2157
2190
  
2158
 
  /* If we only got one interface, explicitly use only that one */
2159
 
  if(argz_count(interfaces, interfaces_size) == 1){
2160
 
    if(debug){
2161
 
      fprintf_plus(stderr, "Using only interface \"%s\"\n",
2162
 
                   interfaces);
2163
 
    }
2164
 
    if_index = (AvahiIfIndex)if_nametoindex(interfaces);
2165
 
  }
2166
 
  
2167
 
  /* Bring up interfaces which are down */
2168
 
  if(not (argz_count(interfaces, interfaces_size) == 1
2169
 
          and strcmp(interfaces, "none") == 0)){
 
2191
  /* Bring up interfaces which are down, and remove any "none"s */
 
2192
  {
2170
2193
    char *interface = NULL;
2171
 
    while((interface = argz_next(interfaces, interfaces_size,
 
2194
    while((interface = argz_next(mc.interfaces, mc.interfaces_size,
2172
2195
                                 interface))){
 
2196
      /* If interface name is "none", stop bringing up interfaces.
 
2197
         Also remove all instances of "none" from the list */
 
2198
      if(strcmp(interface, "none") == 0){
 
2199
        argz_delete(&mc.interfaces, &mc.interfaces_size,
 
2200
                    interface);
 
2201
        interface = NULL;
 
2202
        while((interface = argz_next(mc.interfaces,
 
2203
                                     mc.interfaces_size, interface))){
 
2204
          if(strcmp(interface, "none") == 0){
 
2205
            argz_delete(&mc.interfaces, &mc.interfaces_size,
 
2206
                        interface);
 
2207
            interface = NULL;
 
2208
          }
 
2209
        }
 
2210
        break;
 
2211
      }
2173
2212
      bool interface_was_up = interface_is_up(interface);
2174
2213
      ret = bring_up_interface(interface, delay);
2175
2214
      if(not interface_was_up){
2183
2222
        }
2184
2223
      }
2185
2224
    }
2186
 
    free(interfaces);
2187
 
    interfaces = NULL;
2188
 
    interfaces_size = 0;
2189
2225
    if(debug and (interfaces_to_take_down == NULL)){
2190
2226
      fprintf_plus(stderr, "No interfaces were brought up\n");
2191
2227
    }
2192
2228
  }
2193
2229
  
 
2230
  /* If we only got one interface, explicitly use only that one */
 
2231
  if(argz_count(mc.interfaces, mc.interfaces_size) == 1){
 
2232
    if(debug){
 
2233
      fprintf_plus(stderr, "Using only interface \"%s\"\n",
 
2234
                   mc.interfaces);
 
2235
    }
 
2236
    if_index = (AvahiIfIndex)if_nametoindex(mc.interfaces);
 
2237
  }
 
2238
  
2194
2239
  if(quit_now){
2195
2240
    goto end;
2196
2241
  }
2254
2299
      exitcode = EX_USAGE;
2255
2300
      goto end;
2256
2301
    }
2257
 
  
 
2302
    
2258
2303
    if(quit_now){
2259
2304
      goto end;
2260
2305
    }
2290
2335
        fprintf_plus(stderr, "Retrying in %d seconds\n",
2291
2336
                     (int)retry_interval);
2292
2337
      }
2293
 
      sleep((int)retry_interval);
 
2338
      sleep((unsigned int)retry_interval);
2294
2339
    }
2295
2340
    
2296
2341
    if (not quit_now){
2369
2414
  }
2370
2415
  
2371
2416
  /* Cleanup things */
 
2417
  free(mc.interfaces);
 
2418
  
2372
2419
  if(sb != NULL)
2373
2420
    avahi_s_service_browser_free(sb);
2374
2421