wps_ufd.c
Go to the documentation of this file.
00001 /*
00002  * UFD routines for Wi-Fi Protected Setup
00003  * Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 #include "common.h"
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <sys/wait.h>
00020 #include <fcntl.h>
00021 #include <dirent.h>
00022 
00023 #include "wps/wps.h"
00024 #include "wps/wps_i.h"
00025 
00026 #ifdef CONFIG_NATIVE_WINDOWS
00027 #define UFD_DIR1 "%s\\SMRTNTKY"
00028 #define UFD_DIR2 UFD_DIR1 "\\WFAWSC"
00029 #define UFD_FILE UFD_DIR2 "\\%s"
00030 #else /* CONFIG_NATIVE_WINDOWS */
00031 #define UFD_DIR1 "%s/SMRTNTKY"
00032 #define UFD_DIR2 UFD_DIR1 "/WFAWSC"
00033 #define UFD_FILE UFD_DIR2 "/%s"
00034 #endif /* CONFIG_NATIVE_WINDOWS */
00035 
00036 
00037 struct wps_ufd_data {
00038         int ufd_fd;
00039 };
00040 
00041 
00042 static int dev_pwd_e_file_filter(const struct dirent *entry)
00043 {
00044         unsigned int prefix;
00045         char ext[5];
00046 
00047         if (sscanf(entry->d_name, "%8x.%4s", &prefix, ext) != 2)
00048                 return 0;
00049         if (prefix == 0)
00050                 return 0;
00051         if (os_strcasecmp(ext, "WFA") != 0)
00052                 return 0;
00053 
00054         return 1;
00055 }
00056 
00057 
00058 static int wps_get_dev_pwd_e_file_name(char *path, char *file_name)
00059 {
00060         struct dirent **namelist;
00061         int i, file_num;
00062 
00063         file_num = scandir(path, &namelist, &dev_pwd_e_file_filter,
00064                            alphasort);
00065         if (file_num < 0) {
00066                 wpa_printf(MSG_ERROR, "WPS: OOB file not found: %d (%s)",
00067                            errno, strerror(errno));
00068                 return -1;
00069         }
00070         if (file_num == 0) {
00071                 wpa_printf(MSG_ERROR, "WPS: OOB file not found");
00072                 os_free(namelist);
00073                 return -1;
00074         }
00075         os_strlcpy(file_name, namelist[0]->d_name, 13);
00076         for (i = 0; i < file_num; i++)
00077                 os_free(namelist[i]);
00078         os_free(namelist);
00079         return 0;
00080 }
00081 
00082 
00083 static int get_file_name(struct wps_context *wps, int registrar,
00084                          const char *path, char *file_name)
00085 {
00086         switch (wps->oob_conf.oob_method) {
00087         case OOB_METHOD_CRED:
00088                 os_snprintf(file_name, 13, "00000000.WSC");
00089                 break;
00090         case OOB_METHOD_DEV_PWD_E:
00091                 if (registrar) {
00092                         char temp[128];
00093                         os_snprintf(temp, sizeof(temp), UFD_DIR2, path);
00094                         if (wps_get_dev_pwd_e_file_name(temp, file_name) < 0)
00095                                 return -1;
00096                 } else {
00097                         u8 *mac_addr = wps->dev.mac_addr;
00098 
00099                         os_snprintf(file_name, 13, "%02X%02X%02X%02X.WFA",
00100                                     mac_addr[2], mac_addr[3], mac_addr[4],
00101                                     mac_addr[5]);
00102                 }
00103                 break;
00104         case OOB_METHOD_DEV_PWD_R:
00105                 os_snprintf(file_name, 13, "00000000.WFA");
00106                 break;
00107         default:
00108                 wpa_printf(MSG_ERROR, "WPS: Invalid USBA OOB method");
00109                 return -1;
00110         }
00111         return 0;
00112 }
00113 
00114 
00115 static int ufd_mkdir(const char *path)
00116 {
00117         if (mkdir(path, S_IRWXU) < 0 && errno != EEXIST) {
00118                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to create directory "
00119                            "'%s': %d (%s)", path, errno, strerror(errno));
00120                 return -1;
00121         }
00122         return 0;
00123 }
00124 
00125 
00126 static void * init_ufd(struct wps_context *wps,
00127                        struct oob_device_data *oob_dev, int registrar)
00128 {
00129         int write_f;
00130         char temp[128];
00131         char *path = oob_dev->device_path;
00132         char filename[13];
00133         struct wps_ufd_data *data;
00134         int ufd_fd;
00135 
00136         if (path == NULL)
00137                 return NULL;
00138 
00139         write_f = wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E ?
00140                 !registrar : registrar;
00141 
00142         if (get_file_name(wps, registrar, path, filename) < 0) {
00143                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to get file name");
00144                 return NULL;
00145         }
00146 
00147         if (write_f) {
00148                 os_snprintf(temp, sizeof(temp), UFD_DIR1, path);
00149                 if (ufd_mkdir(temp))
00150                         return NULL;
00151                 os_snprintf(temp, sizeof(temp), UFD_DIR2, path);
00152                 if (ufd_mkdir(temp))
00153                         return NULL;
00154         }
00155 
00156         os_snprintf(temp, sizeof(temp), UFD_FILE, path, filename);
00157         if (write_f)
00158                 ufd_fd = open(temp, O_WRONLY | O_CREAT | O_TRUNC,
00159                               S_IRUSR | S_IWUSR);
00160         else
00161                 ufd_fd = open(temp, O_RDONLY);
00162         if (ufd_fd < 0) {
00163                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to open %s: %s",
00164                            temp, strerror(errno));
00165                 return NULL;
00166         }
00167 
00168         data = os_zalloc(sizeof(*data));
00169         if (data == NULL)
00170                 return NULL;
00171         data->ufd_fd = ufd_fd;
00172         return data;
00173 }
00174 
00175 
00176 static struct wpabuf * read_ufd(void *priv)
00177 {
00178         struct wps_ufd_data *data = priv;
00179         struct wpabuf *buf;
00180         struct stat s;
00181         size_t file_size;
00182 
00183         if (fstat(data->ufd_fd, &s) < 0) {
00184                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to get file size");
00185                 return NULL;
00186         }
00187 
00188         file_size = s.st_size;
00189         buf = wpabuf_alloc(file_size);
00190         if (buf == NULL) {
00191                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to alloc read "
00192                            "buffer");
00193                 return NULL;
00194         }
00195 
00196         if (read(data->ufd_fd, wpabuf_mhead(buf), file_size) !=
00197             (int) file_size) {
00198                 wpabuf_free(buf);
00199                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to read");
00200                 return NULL;
00201         }
00202         wpabuf_put(buf, file_size);
00203         return buf;
00204 }
00205 
00206 
00207 static int write_ufd(void *priv, struct wpabuf *buf)
00208 {
00209         struct wps_ufd_data *data = priv;
00210 
00211         if (write(data->ufd_fd, wpabuf_mhead(buf), wpabuf_len(buf)) !=
00212             (int) wpabuf_len(buf)) {
00213                 wpa_printf(MSG_ERROR, "WPS (UFD): Failed to write");
00214                 return -1;
00215         }
00216         return 0;
00217 }
00218 
00219 
00220 static void deinit_ufd(void *priv)
00221 {
00222         struct wps_ufd_data *data = priv;
00223         close(data->ufd_fd);
00224         os_free(data);
00225 }
00226 
00227 
00228 struct oob_device_data oob_ufd_device_data = {
00229         .device_name    = NULL,
00230         .device_path    = NULL,
00231         .init_func      = init_ufd,
00232         .read_func      = read_ufd,
00233         .write_func     = write_ufd,
00234         .deinit_func    = deinit_ufd,
00235 };


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:36