2 * UFD routines for Wi-Fi Protected Setup
3 * Copyright (c) 2009, Masashi Honma <honma@ictec.co.jp>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
17 #include <sys/types.h>
24 #include "wps/wps_i.h"
26 #ifdef CONFIG_NATIVE_WINDOWS
27 #define UFD_DIR1 "%s\\SMRTNTKY"
28 #define UFD_DIR2 UFD_DIR1 "\\WFAWSC"
29 #define UFD_FILE UFD_DIR2 "\\%s"
30 #else /* CONFIG_NATIVE_WINDOWS */
31 #define UFD_DIR1 "%s/SMRTNTKY"
32 #define UFD_DIR2 UFD_DIR1 "/WFAWSC"
33 #define UFD_FILE UFD_DIR2 "/%s"
34 #endif /* CONFIG_NATIVE_WINDOWS */
42 static int dev_pwd_e_file_filter(const struct dirent
*entry
)
47 if (sscanf(entry
->d_name
, "%8x.%4s", &prefix
, ext
) != 2)
51 if (os_strcasecmp(ext
, "WFA") != 0)
58 static int wps_get_dev_pwd_e_file_name(char *path
, char *file_name
)
60 struct dirent
**namelist
;
63 file_num
= scandir(path
, &namelist
, &dev_pwd_e_file_filter
,
66 wpa_printf(MSG_ERROR
, "WPS: OOB file not found: %d (%s)",
67 errno
, strerror(errno
));
71 wpa_printf(MSG_ERROR
, "WPS: OOB file not found");
75 os_strlcpy(file_name
, namelist
[0]->d_name
, 13);
76 for (i
= 0; i
< file_num
; i
++)
83 static int get_file_name(struct wps_context
*wps
, int registrar
,
84 const char *path
, char *file_name
)
86 switch (wps
->oob_conf
.oob_method
) {
88 os_snprintf(file_name
, 13, "00000000.WSC");
90 case OOB_METHOD_DEV_PWD_E
:
93 os_snprintf(temp
, sizeof(temp
), UFD_DIR2
, path
);
94 if (wps_get_dev_pwd_e_file_name(temp
, file_name
) < 0)
97 u8
*mac_addr
= wps
->dev
.mac_addr
;
99 os_snprintf(file_name
, 13, "%02X%02X%02X%02X.WFA",
100 mac_addr
[2], mac_addr
[3], mac_addr
[4],
104 case OOB_METHOD_DEV_PWD_R
:
105 os_snprintf(file_name
, 13, "00000000.WFA");
108 wpa_printf(MSG_ERROR
, "WPS: Invalid USBA OOB method");
115 static int ufd_mkdir(const char *path
)
117 if (mkdir(path
, S_IRWXU
) < 0 && errno
!= EEXIST
) {
118 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to create directory "
119 "'%s': %d (%s)", path
, errno
, strerror(errno
));
126 static void * init_ufd(struct wps_context
*wps
,
127 struct oob_device_data
*oob_dev
, int registrar
)
131 char *path
= oob_dev
->device_path
;
133 struct wps_ufd_data
*data
;
139 write_f
= wps
->oob_conf
.oob_method
== OOB_METHOD_DEV_PWD_E
?
140 !registrar
: registrar
;
142 if (get_file_name(wps
, registrar
, path
, filename
) < 0) {
143 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to get file name");
148 os_snprintf(temp
, sizeof(temp
), UFD_DIR1
, path
);
151 os_snprintf(temp
, sizeof(temp
), UFD_DIR2
, path
);
156 os_snprintf(temp
, sizeof(temp
), UFD_FILE
, path
, filename
);
158 ufd_fd
= open(temp
, O_WRONLY
| O_CREAT
| O_TRUNC
,
161 ufd_fd
= open(temp
, O_RDONLY
);
163 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to open %s: %s",
164 temp
, strerror(errno
));
168 data
= os_zalloc(sizeof(*data
));
171 data
->ufd_fd
= ufd_fd
;
176 static struct wpabuf
* read_ufd(void *priv
)
178 struct wps_ufd_data
*data
= priv
;
183 if (fstat(data
->ufd_fd
, &s
) < 0) {
184 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to get file size");
188 file_size
= s
.st_size
;
189 buf
= wpabuf_alloc(file_size
);
191 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to alloc read "
196 if (read(data
->ufd_fd
, wpabuf_mhead(buf
), file_size
) !=
199 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to read");
202 wpabuf_put(buf
, file_size
);
207 static int write_ufd(void *priv
, struct wpabuf
*buf
)
209 struct wps_ufd_data
*data
= priv
;
211 if (write(data
->ufd_fd
, wpabuf_mhead(buf
), wpabuf_len(buf
)) !=
212 (int) wpabuf_len(buf
)) {
213 wpa_printf(MSG_ERROR
, "WPS (UFD): Failed to write");
220 static void deinit_ufd(void *priv
)
222 struct wps_ufd_data
*data
= priv
;
228 struct oob_device_data oob_ufd_device_data
= {
231 .init_func
= init_ufd
,
232 .read_func
= read_ufd
,
233 .write_func
= write_ufd
,
234 .deinit_func
= deinit_ufd
,