=== modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2011-11-11 09:10:58 +0000 +++ plugins.d/mandos-client.c 2011-11-11 15:05:27 +0000 @@ -53,7 +53,7 @@ sockaddr_in6, PF_INET6, SOCK_STREAM, uid_t, gid_t, open(), opendir(), DIR */ -#include /* open() */ +#include /* open(), S_ISREG */ #include /* socket(), struct sockaddr_in6, inet_pton(), connect() */ #include /* open() */ @@ -1152,13 +1152,16 @@ * (This function is passed to scandir(3) as a filter function.) */ int good_interface(const struct dirent *if_entry){ - int ret; if(if_entry->d_name[0] == '.'){ return 0; } + struct ifreq ifr; - if(not get_flags(if_entry->d_name, &ifr)){ + if(debug){ + fprintf(stderr, "Failed to get flags for interface \"%s\"\n", + if_entry->d_name); + } return 0; } @@ -1174,107 +1177,39 @@ * (This function is passed to scandir(3) as a filter function.) */ int up_interface(const struct dirent *if_entry){ - ssize_t ssret; - char *flagname = NULL; if(if_entry->d_name[0] == '.'){ return 0; } - int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net, - if_entry->d_name); - if(ret < 0){ - perror_plus("asprintf"); - return 0; - } - int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY)); - if(flags_fd == -1){ - perror_plus("open"); - free(flagname); - return 0; - } - free(flagname); - typedef short ifreq_flags; /* ifreq.ifr_flags in netdevice(7) */ - /* read line from flags_fd */ - ssize_t to_read = 2+(sizeof(ifreq_flags)*2)+1; /* "0x1003\n" */ - char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */ - flagstring[(size_t)to_read] = '\0'; - if(flagstring == NULL){ - perror_plus("malloc"); - close(flags_fd); - return 0; - } - while(to_read > 0){ - ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring, - (size_t)to_read)); - if(ssret == -1){ - perror_plus("read"); - free(flagstring); - close(flags_fd); - return 0; - } - to_read -= ssret; - if(ssret == 0){ - break; - } - } - close(flags_fd); - intmax_t tmpmax; - char *tmp; - errno = 0; - tmpmax = strtoimax(flagstring, &tmp, 0); - if(errno != 0 or tmp == flagstring or (*tmp != '\0' - and not (isspace(*tmp))) - or tmpmax != (ifreq_flags)tmpmax){ - if(debug){ - fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n", - flagstring, if_entry->d_name); - } - free(flagstring); - return 0; - } - free(flagstring); - ifreq_flags flags = (ifreq_flags)tmpmax; - /* Reject the loopback device */ - if(flags & IFF_LOOPBACK){ - if(debug){ - fprintf(stderr, "Rejecting loopback interface \"%s\"\n", + + struct ifreq ifr; + if(not get_flags(if_entry->d_name, &ifr)){ + if(debug){ + fprintf(stderr, "Failed to get flags for interface \"%s\"\n", if_entry->d_name); } return 0; } - + /* Reject down interfaces */ - if(not (flags & IFF_UP)){ - return 0; - } - - /* Accept point-to-point devices only if connect_to is specified */ - if(connect_to != NULL and (flags & IFF_POINTOPOINT)){ - if(debug){ - fprintf(stderr, "Accepting point-to-point interface \"%s\"\n", - if_entry->d_name); - } - return 1; - } - /* Otherwise, reject non-broadcast-capable devices */ - if(not (flags & IFF_BROADCAST)){ - if(debug){ - fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n", - if_entry->d_name); - } - return 0; - } - /* Reject non-ARP interfaces (including dummy interfaces) */ - if(flags & IFF_NOARP){ - if(debug){ - fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n", - if_entry->d_name); - } - return 0; - } - /* Accept this device */ - if(debug){ - fprintf(stderr, "Interface \"%s\" is acceptable\n", - if_entry->d_name); + if(not (ifr.ifr_flags & IFF_UP)){ + if(debug){ + fprintf(stderr, "Rejecting down interface \"%s\"\n", + if_entry->d_name); + } + return 0; + } + + /* Reject non-running interfaces */ + if(not (ifr.ifr_flags & IFF_RUNNING)){ + if(debug){ + fprintf(stderr, "Rejecting non-running interface \"%s\"\n", + if_entry->d_name); + } + return 0; + } + + if(not good_flags(if_entry->d_name, &ifr)){ + return 0; } return 1; } @@ -1323,7 +1258,7 @@ } return 0; } - if(not (st.st_mode & S_ISREG)){ + if(not (S_ISREG(st.st_mode))){ /* Not a regular file */ return 0; } @@ -1677,7 +1612,7 @@ setenv("VERBOSE", debug ? "1" : "0", 1); setenv("MODE", "start", 1); /* setenv( XXX more here */ - ret = execl(fullname, direntry->d_name, "start"); + ret = execl(fullname, direntry->d_name, "start", NULL); perror_plus("execl"); } free(fullname); @@ -1694,10 +1629,17 @@ if(interface[0] == '\0'){ struct dirent **direntries; - ret = scandir(sys_class_net, &direntries, good_interface, + /* First look for interfaces that are up */ + ret = scandir(sys_class_net, &direntries, up_interface, alphasort); + if(ret == 0){ + /* No up interfaces, look for any good interfaces */ + free(direntries); + ret = scandir(sys_class_net, &direntries, good_interface, + alphasort); + } if(ret >= 1){ - /* Pick the first good interface */ + /* Pick the first interface returned */ interface = strdup(direntries[0]->d_name); if(debug){ fprintf(stderr, "Using interface \"%s\"\n", interface);