1 /* 2 * wpa_supplicant/hostapd control interface library 3 * Copyright (c) 2004-2007, Jouni Malinen <j (at) w1.fi> 4 * 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. 8 * 9 * Alternatively, this software may be distributed under the terms of BSD 10 * license. 11 * 12 * See README and COPYING for more details. 13 */ 14 15 #include "includes.h" 16 17 #ifdef CONFIG_CTRL_IFACE 18 19 #ifdef CONFIG_CTRL_IFACE_UNIX 20 #include <sys/un.h> 21 #endif /* CONFIG_CTRL_IFACE_UNIX */ 22 #ifdef ANDROID 23 #include <dirent.h> 24 #include <linux/limits.h> 25 #include <cutils/sockets.h> 26 #include <cutils/memory.h> 27 #include "private/android_filesystem_config.h" 28 #endif 29 30 #include "wpa_ctrl.h" 31 #include "common.h" 32 33 34 #if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP) 35 #define CTRL_IFACE_SOCKET 36 #ifdef ANDROID 37 static const char *local_socket_dir = "/data/misc/wifi/sockets"; 38 static const char *local_socket_prefix = "wpa_ctrl_"; 39 #endif /* ANDROID */ 40 #endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */ 41 42 /** 43 * struct wpa_ctrl - Internal structure for control interface library 44 * 45 * This structure is used by the wpa_supplicant/hostapd control interface 46 * library to store internal data. Programs using the library should not touch 47 * this data directly. They can only use the pointer to the data structure as 48 * an identifier for the control interface connection and use this as one of 49 * the arguments for most of the control interface library functions. 50 */ 51 struct wpa_ctrl { 52 #ifdef CONFIG_CTRL_IFACE_UDP 53 int s; 54 struct sockaddr_in local; 55 struct sockaddr_in dest; 56 char *cookie; 57 #endif /* CONFIG_CTRL_IFACE_UDP */ 58 #ifdef CONFIG_CTRL_IFACE_UNIX 59 int s; 60 struct sockaddr_un local; 61 struct sockaddr_un dest; 62 #endif /* CONFIG_CTRL_IFACE_UNIX */ 63 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 64 HANDLE pipe; 65 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 66 }; 67 68 69 #ifdef CONFIG_CTRL_IFACE_UNIX 70 71 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) 72 { 73 struct wpa_ctrl *ctrl; 74 static int counter = 0; 75 76 ctrl = os_malloc(sizeof(*ctrl)); 77 if (ctrl == NULL) 78 return NULL; 79 os_memset(ctrl, 0, sizeof(*ctrl)); 80 81 ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0); 82 if (ctrl->s < 0) { 83 os_free(ctrl); 84 return NULL; 85 } 86 87 ctrl->local.sun_family = AF_UNIX; 88 os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path), 89 #ifdef ANDROID 90 "%s/%s%d-%d", local_socket_dir, local_socket_prefix, 91 getpid(), counter++); 92 #else /* ANDROID */ 93 "/tmp/wpa_ctrl_%d-%d", getpid(), counter++); 94 #endif 95 if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, 96 sizeof(ctrl->local)) < 0) { 97 close(ctrl->s); 98 os_free(ctrl); 99 return NULL; 100 } 101 102 #ifdef ANDROID 103 chmod(ctrl->local.sun_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); 104 chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI); 105 /* 106 * If the ctrl_path isn't an absolute pathname, assume that 107 * it's the name of a socket in the Android reserved namespace. 108 * Otherwise, it's a normal UNIX domain socket appearing in the 109 * filesystem. 110 */ 111 if (ctrl_path != NULL && *ctrl_path != '/') { 112 os_snprintf(ctrl->dest.sun_path, sizeof(ctrl->dest.sun_path), "wpa_%s", 113 ctrl_path); 114 if (socket_local_client_connect(ctrl->s, 115 ctrl->dest.sun_path, 116 ANDROID_SOCKET_NAMESPACE_RESERVED, 117 SOCK_DGRAM) < 0) { 118 close(ctrl->s); 119 unlink(ctrl->local.sun_path); 120 os_free(ctrl); 121 return NULL; 122 } 123 return ctrl; 124 } 125 #endif 126 ctrl->dest.sun_family = AF_UNIX; 127 os_snprintf(ctrl->dest.sun_path, sizeof(ctrl->dest.sun_path), "%s", 128 ctrl_path); 129 if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, 130 sizeof(ctrl->dest)) < 0) { 131 close(ctrl->s); 132 unlink(ctrl->local.sun_path); 133 os_free(ctrl); 134 return NULL; 135 } 136 137 return ctrl; 138 } 139 140 141 void wpa_ctrl_close(struct wpa_ctrl *ctrl) 142 { 143 if (ctrl == NULL) 144 return; 145 unlink(ctrl->local.sun_path); 146 if (ctrl->s >= 0) 147 close(ctrl->s); 148 os_free(ctrl); 149 } 150 151 #ifdef ANDROID 152 /** 153 * wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that 154 * may be left over from clients that were previously connected to 155 * wpa_supplicant. This keeps these files from being orphaned in the 156 * event of crashes that prevented them from being removed as part 157 * of the normal orderly shutdown. 158 */ 159 void wpa_ctrl_cleanup(void) 160 { 161 DIR *dir; 162 struct dirent entry; 163 struct dirent *result; 164 size_t dirnamelen; 165 int prefixlen = strlen(local_socket_prefix); 166 size_t maxcopy; 167 char pathname[PATH_MAX]; 168 char *namep; 169 170 if ((dir = opendir(local_socket_dir)) == NULL) 171 return; 172 173 dirnamelen = (size_t)snprintf(pathname, sizeof(pathname), "%s/", local_socket_dir); 174 if (dirnamelen >= sizeof(pathname)) { 175 closedir(dir); 176 return; 177 } 178 namep = pathname + dirnamelen; 179 maxcopy = PATH_MAX-dirnamelen; 180 while (readdir_r(dir, &entry, &result) == 0 && result != NULL) { 181 if (strncmp(entry.d_name, local_socket_prefix, prefixlen) == 0) { 182 if (strlcpy(namep, entry.d_name, maxcopy) < maxcopy) { 183 unlink(pathname); 184 } 185 } 186 } 187 closedir(dir); 188 } 189 #endif /* ANDROID */ 190 191 #else /* CONFIG_CTRL_IFACE_UNIX */ 192 #ifdef ANDROID 193 void wpa_ctrl_cleanup(void) 194 { 195 } 196 #endif /* ANDROID */ 197 #endif /* CONFIG_CTRL_IFACE_UNIX */ 198 199 #ifdef CONFIG_CTRL_IFACE_UDP 200 201 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) 202 { 203 struct wpa_ctrl *ctrl; 204 char buf[128]; 205 size_t len; 206 207 ctrl = os_malloc(sizeof(*ctrl)); 208 if (ctrl == NULL) 209 return NULL; 210 os_memset(ctrl, 0, sizeof(*ctrl)); 211 212 ctrl->s = socket(PF_INET, SOCK_DGRAM, 0); 213 if (ctrl->s < 0) { 214 perror("socket"); 215 os_free(ctrl); 216 return NULL; 217 } 218 219 ctrl->local.sin_family = AF_INET; 220 ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1); 221 if (bind(ctrl->s, (struct sockaddr *) &ctrl->local, 222 sizeof(ctrl->local)) < 0) { 223 close(ctrl->s); 224 os_free(ctrl); 225 return NULL; 226 } 227 228 ctrl->dest.sin_family = AF_INET; 229 ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1); 230 ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT); 231 if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest, 232 sizeof(ctrl->dest)) < 0) { 233 perror("connect"); 234 close(ctrl->s); 235 os_free(ctrl); 236 return NULL; 237 } 238 239 len = sizeof(buf) - 1; 240 if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) { 241 buf[len] = '\0'; 242 ctrl->cookie = strdup(buf); 243 } 244 245 return ctrl; 246 } 247 248 249 void wpa_ctrl_close(struct wpa_ctrl *ctrl) 250 { 251 close(ctrl->s); 252 os_free(ctrl->cookie); 253 os_free(ctrl); 254 } 255 256 #endif /* CONFIG_CTRL_IFACE_UDP */ 257 258 259 #ifdef CTRL_IFACE_SOCKET 260 int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, 261 char *reply, size_t *reply_len, 262 void (*msg_cb)(char *msg, size_t len)) 263 { 264 struct timeval tv; 265 int res; 266 fd_set rfds; 267 const char *_cmd; 268 char *cmd_buf = NULL; 269 size_t _cmd_len; 270 271 #ifdef CONFIG_CTRL_IFACE_UDP 272 if (ctrl->cookie) { 273 char *pos; 274 _cmd_len = strlen(ctrl->cookie) + 1 + cmd_len; 275 cmd_buf = os_malloc(_cmd_len ); 276 if (cmd_buf == NULL) 277 return -1; 278 _cmd = cmd_buf; 279 pos = cmd_buf; 280 strcpy(pos, ctrl->cookie); 281 pos += strlen(ctrl->cookie); 282 *pos++ = ' '; 283 memcpy(pos, cmd, cmd_len); 284 } else 285 #endif /* CONFIG_CTRL_IFACE_UDP */ 286 { 287 _cmd = cmd; 288 _cmd_len = cmd_len; 289 } 290 291 if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) { 292 os_free(cmd_buf); 293 return -1; 294 } 295 os_free(cmd_buf); 296 297 for (;;) { 298 #ifdef ANDROID 299 tv.tv_sec = 10; 300 #else 301 tv.tv_sec = 2; 302 #endif 303 tv.tv_usec = 0; 304 FD_ZERO(&rfds); 305 FD_SET(ctrl->s, &rfds); 306 res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv); 307 if (FD_ISSET(ctrl->s, &rfds)) { 308 res = recv(ctrl->s, reply, *reply_len, 0); 309 if (res < 0) 310 return res; 311 if (res > 0 && reply[0] == '<') { 312 /* This is an unsolicited message from 313 * wpa_supplicant, not the reply to the 314 * request. Use msg_cb to report this to the 315 * caller. */ 316 if (msg_cb) { 317 /* Make sure the message is nul 318 * terminated. */ 319 if ((size_t) res == *reply_len) 320 res = (*reply_len) - 1; 321 reply[res] = '\0'; 322 msg_cb(reply, res); 323 } 324 continue; 325 } 326 *reply_len = res; 327 break; 328 } else { 329 return -2; 330 } 331 } 332 return 0; 333 } 334 #endif /* CTRL_IFACE_SOCKET */ 335 336 337 static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach) 338 { 339 char buf[10]; 340 int ret; 341 size_t len = 10; 342 343 ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6, 344 buf, &len, NULL); 345 if (ret < 0) 346 return ret; 347 if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0) 348 return 0; 349 return -1; 350 } 351 352 353 int wpa_ctrl_attach(struct wpa_ctrl *ctrl) 354 { 355 return wpa_ctrl_attach_helper(ctrl, 1); 356 } 357 358 359 int wpa_ctrl_detach(struct wpa_ctrl *ctrl) 360 { 361 return wpa_ctrl_attach_helper(ctrl, 0); 362 } 363 364 365 #ifdef CTRL_IFACE_SOCKET 366 367 int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len) 368 { 369 int res; 370 371 res = recv(ctrl->s, reply, *reply_len, 0); 372 if (res < 0) 373 return res; 374 *reply_len = res; 375 return 0; 376 } 377 378 379 int wpa_ctrl_pending(struct wpa_ctrl *ctrl) 380 { 381 struct timeval tv; 382 fd_set rfds; 383 tv.tv_sec = 0; 384 tv.tv_usec = 0; 385 FD_ZERO(&rfds); 386 FD_SET(ctrl->s, &rfds); 387 select(ctrl->s + 1, &rfds, NULL, NULL, &tv); 388 return FD_ISSET(ctrl->s, &rfds); 389 } 390 391 392 int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl) 393 { 394 return ctrl->s; 395 } 396 397 #endif /* CTRL_IFACE_SOCKET */ 398 399 400 #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE 401 402 #ifndef WPA_SUPPLICANT_NAMED_PIPE 403 #define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant" 404 #endif 405 #define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE) 406 407 struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path) 408 { 409 struct wpa_ctrl *ctrl; 410 DWORD mode; 411 TCHAR name[256]; 412 int i; 413 414 ctrl = os_malloc(sizeof(*ctrl)); 415 if (ctrl == NULL) 416 return NULL; 417 os_memset(ctrl, 0, sizeof(*ctrl)); 418 419 #ifdef UNICODE 420 if (ctrl_path == NULL) 421 _snwprintf(name, 256, NAMED_PIPE_PREFIX); 422 else 423 _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"), 424 ctrl_path); 425 #else /* UNICODE */ 426 if (ctrl_path == NULL) 427 os_snprintf(name, 256, NAMED_PIPE_PREFIX); 428 else 429 os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s", 430 ctrl_path); 431 #endif /* UNICODE */ 432 433 for (i = 0; i < 10; i++) { 434 ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, 435 NULL, OPEN_EXISTING, 0, NULL); 436 /* 437 * Current named pipe server side in wpa_supplicant is 438 * re-opening the pipe for new clients only after the previous 439 * one is taken into use. This leaves a small window for race 440 * conditions when two connections are being opened at almost 441 * the same time. Retry if that was the case. 442 */ 443 if (ctrl->pipe != INVALID_HANDLE_VALUE || 444 GetLastError() != ERROR_PIPE_BUSY) 445 break; 446 WaitNamedPipe(name, 1000); 447 } 448 if (ctrl->pipe == INVALID_HANDLE_VALUE) { 449 os_free(ctrl); 450 return NULL; 451 } 452 453 mode = PIPE_READMODE_MESSAGE; 454 if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) { 455 CloseHandle(ctrl->pipe); 456 os_free(ctrl); 457 return NULL; 458 } 459 460 return ctrl; 461 } 462 463 464 void wpa_ctrl_close(struct wpa_ctrl *ctrl) 465 { 466 CloseHandle(ctrl->pipe); 467 os_free(ctrl); 468 } 469 470 471 int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, 472 char *reply, size_t *reply_len, 473 void (*msg_cb)(char *msg, size_t len)) 474 { 475 DWORD written; 476 DWORD readlen = *reply_len; 477 478 if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL)) 479 return -1; 480 481 if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL)) 482 return -1; 483 *reply_len = readlen; 484 485 return 0; 486 } 487 488 489 int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len) 490 { 491 DWORD len = *reply_len; 492 if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL)) 493 return -1; 494 *reply_len = len; 495 return 0; 496 } 497 498 499 int wpa_ctrl_pending(struct wpa_ctrl *ctrl) 500 { 501 DWORD left; 502 503 if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL)) 504 return -1; 505 return left ? 1 : 0; 506 } 507 508 509 int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl) 510 { 511 return ctrl->pipe; 512 } 513 514 #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */ 515 516 #endif /* CONFIG_CTRL_IFACE */ 517