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