1 /* 2 * WPA Supplicant / UNIX domain socket -based control interface 3 * Copyright (c) 2004-2020, Jouni Malinen <j@w1.fi> 4 * 5 * This software may be distributed under the terms of the BSD license. 6 * See README for more details. 7 */ 8 9 #include "includes.h" 10 #include <sys/un.h> 11 #include <sys/stat.h> 12 #include <grp.h> 13 #include <stddef.h> 14 #include <unistd.h> 15 #include <fcntl.h> 16 #ifdef __linux__ 17 #include <sys/ioctl.h> 18 #endif /* __linux__ */ 19 #ifdef ANDROID 20 #include <cutils/sockets.h> 21 #endif /* ANDROID */ 22 23 #include "utils/common.h" 24 #include "utils/eloop.h" 25 #include "utils/list.h" 26 #include "common/ctrl_iface_common.h" 27 #include "eapol_supp/eapol_supp_sm.h" 28 #include "config.h" 29 #include "wpa_supplicant_i.h" 30 #include "ctrl_iface.h" 31 32 /* Per-interface ctrl_iface */ 33 34 struct ctrl_iface_priv { 35 struct wpa_supplicant *wpa_s; 36 int sock; 37 struct dl_list ctrl_dst; 38 int android_control_socket; 39 struct dl_list msg_queue; 40 unsigned int throttle_count; 41 }; 42 43 44 struct ctrl_iface_global_priv { 45 struct wpa_global *global; 46 int sock; 47 struct dl_list ctrl_dst; 48 int android_control_socket; 49 struct dl_list msg_queue; 50 unsigned int throttle_count; 51 }; 52 53 struct ctrl_iface_msg { 54 struct dl_list list; 55 struct wpa_supplicant *wpa_s; 56 int level; 57 enum wpa_msg_type type; 58 const char *txt; 59 size_t len; 60 }; 61 62 63 static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, 64 const char *ifname, int sock, 65 struct dl_list *ctrl_dst, 66 int level, const char *buf, 67 size_t len, 68 struct ctrl_iface_priv *priv, 69 struct ctrl_iface_global_priv *gp); 70 static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s, 71 struct ctrl_iface_priv *priv); 72 static int wpas_ctrl_iface_global_reinit(struct wpa_global *global, 73 struct ctrl_iface_global_priv *priv); 74 75 76 static void wpas_ctrl_sock_debug(const char *title, int sock, const char *buf, 77 size_t len) 78 { 79 #ifdef __linux__ 80 socklen_t optlen; 81 int sndbuf, outq; 82 int level = MSG_MSGDUMP; 83 84 if (len >= 5 && os_strncmp(buf, "PONG\n", 5) == 0) 85 level = MSG_EXCESSIVE; 86 87 optlen = sizeof(sndbuf); 88 sndbuf = 0; 89 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0) 90 sndbuf = -1; 91 92 if (ioctl(sock, TIOCOUTQ, &outq) < 0) 93 outq = -1; 94 95 wpa_printf(level, 96 "CTRL-DEBUG: %s: sock=%d sndbuf=%d outq=%d send_len=%d", 97 title, sock, sndbuf, outq, (int) len); 98 #endif /* __linux__ */ 99 } 100 101 102 static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst, 103 struct sockaddr_storage *from, 104 socklen_t fromlen, int global) 105 { 106 return ctrl_iface_attach(ctrl_dst, from, fromlen, NULL); 107 } 108 109 110 static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst, 111 struct sockaddr_storage *from, 112 socklen_t fromlen) 113 { 114 return ctrl_iface_detach(ctrl_dst, from, fromlen); 115 } 116 117 118 static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, 119 struct sockaddr_storage *from, 120 socklen_t fromlen, 121 char *level) 122 { 123 wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 124 125 return ctrl_iface_level(&priv->ctrl_dst, from, fromlen, level); 126 } 127 128 129 static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, 130 void *sock_ctx) 131 { 132 struct wpa_supplicant *wpa_s = eloop_ctx; 133 struct ctrl_iface_priv *priv = sock_ctx; 134 char *buf; 135 int res; 136 struct sockaddr_storage from; 137 socklen_t fromlen = sizeof(from); 138 char *reply = NULL, *reply_buf = NULL; 139 size_t reply_len = 0; 140 int new_attached = 0; 141 142 buf = os_malloc(CTRL_IFACE_MAX_LEN + 1); 143 if (!buf) 144 return; 145 res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0, 146 (struct sockaddr *) &from, &fromlen); 147 if (res < 0) { 148 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 149 strerror(errno)); 150 os_free(buf); 151 return; 152 } 153 if ((size_t) res > CTRL_IFACE_MAX_LEN) { 154 wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated"); 155 os_free(buf); 156 return; 157 } 158 buf[res] = '\0'; 159 160 if (os_strcmp(buf, "ATTACH") == 0) { 161 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 162 fromlen, 0)) 163 reply_len = 1; 164 else { 165 new_attached = 1; 166 reply_len = 2; 167 } 168 } else if (os_strcmp(buf, "DETACH") == 0) { 169 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 170 fromlen)) 171 reply_len = 1; 172 else 173 reply_len = 2; 174 } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 175 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen, 176 buf + 6)) 177 reply_len = 1; 178 else 179 reply_len = 2; 180 } else { 181 reply_buf = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 182 &reply_len); 183 reply = reply_buf; 184 185 /* 186 * There could be some password/key material in the command, so 187 * clear the buffer explicitly now that it is not needed 188 * anymore. 189 */ 190 os_memset(buf, 0, res); 191 } 192 193 if (!reply && reply_len == 1) { 194 reply = "FAIL\n"; 195 reply_len = 5; 196 } else if (!reply && reply_len == 2) { 197 reply = "OK\n"; 198 reply_len = 3; 199 } 200 201 if (reply) { 202 wpas_ctrl_sock_debug("ctrl_sock-sendto", sock, reply, 203 reply_len); 204 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 205 fromlen) < 0) { 206 int _errno = errno; 207 wpa_dbg(wpa_s, MSG_DEBUG, 208 "ctrl_iface sendto failed: %d - %s", 209 _errno, strerror(_errno)); 210 if (_errno == ENOBUFS || _errno == EAGAIN) { 211 /* 212 * The socket send buffer could be full. This 213 * may happen if client programs are not 214 * receiving their pending messages. Close and 215 * reopen the socket as a workaround to avoid 216 * getting stuck being unable to send any new 217 * responses. 218 */ 219 sock = wpas_ctrl_iface_reinit(wpa_s, priv); 220 if (sock < 0) { 221 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket"); 222 } 223 } 224 if (new_attached) { 225 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to send response to ATTACH - detaching"); 226 new_attached = 0; 227 wpa_supplicant_ctrl_iface_detach( 228 &priv->ctrl_dst, &from, fromlen); 229 } 230 } 231 } 232 os_free(reply_buf); 233 os_free(buf); 234 235 if (new_attached) 236 eapol_sm_notify_ctrl_attached(wpa_s->eapol); 237 } 238 239 240 static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s) 241 { 242 char *buf; 243 size_t len; 244 char *pbuf, *dir = NULL; 245 int res; 246 247 if (wpa_s->conf->ctrl_interface == NULL) 248 return NULL; 249 250 pbuf = os_strdup(wpa_s->conf->ctrl_interface); 251 if (pbuf == NULL) 252 return NULL; 253 if (os_strncmp(pbuf, "DIR=", 4) == 0) { 254 char *gid_str; 255 dir = pbuf + 4; 256 gid_str = os_strstr(dir, " GROUP="); 257 if (gid_str) 258 *gid_str = '\0'; 259 } else 260 dir = pbuf; 261 262 len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2; 263 buf = os_malloc(len); 264 if (buf == NULL) { 265 os_free(pbuf); 266 return NULL; 267 } 268 269 res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname); 270 if (os_snprintf_error(len, res)) { 271 os_free(pbuf); 272 os_free(buf); 273 return NULL; 274 } 275 #ifdef __CYGWIN__ 276 { 277 /* Windows/WinPcap uses interface names that are not suitable 278 * as a file name - convert invalid chars to underscores */ 279 char *pos = buf; 280 while (*pos) { 281 if (*pos == '\\') 282 *pos = '_'; 283 pos++; 284 } 285 } 286 #endif /* __CYGWIN__ */ 287 os_free(pbuf); 288 return buf; 289 } 290 291 292 static int wpas_ctrl_iface_throttle(int sock) 293 { 294 #ifdef __linux__ 295 socklen_t optlen; 296 int sndbuf, outq; 297 298 optlen = sizeof(sndbuf); 299 sndbuf = 0; 300 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0 || 301 ioctl(sock, TIOCOUTQ, &outq) < 0 || 302 sndbuf <= 0 || outq < 0) 303 return 0; 304 return outq > sndbuf / 2; 305 #else /* __linux__ */ 306 return 0; 307 #endif /* __linux__ */ 308 } 309 310 311 static void wpas_ctrl_msg_send_pending_global(struct wpa_global *global) 312 { 313 struct ctrl_iface_global_priv *gpriv; 314 struct ctrl_iface_msg *msg; 315 316 gpriv = global->ctrl_iface; 317 while (gpriv && !dl_list_empty(&gpriv->msg_queue) && 318 !wpas_ctrl_iface_throttle(gpriv->sock)) { 319 msg = dl_list_first(&gpriv->msg_queue, struct ctrl_iface_msg, 320 list); 321 if (!msg) 322 break; 323 dl_list_del(&msg->list); 324 wpa_supplicant_ctrl_iface_send( 325 msg->wpa_s, 326 msg->type != WPA_MSG_PER_INTERFACE ? 327 NULL : msg->wpa_s->ifname, 328 gpriv->sock, &gpriv->ctrl_dst, msg->level, 329 msg->txt, msg->len, NULL, gpriv); 330 os_free(msg); 331 } 332 } 333 334 335 static void wpas_ctrl_msg_send_pending_iface(struct wpa_supplicant *wpa_s) 336 { 337 struct ctrl_iface_priv *priv; 338 struct ctrl_iface_msg *msg; 339 340 priv = wpa_s->ctrl_iface; 341 while (priv && !dl_list_empty(&priv->msg_queue) && 342 !wpas_ctrl_iface_throttle(priv->sock)) { 343 msg = dl_list_first(&priv->msg_queue, struct ctrl_iface_msg, 344 list); 345 if (!msg) 346 break; 347 dl_list_del(&msg->list); 348 wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock, 349 &priv->ctrl_dst, msg->level, 350 msg->txt, msg->len, priv, NULL); 351 os_free(msg); 352 } 353 } 354 355 356 static void wpas_ctrl_msg_queue_timeout(void *eloop_ctx, void *timeout_ctx) 357 { 358 struct wpa_supplicant *wpa_s = eloop_ctx; 359 struct ctrl_iface_priv *priv; 360 struct ctrl_iface_global_priv *gpriv; 361 int sock = -1, gsock = -1; 362 363 wpas_ctrl_msg_send_pending_global(wpa_s->global); 364 wpas_ctrl_msg_send_pending_iface(wpa_s); 365 366 priv = wpa_s->ctrl_iface; 367 if (priv && !dl_list_empty(&priv->msg_queue)) 368 sock = priv->sock; 369 370 gpriv = wpa_s->global->ctrl_iface; 371 if (gpriv && !dl_list_empty(&gpriv->msg_queue)) 372 gsock = gpriv->sock; 373 374 if (sock > -1 || gsock > -1) { 375 /* Continue pending message transmission from a timeout */ 376 wpa_printf(MSG_MSGDUMP, 377 "CTRL: Had to throttle pending event message transmission for (sock %d gsock %d)", 378 sock, gsock); 379 eloop_register_timeout(0, 20000, wpas_ctrl_msg_queue_timeout, 380 wpa_s, NULL); 381 } 382 } 383 384 385 static void wpas_ctrl_msg_queue(struct dl_list *queue, 386 struct wpa_supplicant *wpa_s, int level, 387 enum wpa_msg_type type, 388 const char *txt, size_t len) 389 { 390 struct ctrl_iface_msg *msg; 391 392 msg = os_zalloc(sizeof(*msg) + len); 393 if (!msg) 394 return; 395 396 msg->wpa_s = wpa_s; 397 msg->level = level; 398 msg->type = type; 399 os_memcpy(msg + 1, txt, len); 400 msg->txt = (const char *) (msg + 1); 401 msg->len = len; 402 dl_list_add_tail(queue, &msg->list); 403 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL); 404 eloop_register_timeout(0, 0, wpas_ctrl_msg_queue_timeout, wpa_s, NULL); 405 } 406 407 408 static void wpas_ctrl_msg_queue_limit(unsigned int throttle_count, 409 struct dl_list *queue) 410 { 411 struct ctrl_iface_msg *msg; 412 413 if (throttle_count < 2000) 414 return; 415 416 msg = dl_list_first(queue, struct ctrl_iface_msg, list); 417 if (msg) { 418 wpa_printf(MSG_DEBUG, "CTRL: Dropped oldest pending message"); 419 dl_list_del(&msg->list); 420 os_free(msg); 421 } 422 } 423 424 425 static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, 426 enum wpa_msg_type type, 427 const char *txt, size_t len) 428 { 429 struct wpa_supplicant *wpa_s = ctx; 430 struct ctrl_iface_priv *priv; 431 struct ctrl_iface_global_priv *gpriv; 432 433 if (wpa_s == NULL) 434 return; 435 436 gpriv = wpa_s->global->ctrl_iface; 437 438 if (type != WPA_MSG_NO_GLOBAL && gpriv && 439 !dl_list_empty(&gpriv->ctrl_dst)) { 440 if (!dl_list_empty(&gpriv->msg_queue) || 441 wpas_ctrl_iface_throttle(gpriv->sock)) { 442 if (gpriv->throttle_count == 0) { 443 wpa_printf(MSG_MSGDUMP, 444 "CTRL: Had to throttle global event message for sock %d", 445 gpriv->sock); 446 } 447 gpriv->throttle_count++; 448 wpas_ctrl_msg_queue_limit(gpriv->throttle_count, 449 &gpriv->msg_queue); 450 wpas_ctrl_msg_queue(&gpriv->msg_queue, wpa_s, level, 451 type, txt, len); 452 } else { 453 if (gpriv->throttle_count) { 454 wpa_printf(MSG_MSGDUMP, 455 "CTRL: Had to throttle %u global event message(s) for sock %d", 456 gpriv->throttle_count, gpriv->sock); 457 } 458 gpriv->throttle_count = 0; 459 wpa_supplicant_ctrl_iface_send( 460 wpa_s, 461 type != WPA_MSG_PER_INTERFACE ? 462 NULL : wpa_s->ifname, 463 gpriv->sock, &gpriv->ctrl_dst, level, 464 txt, len, NULL, gpriv); 465 } 466 } 467 468 priv = wpa_s->ctrl_iface; 469 470 if (type != WPA_MSG_ONLY_GLOBAL && priv) { 471 if (!dl_list_empty(&priv->msg_queue) || 472 wpas_ctrl_iface_throttle(priv->sock)) { 473 if (priv->throttle_count == 0) { 474 wpa_printf(MSG_MSGDUMP, 475 "CTRL: Had to throttle event message for sock %d", 476 priv->sock); 477 } 478 priv->throttle_count++; 479 wpas_ctrl_msg_queue_limit(priv->throttle_count, 480 &priv->msg_queue); 481 wpas_ctrl_msg_queue(&priv->msg_queue, wpa_s, level, 482 type, txt, len); 483 } else { 484 if (priv->throttle_count) { 485 wpa_printf(MSG_MSGDUMP, 486 "CTRL: Had to throttle %u event message(s) for sock %d", 487 priv->throttle_count, priv->sock); 488 } 489 priv->throttle_count = 0; 490 wpa_supplicant_ctrl_iface_send(wpa_s, NULL, priv->sock, 491 &priv->ctrl_dst, level, 492 txt, len, priv, NULL); 493 } 494 } 495 } 496 497 498 static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s, 499 struct ctrl_iface_priv *priv) 500 { 501 struct sockaddr_un addr; 502 char *fname = NULL; 503 gid_t gid = 0; 504 int gid_set = 0; 505 char *buf, *dir = NULL, *gid_str = NULL; 506 struct group *grp; 507 char *endp; 508 int flags; 509 510 buf = os_strdup(wpa_s->conf->ctrl_interface); 511 if (buf == NULL) 512 goto fail; 513 #ifdef ANDROID 514 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s", 515 wpa_s->conf->ctrl_interface); 516 priv->sock = android_get_control_socket(addr.sun_path); 517 if (priv->sock >= 0) { 518 priv->android_control_socket = 1; 519 goto havesock; 520 } 521 #endif /* ANDROID */ 522 if (os_strncmp(buf, "DIR=", 4) == 0) { 523 dir = buf + 4; 524 gid_str = os_strstr(dir, " GROUP="); 525 if (gid_str) { 526 *gid_str = '\0'; 527 gid_str += 7; 528 } 529 } else { 530 dir = buf; 531 gid_str = wpa_s->conf->ctrl_interface_group; 532 } 533 534 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { 535 if (errno == EEXIST) { 536 wpa_printf(MSG_DEBUG, "Using existing control " 537 "interface directory."); 538 } else { 539 wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s", 540 dir, strerror(errno)); 541 goto fail; 542 } 543 } 544 545 #ifdef ANDROID 546 /* 547 * wpa_supplicant is started from /init.*.rc on Android and that seems 548 * to be using umask 0077 which would leave the control interface 549 * directory without group access. This breaks things since Wi-Fi 550 * framework assumes that this directory can be accessed by other 551 * applications in the wifi group. Fix this by adding group access even 552 * if umask value would prevent this. 553 */ 554 if (chmod(dir, S_IRWXU | S_IRWXG) < 0) { 555 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s", 556 strerror(errno)); 557 /* Try to continue anyway */ 558 } 559 #endif /* ANDROID */ 560 561 if (gid_str) { 562 grp = getgrnam(gid_str); 563 if (grp) { 564 gid = grp->gr_gid; 565 gid_set = 1; 566 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 567 " (from group name '%s')", 568 (int) gid, gid_str); 569 } else { 570 /* Group name not found - try to parse this as gid */ 571 gid = strtol(gid_str, &endp, 10); 572 if (*gid_str == '\0' || *endp != '\0') { 573 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 574 "'%s'", gid_str); 575 goto fail; 576 } 577 gid_set = 1; 578 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 579 (int) gid); 580 } 581 } 582 583 if (gid_set && lchown(dir, -1, gid) < 0) { 584 wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s", 585 dir, (int) gid, strerror(errno)); 586 goto fail; 587 } 588 589 /* Make sure the group can enter and read the directory */ 590 if (gid_set && 591 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) { 592 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s", 593 strerror(errno)); 594 goto fail; 595 } 596 597 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= 598 sizeof(addr.sun_path)) { 599 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded"); 600 goto fail; 601 } 602 603 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 604 if (priv->sock < 0) { 605 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 606 goto fail; 607 } 608 609 os_memset(&addr, 0, sizeof(addr)); 610 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 611 addr.sun_len = sizeof(addr); 612 #endif /* __FreeBSD__ */ 613 addr.sun_family = AF_UNIX; 614 fname = wpa_supplicant_ctrl_iface_path(wpa_s); 615 if (fname == NULL) 616 goto fail; 617 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 618 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 619 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 620 strerror(errno)); 621 if (connect(priv->sock, (struct sockaddr *) &addr, 622 sizeof(addr)) < 0) { 623 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 624 " allow connections - assuming it was left" 625 "over from forced program termination"); 626 if (unlink(fname) < 0) { 627 wpa_printf(MSG_ERROR, 628 "Could not unlink existing ctrl_iface socket '%s': %s", 629 fname, strerror(errno)); 630 goto fail; 631 } 632 if (bind(priv->sock, (struct sockaddr *) &addr, 633 sizeof(addr)) < 0) { 634 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s", 635 strerror(errno)); 636 goto fail; 637 } 638 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 639 "ctrl_iface socket '%s'", fname); 640 } else { 641 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 642 "be in use - cannot override it"); 643 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 644 "not used anymore", fname); 645 os_free(fname); 646 fname = NULL; 647 goto fail; 648 } 649 } 650 651 if (gid_set && lchown(fname, -1, gid) < 0) { 652 wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s", 653 fname, (int) gid, strerror(errno)); 654 goto fail; 655 } 656 657 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 658 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s", 659 fname, strerror(errno)); 660 goto fail; 661 } 662 os_free(fname); 663 664 #ifdef ANDROID 665 havesock: 666 #endif /* ANDROID */ 667 668 /* 669 * Make socket non-blocking so that we don't hang forever if 670 * target dies unexpectedly. 671 */ 672 flags = fcntl(priv->sock, F_GETFL); 673 if (flags >= 0) { 674 flags |= O_NONBLOCK; 675 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 676 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 677 strerror(errno)); 678 /* Not fatal, continue on.*/ 679 } 680 } 681 682 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, 683 wpa_s, priv); 684 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 685 686 os_free(buf); 687 return 0; 688 689 fail: 690 if (priv->sock >= 0) { 691 close(priv->sock); 692 priv->sock = -1; 693 } 694 if (fname) { 695 unlink(fname); 696 os_free(fname); 697 } 698 os_free(buf); 699 return -1; 700 } 701 702 703 struct ctrl_iface_priv * 704 wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 705 { 706 struct ctrl_iface_priv *priv; 707 708 priv = os_zalloc(sizeof(*priv)); 709 if (priv == NULL) 710 return NULL; 711 dl_list_init(&priv->ctrl_dst); 712 dl_list_init(&priv->msg_queue); 713 priv->wpa_s = wpa_s; 714 priv->sock = -1; 715 716 if (wpa_s->conf->ctrl_interface == NULL) 717 return priv; 718 719 #ifdef ANDROID 720 if (wpa_s->global->params.ctrl_interface) { 721 int same = 0; 722 723 if (wpa_s->global->params.ctrl_interface[0] == '/') { 724 if (os_strcmp(wpa_s->global->params.ctrl_interface, 725 wpa_s->conf->ctrl_interface) == 0) 726 same = 1; 727 } else if (os_strncmp(wpa_s->global->params.ctrl_interface, 728 "@android:", 9) == 0 || 729 os_strncmp(wpa_s->global->params.ctrl_interface, 730 "@abstract:", 10) == 0) { 731 char *pos; 732 733 /* 734 * Currently, Android uses @android:wpa_* as the naming 735 * convention for the global ctrl interface. This logic 736 * needs to be revisited if the above naming convention 737 * is modified. 738 */ 739 pos = os_strchr(wpa_s->global->params.ctrl_interface, 740 '_'); 741 if (pos && 742 os_strcmp(pos + 1, 743 wpa_s->conf->ctrl_interface) == 0) 744 same = 1; 745 } 746 747 if (same) { 748 /* 749 * The invalid configuration combination might be 750 * possible to hit in an Android OTA upgrade case, so 751 * instead of refusing to start the wpa_supplicant 752 * process, do not open the per-interface ctrl_iface 753 * and continue with the global control interface that 754 * was set from the command line since the Wi-Fi 755 * framework will use it for operations. 756 */ 757 wpa_printf(MSG_ERROR, 758 "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface", 759 wpa_s->global->params.ctrl_interface, 760 wpa_s->conf->ctrl_interface); 761 return priv; 762 } 763 } 764 #endif /* ANDROID */ 765 766 if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) { 767 os_free(priv); 768 return NULL; 769 } 770 771 return priv; 772 } 773 774 775 static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s, 776 struct ctrl_iface_priv *priv) 777 { 778 int res; 779 780 if (priv->sock <= 0) 781 return -1; 782 783 /* 784 * On Android, the control socket being used may be the socket 785 * that is created when wpa_supplicant is started as a /init.*.rc 786 * service. Such a socket is maintained as a key-value pair in 787 * Android's environment. Closing this control socket would leave us 788 * in a bad state with an invalid socket descriptor. 789 */ 790 if (priv->android_control_socket) 791 return priv->sock; 792 793 eloop_unregister_read_sock(priv->sock); 794 close(priv->sock); 795 priv->sock = -1; 796 res = wpas_ctrl_iface_open_sock(wpa_s, priv); 797 if (res < 0) 798 return -1; 799 return priv->sock; 800 } 801 802 803 static void 804 wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global, 805 struct wpa_supplicant *wpa_s) 806 { 807 struct ctrl_iface_global_priv *gpriv; 808 struct ctrl_iface_msg *msg, *prev_msg; 809 unsigned int count = 0; 810 811 if (!global || !global->ctrl_iface) 812 return; 813 814 gpriv = global->ctrl_iface; 815 dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue, 816 struct ctrl_iface_msg, list) { 817 if (msg->wpa_s == wpa_s) { 818 count++; 819 dl_list_del(&msg->list); 820 os_free(msg); 821 } 822 } 823 824 if (count) { 825 wpa_printf(MSG_DEBUG, 826 "CTRL: Dropped %u pending message(s) for interface that is being removed", 827 count); 828 } 829 } 830 831 832 void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s, 833 struct ctrl_iface_priv *priv) 834 { 835 struct wpa_ctrl_dst *dst, *prev; 836 struct ctrl_iface_msg *msg, *prev_msg; 837 struct ctrl_iface_global_priv *gpriv; 838 839 if (!priv) { 840 /* Control interface has not yet been initialized, so there is 841 * nothing to deinitialize here. However, there might be a 842 * pending message for this interface, so get rid of any such 843 * entry before completing interface removal. */ 844 wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s); 845 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL); 846 return; 847 } 848 849 if (priv->sock > -1) { 850 char *fname; 851 char *buf, *dir = NULL; 852 eloop_unregister_read_sock(priv->sock); 853 if (!dl_list_empty(&priv->ctrl_dst)) { 854 /* 855 * Wait before closing the control socket if 856 * there are any attached monitors in order to allow 857 * them to receive any pending messages. 858 */ 859 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " 860 "monitors to receive messages"); 861 os_sleep(0, 100000); 862 } 863 close(priv->sock); 864 priv->sock = -1; 865 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); 866 if (fname) { 867 unlink(fname); 868 os_free(fname); 869 } 870 871 if (priv->wpa_s->conf->ctrl_interface == NULL) 872 goto free_dst; 873 buf = os_strdup(priv->wpa_s->conf->ctrl_interface); 874 if (buf == NULL) 875 goto free_dst; 876 if (os_strncmp(buf, "DIR=", 4) == 0) { 877 char *gid_str; 878 dir = buf + 4; 879 gid_str = os_strstr(dir, " GROUP="); 880 if (gid_str) 881 *gid_str = '\0'; 882 } else 883 dir = buf; 884 885 if (rmdir(dir) < 0) { 886 if (errno == ENOTEMPTY) { 887 wpa_printf(MSG_DEBUG, "Control interface " 888 "directory not empty - leaving it " 889 "behind"); 890 } else { 891 wpa_printf(MSG_ERROR, 892 "rmdir[ctrl_interface=%s]: %s", 893 dir, strerror(errno)); 894 } 895 } 896 os_free(buf); 897 } 898 899 free_dst: 900 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 901 list) { 902 dl_list_del(&dst->list); 903 os_free(dst); 904 } 905 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue, 906 struct ctrl_iface_msg, list) { 907 dl_list_del(&msg->list); 908 os_free(msg); 909 } 910 gpriv = priv->wpa_s->global->ctrl_iface; 911 if (gpriv) { 912 dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue, 913 struct ctrl_iface_msg, list) { 914 if (msg->wpa_s == priv->wpa_s) { 915 dl_list_del(&msg->list); 916 os_free(msg); 917 } 918 } 919 } 920 wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s); 921 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL); 922 os_free(priv); 923 } 924 925 926 /** 927 * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors 928 * @ifname: Interface name for global control socket or %NULL 929 * @sock: Local socket fd 930 * @ctrl_dst: List of attached listeners 931 * @level: Priority level of the message 932 * @buf: Message data 933 * @len: Message length 934 * 935 * Send a packet to all monitor programs attached to the control interface. 936 */ 937 static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s, 938 const char *ifname, int sock, 939 struct dl_list *ctrl_dst, 940 int level, const char *buf, 941 size_t len, 942 struct ctrl_iface_priv *priv, 943 struct ctrl_iface_global_priv *gp) 944 { 945 struct wpa_ctrl_dst *dst, *next; 946 char levelstr[10]; 947 int idx, res; 948 struct msghdr msg; 949 struct iovec io[5]; 950 951 if (sock < 0 || dl_list_empty(ctrl_dst)) 952 return; 953 954 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 955 if (os_snprintf_error(sizeof(levelstr), res)) 956 return; 957 idx = 0; 958 if (ifname) { 959 io[idx].iov_base = "IFNAME="; 960 io[idx].iov_len = 7; 961 idx++; 962 io[idx].iov_base = (char *) ifname; 963 io[idx].iov_len = os_strlen(ifname); 964 idx++; 965 io[idx].iov_base = " "; 966 io[idx].iov_len = 1; 967 idx++; 968 } 969 io[idx].iov_base = levelstr; 970 io[idx].iov_len = os_strlen(levelstr); 971 idx++; 972 io[idx].iov_base = (char *) buf; 973 io[idx].iov_len = len; 974 idx++; 975 os_memset(&msg, 0, sizeof(msg)); 976 msg.msg_iov = io; 977 msg.msg_iovlen = idx; 978 979 dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) { 980 int _errno; 981 char txt[200]; 982 983 if (level < dst->debug_level) 984 continue; 985 986 msg.msg_name = (void *) &dst->addr; 987 msg.msg_namelen = dst->addrlen; 988 wpas_ctrl_sock_debug("ctrl_sock-sendmsg", sock, buf, len); 989 if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) { 990 sockaddr_print(MSG_MSGDUMP, 991 "CTRL_IFACE monitor sent successfully to", 992 &dst->addr, dst->addrlen); 993 dst->errors = 0; 994 continue; 995 } 996 997 _errno = errno; 998 os_snprintf(txt, sizeof(txt), "CTRL_IFACE monitor: %d (%s) for", 999 _errno, strerror(_errno)); 1000 sockaddr_print(MSG_DEBUG, txt, &dst->addr, dst->addrlen); 1001 dst->errors++; 1002 1003 if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) { 1004 sockaddr_print(MSG_INFO, "CTRL_IFACE: Detach monitor that cannot receive messages:", 1005 &dst->addr, dst->addrlen); 1006 wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr, 1007 dst->addrlen); 1008 } 1009 1010 if (_errno == ENOBUFS || _errno == EAGAIN) { 1011 /* 1012 * The socket send buffer could be full. This may happen 1013 * if client programs are not receiving their pending 1014 * messages. Close and reopen the socket as a workaround 1015 * to avoid getting stuck being unable to send any new 1016 * responses. 1017 */ 1018 if (priv) 1019 sock = wpas_ctrl_iface_reinit(wpa_s, priv); 1020 else if (gp) 1021 sock = wpas_ctrl_iface_global_reinit( 1022 wpa_s->global, gp); 1023 else 1024 break; 1025 if (sock < 0) { 1026 wpa_dbg(wpa_s, MSG_DEBUG, 1027 "Failed to reinitialize ctrl_iface socket"); 1028 break; 1029 } 1030 } 1031 } 1032 } 1033 1034 1035 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 1036 { 1037 char buf[256]; 1038 int res; 1039 struct sockaddr_storage from; 1040 socklen_t fromlen = sizeof(from); 1041 1042 if (priv->sock == -1) 1043 return; 1044 1045 for (;;) { 1046 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " 1047 "attach", priv->wpa_s->ifname); 1048 eloop_wait_for_read_sock(priv->sock); 1049 1050 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, 1051 (struct sockaddr *) &from, &fromlen); 1052 if (res < 0) { 1053 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 1054 strerror(errno)); 1055 continue; 1056 } 1057 buf[res] = '\0'; 1058 1059 if (os_strcmp(buf, "ATTACH") == 0) { 1060 /* handle ATTACH signal of first monitor interface */ 1061 if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, 1062 &from, fromlen, 1063 0)) { 1064 if (sendto(priv->sock, "OK\n", 3, 0, 1065 (struct sockaddr *) &from, fromlen) < 1066 0) { 1067 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1068 strerror(errno)); 1069 } 1070 /* OK to continue */ 1071 return; 1072 } else { 1073 if (sendto(priv->sock, "FAIL\n", 5, 0, 1074 (struct sockaddr *) &from, fromlen) < 1075 0) { 1076 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1077 strerror(errno)); 1078 } 1079 } 1080 } else { 1081 /* return FAIL for all other signals */ 1082 if (sendto(priv->sock, "FAIL\n", 5, 0, 1083 (struct sockaddr *) &from, fromlen) < 0) { 1084 wpa_printf(MSG_DEBUG, 1085 "ctrl_iface sendto failed: %s", 1086 strerror(errno)); 1087 } 1088 } 1089 } 1090 } 1091 1092 1093 /* Global ctrl_iface */ 1094 1095 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, 1096 void *sock_ctx) 1097 { 1098 struct wpa_global *global = eloop_ctx; 1099 struct ctrl_iface_global_priv *priv = sock_ctx; 1100 char *buf; 1101 int res; 1102 struct sockaddr_storage from; 1103 socklen_t fromlen = sizeof(from); 1104 char *reply = NULL, *reply_buf = NULL; 1105 size_t reply_len; 1106 1107 buf = os_malloc(CTRL_IFACE_MAX_LEN + 1); 1108 if (!buf) 1109 return; 1110 res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0, 1111 (struct sockaddr *) &from, &fromlen); 1112 if (res < 0) { 1113 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 1114 strerror(errno)); 1115 os_free(buf); 1116 return; 1117 } 1118 if ((size_t) res > CTRL_IFACE_MAX_LEN) { 1119 wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated"); 1120 os_free(buf); 1121 return; 1122 } 1123 buf[res] = '\0'; 1124 1125 if (os_strcmp(buf, "ATTACH") == 0) { 1126 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 1127 fromlen, 1)) 1128 reply_len = 1; 1129 else 1130 reply_len = 2; 1131 } else if (os_strcmp(buf, "DETACH") == 0) { 1132 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 1133 fromlen)) 1134 reply_len = 1; 1135 else 1136 reply_len = 2; 1137 } else { 1138 reply_buf = wpa_supplicant_global_ctrl_iface_process( 1139 global, buf, &reply_len); 1140 reply = reply_buf; 1141 1142 /* 1143 * There could be some password/key material in the command, so 1144 * clear the buffer explicitly now that it is not needed 1145 * anymore. 1146 */ 1147 os_memset(buf, 0, res); 1148 } 1149 1150 if (!reply && reply_len == 1) { 1151 reply = "FAIL\n"; 1152 reply_len = 5; 1153 } else if (!reply && reply_len == 2) { 1154 reply = "OK\n"; 1155 reply_len = 3; 1156 } 1157 1158 if (reply) { 1159 wpas_ctrl_sock_debug("global_ctrl_sock-sendto", 1160 sock, reply, reply_len); 1161 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 1162 fromlen) < 0) { 1163 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s", 1164 strerror(errno)); 1165 } 1166 } 1167 os_free(reply_buf); 1168 os_free(buf); 1169 } 1170 1171 1172 static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global, 1173 struct ctrl_iface_global_priv *priv) 1174 { 1175 struct sockaddr_un addr; 1176 const char *ctrl = global->params.ctrl_interface; 1177 int flags; 1178 1179 wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl); 1180 1181 #ifdef ANDROID 1182 if (os_strncmp(ctrl, "@android:", 9) == 0) { 1183 priv->sock = android_get_control_socket(ctrl + 9); 1184 if (priv->sock < 0) { 1185 wpa_printf(MSG_ERROR, "Failed to open Android control " 1186 "socket '%s'", ctrl + 9); 1187 goto fail; 1188 } 1189 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'", 1190 ctrl + 9); 1191 priv->android_control_socket = 1; 1192 goto havesock; 1193 } 1194 1195 if (os_strncmp(ctrl, "@abstract:", 10) != 0) { 1196 /* 1197 * Backwards compatibility - try to open an Android control 1198 * socket and if that fails, assume this was a UNIX domain 1199 * socket instead. 1200 */ 1201 priv->sock = android_get_control_socket(ctrl); 1202 if (priv->sock >= 0) { 1203 wpa_printf(MSG_DEBUG, 1204 "Using Android control socket '%s'", 1205 ctrl); 1206 priv->android_control_socket = 1; 1207 goto havesock; 1208 } 1209 } 1210 #endif /* ANDROID */ 1211 1212 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 1213 if (priv->sock < 0) { 1214 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 1215 goto fail; 1216 } 1217 1218 os_memset(&addr, 0, sizeof(addr)); 1219 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 1220 addr.sun_len = sizeof(addr); 1221 #endif /* __FreeBSD__ */ 1222 addr.sun_family = AF_UNIX; 1223 1224 if (os_strncmp(ctrl, "@abstract:", 10) == 0) { 1225 addr.sun_path[0] = '\0'; 1226 os_strlcpy(addr.sun_path + 1, ctrl + 10, 1227 sizeof(addr.sun_path) - 1); 1228 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 1229 0) { 1230 wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: " 1231 "bind(PF_UNIX;%s) failed: %s", 1232 ctrl, strerror(errno)); 1233 goto fail; 1234 } 1235 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'", 1236 ctrl + 10); 1237 goto havesock; 1238 } 1239 1240 os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path)); 1241 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 1242 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s", 1243 ctrl, strerror(errno)); 1244 if (connect(priv->sock, (struct sockaddr *) &addr, 1245 sizeof(addr)) < 0) { 1246 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 1247 " allow connections - assuming it was left" 1248 "over from forced program termination"); 1249 if (unlink(ctrl) < 0) { 1250 wpa_printf(MSG_ERROR, 1251 "Could not unlink existing ctrl_iface socket '%s': %s", 1252 ctrl, strerror(errno)); 1253 goto fail; 1254 } 1255 if (bind(priv->sock, (struct sockaddr *) &addr, 1256 sizeof(addr)) < 0) { 1257 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s", 1258 ctrl, strerror(errno)); 1259 goto fail; 1260 } 1261 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 1262 "ctrl_iface socket '%s'", 1263 ctrl); 1264 } else { 1265 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 1266 "be in use - cannot override it"); 1267 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 1268 "not used anymore", 1269 ctrl); 1270 goto fail; 1271 } 1272 } 1273 1274 wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl); 1275 1276 if (global->params.ctrl_interface_group) { 1277 char *gid_str = global->params.ctrl_interface_group; 1278 gid_t gid = 0; 1279 struct group *grp; 1280 char *endp; 1281 1282 grp = getgrnam(gid_str); 1283 if (grp) { 1284 gid = grp->gr_gid; 1285 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 1286 " (from group name '%s')", 1287 (int) gid, gid_str); 1288 } else { 1289 /* Group name not found - try to parse this as gid */ 1290 gid = strtol(gid_str, &endp, 10); 1291 if (*gid_str == '\0' || *endp != '\0') { 1292 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 1293 "'%s'", gid_str); 1294 goto fail; 1295 } 1296 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 1297 (int) gid); 1298 } 1299 if (lchown(ctrl, -1, gid) < 0) { 1300 wpa_printf(MSG_ERROR, 1301 "lchown[global_ctrl_interface=%s,gid=%d]: %s", 1302 ctrl, (int) gid, strerror(errno)); 1303 goto fail; 1304 } 1305 1306 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) { 1307 wpa_printf(MSG_ERROR, 1308 "chmod[global_ctrl_interface=%s]: %s", 1309 ctrl, strerror(errno)); 1310 goto fail; 1311 } 1312 } else { 1313 if (chmod(ctrl, S_IRWXU) < 0) { 1314 wpa_printf(MSG_DEBUG, 1315 "chmod[global_ctrl_interface=%s](S_IRWXU): %s", 1316 ctrl, strerror(errno)); 1317 /* continue anyway since group change was not required 1318 */ 1319 } 1320 } 1321 1322 havesock: 1323 1324 /* 1325 * Make socket non-blocking so that we don't hang forever if 1326 * target dies unexpectedly. 1327 */ 1328 flags = fcntl(priv->sock, F_GETFL); 1329 if (flags >= 0) { 1330 flags |= O_NONBLOCK; 1331 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 1332 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 1333 strerror(errno)); 1334 /* Not fatal, continue on.*/ 1335 } 1336 } 1337 1338 eloop_register_read_sock(priv->sock, 1339 wpa_supplicant_global_ctrl_iface_receive, 1340 global, priv); 1341 1342 return 0; 1343 1344 fail: 1345 if (priv->sock >= 0) { 1346 close(priv->sock); 1347 priv->sock = -1; 1348 } 1349 return -1; 1350 } 1351 1352 1353 struct ctrl_iface_global_priv * 1354 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 1355 { 1356 struct ctrl_iface_global_priv *priv; 1357 1358 priv = os_zalloc(sizeof(*priv)); 1359 if (priv == NULL) 1360 return NULL; 1361 dl_list_init(&priv->ctrl_dst); 1362 dl_list_init(&priv->msg_queue); 1363 priv->global = global; 1364 priv->sock = -1; 1365 1366 if (global->params.ctrl_interface == NULL) 1367 return priv; 1368 1369 if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) { 1370 os_free(priv); 1371 return NULL; 1372 } 1373 1374 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 1375 1376 return priv; 1377 } 1378 1379 1380 static int wpas_ctrl_iface_global_reinit(struct wpa_global *global, 1381 struct ctrl_iface_global_priv *priv) 1382 { 1383 int res; 1384 1385 if (priv->sock <= 0) 1386 return -1; 1387 1388 /* 1389 * On Android, the control socket being used may be the socket 1390 * that is created when wpa_supplicant is started as a /init.*.rc 1391 * service. Such a socket is maintained as a key-value pair in 1392 * Android's environment. Closing this control socket would leave us 1393 * in a bad state with an invalid socket descriptor. 1394 */ 1395 if (priv->android_control_socket) 1396 return priv->sock; 1397 1398 eloop_unregister_read_sock(priv->sock); 1399 close(priv->sock); 1400 priv->sock = -1; 1401 res = wpas_global_ctrl_iface_open_sock(global, priv); 1402 if (res < 0) 1403 return -1; 1404 return priv->sock; 1405 } 1406 1407 1408 void 1409 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 1410 { 1411 struct wpa_ctrl_dst *dst, *prev; 1412 struct ctrl_iface_msg *msg, *prev_msg; 1413 1414 if (priv->sock >= 0) { 1415 eloop_unregister_read_sock(priv->sock); 1416 close(priv->sock); 1417 } 1418 if (priv->global->params.ctrl_interface) 1419 unlink(priv->global->params.ctrl_interface); 1420 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 1421 list) { 1422 dl_list_del(&dst->list); 1423 os_free(dst); 1424 } 1425 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue, 1426 struct ctrl_iface_msg, list) { 1427 dl_list_del(&msg->list); 1428 os_free(msg); 1429 } 1430 os_free(priv); 1431 } 1432