/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

* mandos (Client.checked_ok): Bug fix: Handle disabled client.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1085
1085
  errno = old_errno;
1086
1086
}
1087
1087
 
1088
 
bool get_flags(const char *ifname, struct ifreq *ifr){
1089
 
  int ret;
1090
 
  
1091
 
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1092
 
  if(s < 0){
1093
 
    perror_plus("socket");
1094
 
    return false;
1095
 
  }
1096
 
  strcpy(ifr->ifr_name, ifname);
1097
 
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
1098
 
  if(ret == -1){
 
1088
/* 
 
1089
 * This function determines if a directory entry in /sys/class/net
 
1090
 * corresponds to an acceptable network device.
 
1091
 * (This function is passed to scandir(3) as a filter function.)
 
1092
 */
 
1093
int good_interface(const struct dirent *if_entry){
 
1094
  ssize_t ssret;
 
1095
  char *flagname = NULL;
 
1096
  if(if_entry->d_name[0] == '.'){
 
1097
    return 0;
 
1098
  }
 
1099
  int ret = asprintf(&flagname, "%s/%s/flags", sys_class_net,
 
1100
                     if_entry->d_name);
 
1101
  if(ret < 0){
 
1102
    perror_plus("asprintf");
 
1103
    return 0;
 
1104
  }
 
1105
  int flags_fd = (int)TEMP_FAILURE_RETRY(open(flagname, O_RDONLY));
 
1106
  if(flags_fd == -1){
 
1107
    perror_plus("open");
 
1108
    free(flagname);
 
1109
    return 0;
 
1110
  }
 
1111
  free(flagname);
 
1112
  typedef short ifreq_flags;    /* ifreq.ifr_flags in netdevice(7) */
 
1113
  /* read line from flags_fd */
 
1114
  ssize_t to_read = 2+(sizeof(ifreq_flags)*2)+1; /* "0x1003\n" */
 
1115
  char *flagstring = malloc((size_t)to_read+1); /* +1 for final \0 */
 
1116
  flagstring[(size_t)to_read] = '\0';
 
1117
  if(flagstring == NULL){
 
1118
    perror_plus("malloc");
 
1119
    close(flags_fd);
 
1120
    return 0;
 
1121
  }
 
1122
  while(to_read > 0){
 
1123
    ssret = (ssize_t)TEMP_FAILURE_RETRY(read(flags_fd, flagstring,
 
1124
                                             (size_t)to_read));
 
1125
    if(ssret == -1){
 
1126
      perror_plus("read");
 
1127
      free(flagstring);
 
1128
      close(flags_fd);
 
1129
      return 0;
 
1130
    }
 
1131
    to_read -= ssret;
 
1132
    if(ssret == 0){
 
1133
      break;
 
1134
    }
 
1135
  }
 
1136
  close(flags_fd);
 
1137
  intmax_t tmpmax;
 
1138
  char *tmp;
 
1139
  errno = 0;
 
1140
  tmpmax = strtoimax(flagstring, &tmp, 0);
 
1141
  if(errno != 0 or tmp == flagstring or (*tmp != '\0'
 
1142
                                         and not (isspace(*tmp)))
 
1143
     or tmpmax != (ifreq_flags)tmpmax){
1099
1144
    if(debug){
1100
 
      perror_plus("ioctl SIOCGIFFLAGS");
 
1145
      fprintf(stderr, "Invalid flags \"%s\" for interface \"%s\"\n",
 
1146
              flagstring, if_entry->d_name);
1101
1147
    }
1102
 
    return false;
 
1148
    free(flagstring);
 
1149
    return 0;
1103
1150
  }
1104
 
  return true;
1105
 
}
1106
 
 
1107
 
bool good_flags(const char *ifname, const struct ifreq *ifr){
1108
 
  
 
1151
  free(flagstring);
 
1152
  ifreq_flags flags = (ifreq_flags)tmpmax;
1109
1153
  /* Reject the loopback device */
1110
 
  if(ifr->ifr_flags & IFF_LOOPBACK){
 
1154
  if(flags & IFF_LOOPBACK){
1111
1155
    if(debug){
1112
1156
      fprintf(stderr, "Rejecting loopback interface \"%s\"\n",
1113
 
              ifname);
 
1157
              if_entry->d_name);
1114
1158
    }
1115
 
    return false;
 
1159
    return 0;
1116
1160
  }
1117
1161
  /* Accept point-to-point devices only if connect_to is specified */
1118
 
  if(connect_to != NULL and (ifr->ifr_flags & IFF_POINTOPOINT)){
 
1162
  if(connect_to != NULL and (flags & IFF_POINTOPOINT)){
1119
1163
    if(debug){
1120
1164
      fprintf(stderr, "Accepting point-to-point interface \"%s\"\n",
1121
 
              ifname);
 
1165
              if_entry->d_name);
1122
1166
    }
1123
 
    return true;
 
1167
    return 1;
1124
1168
  }
1125
1169
  /* Otherwise, reject non-broadcast-capable devices */
1126
 
  if(not (ifr->ifr_flags & IFF_BROADCAST)){
 
1170
  if(not (flags & IFF_BROADCAST)){
1127
1171
    if(debug){
1128
1172
      fprintf(stderr, "Rejecting non-broadcast interface \"%s\"\n",
1129
 
              ifname);
 
1173
              if_entry->d_name);
1130
1174
    }
1131
 
    return false;
 
1175
    return 0;
1132
1176
  }
1133
1177
  /* Reject non-ARP interfaces (including dummy interfaces) */
1134
 
  if(ifr->ifr_flags & IFF_NOARP){
 
1178
  if(flags & IFF_NOARP){
1135
1179
    if(debug){
1136
 
      fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n", ifname);
 
1180
      fprintf(stderr, "Rejecting non-ARP interface \"%s\"\n",
 
1181
              if_entry->d_name);
1137
1182
    }
1138
 
    return false;
 
1183
    return 0;
1139
1184
  }
1140
 
  
1141
1185
  /* Accept this device */
1142
1186
  if(debug){
1143
 
    fprintf(stderr, "Interface \"%s\" is good\n", ifname);
1144
 
  }
1145
 
  return true;
1146
 
}
1147
 
 
1148
 
/* 
1149
 
 * This function determines if a directory entry in /sys/class/net
1150
 
 * corresponds to an acceptable network device.
1151
 
 * (This function is passed to scandir(3) as a filter function.)
1152
 
 */
1153
 
int good_interface(const struct dirent *if_entry){
1154
 
  int ret;
1155
 
  if(if_entry->d_name[0] == '.'){
1156
 
    return 0;
1157
 
  }
1158
 
  struct ifreq ifr;
1159
 
 
1160
 
  if(not get_flags(if_entry->d_name, &ifr)){
1161
 
    return 0;
1162
 
  }
1163
 
  
1164
 
  if(not good_flags(if_entry->d_name, &ifr)){
1165
 
    return 0;
 
1187
    fprintf(stderr, "Interface \"%s\" is acceptable\n",
 
1188
            if_entry->d_name);
1166
1189
  }
1167
1190
  return 1;
1168
1191
}