/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/mandos-client.c

Merge from trunk.  Lots of bug fixes, including Debian bug #546928.

Show diffs side-by-side

added added

removed removed

Lines of Context:
125
125
static const char mandos_protocol_version[] = "1";
126
126
const char *argp_program_version = "mandos-client " VERSION;
127
127
const char *argp_program_bug_address = "<mandos@fukt.bsnet.se>";
128
 
static const char sys_class_net[] = "/sys/class/net";
129
 
char *connect_to = NULL;
130
128
 
131
129
/* Used for passing in values through the Avahi callback functions */
132
130
typedef struct {
976
974
  errno = old_errno;
977
975
}
978
976
 
979
 
/* 
980
 
 * This function determines if a directory entry in /sys/class/net
981
 
 * corresponds to an acceptable network device.
982
 
 * (This function is passed to scandir(3) as a filter function.)
983
 
 */
984
 
int good_interface(const struct dirent *if_entry){
985
 
  ssize_t ssret;
986
 
  char *flagname = NULL;
987
 
  int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
988
 
                     if_entry->d_name);
989
 
  if(ret < 0){
990
 
    perror("asprintf");
991
 
    return 0;
992
 
  }
993
 
  if(if_entry->d_name[0] == '.'){
994
 
    return 0;
995
 
  }
996
 
  int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
997
 
  if(flags_fd == -1){
998
 
    perror("open");
999
 
    return 0;
1000
 
  }
1001
 
  typedef short ifreq_flags;    /* ifreq.ifr_flags in netdevice(7) */
1002
 
  /* read line from flags_fd */
1003
 
  ssize_t to_read = (sizeof(ifreq_flags)*2)+3; /* "0x1003\n" */
1004
 
  char *flagstring = malloc((size_t)to_read);
1005
 
  if(flagstring == NULL){
1006
 
    perror("malloc");
1007
 
    close(flags_fd);
1008
 
    return 0;
1009
 
  }
1010
 
  while(to_read > 0){
1011
 
    ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
1012
 
                                             (size_t)to_read));
1013
 
    if(ssret == -1){
1014
 
      perror("read");
1015
 
      free(flagstring);
1016
 
      close(flags_fd);
1017
 
      return 0;
1018
 
    }
1019
 
    to_read -= ssret;
1020
 
    if(ssret == 0){
1021
 
      break;
1022
 
    }
1023
 
  }
1024
 
  close(flags_fd);
1025
 
  intmax_t tmpmax;
1026
 
  char *tmp;
1027
 
  errno = 0;
1028
 
  tmpmax = strtoimax(flagstring, &tmp, 0);
1029
 
  if(errno != 0 or tmp == flagstring or (*tmp != '\0'
1030
 
                                         and not (isspace(*tmp)))
1031
 
     or tmpmax != (ifreq_flags)tmpmax){
1032
 
    free(flagstring);
1033
 
    return 0;
1034
 
  }
1035
 
  free(flagstring);
1036
 
  ifreq_flags flags = (ifreq_flags)tmpmax;
1037
 
  /* Reject the loopback device */
1038
 
  if(flags & IFF_LOOPBACK){
1039
 
    return 0;
1040
 
  }
1041
 
  /* Accept point-to-point devices only if connect_to is specified */
1042
 
  if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
1043
 
    return 1;
1044
 
  }
1045
 
  /* Otherwise, reject non-broadcast-capable devices */
1046
 
  if(not (flags & IFF_BROADCAST)){
1047
 
    return 0;
1048
 
  }
1049
 
  /* Accept this device */
1050
 
  return 1;
1051
 
}
1052
 
 
1053
977
int main(int argc, char *argv[]){
1054
978
  AvahiSServiceBrowser *sb = NULL;
1055
979
  int error;
1057
981
  intmax_t tmpmax;
1058
982
  char *tmp;
1059
983
  int exitcode = EXIT_SUCCESS;
1060
 
  const char *interface = "";
 
984
  const char *interface = "eth0";
1061
985
  struct ifreq network;
1062
986
  int sd = -1;
1063
987
  bool take_down_interface = false;
1064
988
  uid_t uid;
1065
989
  gid_t gid;
 
990
  char *connect_to = NULL;
1066
991
  char tempdir[] = "/tmp/mandosXXXXXX";
1067
992
  bool tempdir_created = false;
1068
993
  AvahiIfIndex if_index = AVAHI_IF_UNSPEC;
1198
1123
  if(not debug){
1199
1124
    avahi_set_log_function(empty_log);
1200
1125
  }
1201
 
 
1202
 
  if(interface[0] == '\0'){
1203
 
    struct dirent **direntries;
1204
 
    ret = scandir(sys_class_net, &direntries, good_interface,
1205
 
                  alphasort);
1206
 
    if(ret >= 1){
1207
 
      /* Pick the first good interface */
1208
 
      interface = strdup(direntries[0]->d_name);
1209
 
      if(interface == NULL){
1210
 
        perror("malloc");
1211
 
        free(direntries);
1212
 
        exitcode = EXIT_FAILURE;
1213
 
        goto end;
1214
 
      }
1215
 
      free(direntries);
1216
 
    } else {
1217
 
      free(direntries);
1218
 
      fprintf(stderr, "Could not find a network interface\n");
1219
 
      exitcode = EXIT_FAILURE;
1220
 
      goto end;
1221
 
    }
1222
 
  }
1223
1126
  
1224
1127
  /* Initialize Avahi early so avahi_simple_poll_quit() can be called
1225
1128
     from the signal handler */
1296
1199
  }
1297
1200
  
1298
1201
  /* If the interface is down, bring it up */
1299
 
  if(strcmp(interface, "none") != 0){
 
1202
  if(interface[0] != '\0'){
1300
1203
    if_index = (AvahiIfIndex) if_nametoindex(interface);
1301
1204
    if(if_index == 0){
1302
1205
      fprintf(stderr, "No such interface: \"%s\"\n", interface);