1 /* 2 * WPA Supplicant / UNIX domain socket -based control interface 3 * Copyright (c) 2004-2013, Jouni Malinen <j (at) 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 ANDROID 17 #include <cutils/sockets.h> 18 #endif /* ANDROID */ 19 20 #include "utils/common.h" 21 #include "utils/eloop.h" 22 #include "utils/list.h" 23 #include "eapol_supp/eapol_supp_sm.h" 24 #include "config.h" 25 #include "wpa_supplicant_i.h" 26 #include "ctrl_iface.h" 27 28 /* Per-interface ctrl_iface */ 29 30 /** 31 * struct wpa_ctrl_dst - Internal data structure of control interface monitors 32 * 33 * This structure is used to store information about registered control 34 * interface monitors into struct wpa_supplicant. This data is private to 35 * ctrl_iface_unix.c and should not be touched directly from other files. 36 */ 37 struct wpa_ctrl_dst { 38 struct dl_list list; 39 struct sockaddr_un addr; 40 socklen_t addrlen; 41 int debug_level; 42 int errors; 43 }; 44 45 46 struct ctrl_iface_priv { 47 struct wpa_supplicant *wpa_s; 48 int sock; 49 struct dl_list ctrl_dst; 50 }; 51 52 53 struct ctrl_iface_global_priv { 54 struct wpa_global *global; 55 int sock; 56 struct dl_list ctrl_dst; 57 }; 58 59 60 static void wpa_supplicant_ctrl_iface_send(const char *ifname, int sock, 61 struct dl_list *ctrl_dst, 62 int level, const char *buf, 63 size_t len); 64 65 66 static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst, 67 struct sockaddr_un *from, 68 socklen_t fromlen) 69 { 70 struct wpa_ctrl_dst *dst; 71 72 dst = os_zalloc(sizeof(*dst)); 73 if (dst == NULL) 74 return -1; 75 os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un)); 76 dst->addrlen = fromlen; 77 dst->debug_level = MSG_INFO; 78 dl_list_add(ctrl_dst, &dst->list); 79 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached", 80 (u8 *) from->sun_path, 81 fromlen - offsetof(struct sockaddr_un, sun_path)); 82 return 0; 83 } 84 85 86 static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst, 87 struct sockaddr_un *from, 88 socklen_t fromlen) 89 { 90 struct wpa_ctrl_dst *dst; 91 92 dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) { 93 if (fromlen == dst->addrlen && 94 os_memcmp(from->sun_path, dst->addr.sun_path, 95 fromlen - offsetof(struct sockaddr_un, sun_path)) 96 == 0) { 97 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached", 98 (u8 *) from->sun_path, 99 fromlen - 100 offsetof(struct sockaddr_un, sun_path)); 101 dl_list_del(&dst->list); 102 os_free(dst); 103 return 0; 104 } 105 } 106 return -1; 107 } 108 109 110 static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv, 111 struct sockaddr_un *from, 112 socklen_t fromlen, 113 char *level) 114 { 115 struct wpa_ctrl_dst *dst; 116 117 wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level); 118 119 dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) { 120 if (fromlen == dst->addrlen && 121 os_memcmp(from->sun_path, dst->addr.sun_path, 122 fromlen - offsetof(struct sockaddr_un, sun_path)) 123 == 0) { 124 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor " 125 "level", (u8 *) from->sun_path, 126 fromlen - 127 offsetof(struct sockaddr_un, sun_path)); 128 dst->debug_level = atoi(level); 129 return 0; 130 } 131 } 132 133 return -1; 134 } 135 136 137 static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, 138 void *sock_ctx) 139 { 140 struct wpa_supplicant *wpa_s = eloop_ctx; 141 struct ctrl_iface_priv *priv = sock_ctx; 142 char buf[4096]; 143 int res; 144 struct sockaddr_un from; 145 socklen_t fromlen = sizeof(from); 146 char *reply = NULL; 147 size_t reply_len = 0; 148 int new_attached = 0; 149 150 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 151 (struct sockaddr *) &from, &fromlen); 152 if (res < 0) { 153 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 154 strerror(errno)); 155 return; 156 } 157 buf[res] = '\0'; 158 159 if (os_strcmp(buf, "ATTACH") == 0) { 160 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 161 fromlen)) 162 reply_len = 1; 163 else { 164 new_attached = 1; 165 reply_len = 2; 166 } 167 } else if (os_strcmp(buf, "DETACH") == 0) { 168 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 169 fromlen)) 170 reply_len = 1; 171 else 172 reply_len = 2; 173 } else if (os_strncmp(buf, "LEVEL ", 6) == 0) { 174 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen, 175 buf + 6)) 176 reply_len = 1; 177 else 178 reply_len = 2; 179 } else { 180 reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf, 181 &reply_len); 182 } 183 184 if (reply) { 185 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 186 fromlen); 187 os_free(reply); 188 } else if (reply_len == 1) { 189 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 190 fromlen); 191 } else if (reply_len == 2) { 192 sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, 193 fromlen); 194 } 195 196 if (new_attached) 197 eapol_sm_notify_ctrl_attached(wpa_s->eapol); 198 } 199 200 201 static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s) 202 { 203 char *buf; 204 size_t len; 205 char *pbuf, *dir = NULL, *gid_str = NULL; 206 int res; 207 208 if (wpa_s->conf->ctrl_interface == NULL) 209 return NULL; 210 211 pbuf = os_strdup(wpa_s->conf->ctrl_interface); 212 if (pbuf == NULL) 213 return NULL; 214 if (os_strncmp(pbuf, "DIR=", 4) == 0) { 215 dir = pbuf + 4; 216 gid_str = os_strstr(dir, " GROUP="); 217 if (gid_str) { 218 *gid_str = '\0'; 219 gid_str += 7; 220 } 221 } else 222 dir = pbuf; 223 224 len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2; 225 buf = os_malloc(len); 226 if (buf == NULL) { 227 os_free(pbuf); 228 return NULL; 229 } 230 231 res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname); 232 if (res < 0 || (size_t) res >= len) { 233 os_free(pbuf); 234 os_free(buf); 235 return NULL; 236 } 237 #ifdef __CYGWIN__ 238 { 239 /* Windows/WinPcap uses interface names that are not suitable 240 * as a file name - convert invalid chars to underscores */ 241 char *pos = buf; 242 while (*pos) { 243 if (*pos == '\\') 244 *pos = '_'; 245 pos++; 246 } 247 } 248 #endif /* __CYGWIN__ */ 249 os_free(pbuf); 250 return buf; 251 } 252 253 254 static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level, int global, 255 const char *txt, size_t len) 256 { 257 struct wpa_supplicant *wpa_s = ctx; 258 259 if (wpa_s == NULL) 260 return; 261 262 if (global != 2 && wpa_s->global->ctrl_iface) { 263 struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface; 264 if (!dl_list_empty(&priv->ctrl_dst)) { 265 wpa_supplicant_ctrl_iface_send(global ? NULL : 266 wpa_s->ifname, 267 priv->sock, 268 &priv->ctrl_dst, 269 level, txt, len); 270 } 271 } 272 273 if (wpa_s->ctrl_iface == NULL) 274 return; 275 wpa_supplicant_ctrl_iface_send(NULL, wpa_s->ctrl_iface->sock, 276 &wpa_s->ctrl_iface->ctrl_dst, 277 level, txt, len); 278 } 279 280 281 struct ctrl_iface_priv * 282 wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s) 283 { 284 struct ctrl_iface_priv *priv; 285 struct sockaddr_un addr; 286 char *fname = NULL; 287 gid_t gid = 0; 288 int gid_set = 0; 289 char *buf, *dir = NULL, *gid_str = NULL; 290 struct group *grp; 291 char *endp; 292 int flags; 293 294 priv = os_zalloc(sizeof(*priv)); 295 if (priv == NULL) 296 return NULL; 297 dl_list_init(&priv->ctrl_dst); 298 priv->wpa_s = wpa_s; 299 priv->sock = -1; 300 301 if (wpa_s->conf->ctrl_interface == NULL) 302 return priv; 303 304 buf = os_strdup(wpa_s->conf->ctrl_interface); 305 if (buf == NULL) 306 goto fail; 307 #ifdef ANDROID 308 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s", 309 wpa_s->conf->ctrl_interface); 310 priv->sock = android_get_control_socket(addr.sun_path); 311 if (priv->sock >= 0) 312 goto havesock; 313 #endif /* ANDROID */ 314 if (os_strncmp(buf, "DIR=", 4) == 0) { 315 dir = buf + 4; 316 gid_str = os_strstr(dir, " GROUP="); 317 if (gid_str) { 318 *gid_str = '\0'; 319 gid_str += 7; 320 } 321 } else { 322 dir = buf; 323 gid_str = wpa_s->conf->ctrl_interface_group; 324 } 325 326 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) { 327 if (errno == EEXIST) { 328 wpa_printf(MSG_DEBUG, "Using existing control " 329 "interface directory."); 330 } else { 331 wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s", 332 dir, strerror(errno)); 333 goto fail; 334 } 335 } 336 337 #ifdef ANDROID 338 /* 339 * wpa_supplicant is started from /init.*.rc on Android and that seems 340 * to be using umask 0077 which would leave the control interface 341 * directory without group access. This breaks things since Wi-Fi 342 * framework assumes that this directory can be accessed by other 343 * applications in the wifi group. Fix this by adding group access even 344 * if umask value would prevent this. 345 */ 346 if (chmod(dir, S_IRWXU | S_IRWXG) < 0) { 347 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s", 348 strerror(errno)); 349 /* Try to continue anyway */ 350 } 351 #endif /* ANDROID */ 352 353 if (gid_str) { 354 grp = getgrnam(gid_str); 355 if (grp) { 356 gid = grp->gr_gid; 357 gid_set = 1; 358 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 359 " (from group name '%s')", 360 (int) gid, gid_str); 361 } else { 362 /* Group name not found - try to parse this as gid */ 363 gid = strtol(gid_str, &endp, 10); 364 if (*gid_str == '\0' || *endp != '\0') { 365 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 366 "'%s'", gid_str); 367 goto fail; 368 } 369 gid_set = 1; 370 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 371 (int) gid); 372 } 373 } 374 375 if (gid_set && chown(dir, -1, gid) < 0) { 376 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", 377 dir, (int) gid, strerror(errno)); 378 goto fail; 379 } 380 381 /* Make sure the group can enter and read the directory */ 382 if (gid_set && 383 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) { 384 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s", 385 strerror(errno)); 386 goto fail; 387 } 388 389 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >= 390 sizeof(addr.sun_path)) { 391 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded"); 392 goto fail; 393 } 394 395 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 396 if (priv->sock < 0) { 397 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 398 goto fail; 399 } 400 401 os_memset(&addr, 0, sizeof(addr)); 402 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 403 addr.sun_len = sizeof(addr); 404 #endif /* __FreeBSD__ */ 405 addr.sun_family = AF_UNIX; 406 fname = wpa_supplicant_ctrl_iface_path(wpa_s); 407 if (fname == NULL) 408 goto fail; 409 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path)); 410 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 411 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s", 412 strerror(errno)); 413 if (connect(priv->sock, (struct sockaddr *) &addr, 414 sizeof(addr)) < 0) { 415 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 416 " allow connections - assuming it was left" 417 "over from forced program termination"); 418 if (unlink(fname) < 0) { 419 wpa_printf(MSG_ERROR, 420 "Could not unlink existing ctrl_iface socket '%s': %s", 421 fname, strerror(errno)); 422 goto fail; 423 } 424 if (bind(priv->sock, (struct sockaddr *) &addr, 425 sizeof(addr)) < 0) { 426 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s", 427 strerror(errno)); 428 goto fail; 429 } 430 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 431 "ctrl_iface socket '%s'", fname); 432 } else { 433 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 434 "be in use - cannot override it"); 435 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 436 "not used anymore", fname); 437 os_free(fname); 438 fname = NULL; 439 goto fail; 440 } 441 } 442 443 if (gid_set && chown(fname, -1, gid) < 0) { 444 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s", 445 fname, (int) gid, strerror(errno)); 446 goto fail; 447 } 448 449 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) { 450 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s", 451 fname, strerror(errno)); 452 goto fail; 453 } 454 os_free(fname); 455 456 #ifdef ANDROID 457 havesock: 458 #endif /* ANDROID */ 459 460 /* 461 * Make socket non-blocking so that we don't hang forever if 462 * target dies unexpectedly. 463 */ 464 flags = fcntl(priv->sock, F_GETFL); 465 if (flags >= 0) { 466 flags |= O_NONBLOCK; 467 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 468 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 469 strerror(errno)); 470 /* Not fatal, continue on.*/ 471 } 472 } 473 474 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive, 475 wpa_s, priv); 476 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb); 477 478 os_free(buf); 479 return priv; 480 481 fail: 482 if (priv->sock >= 0) 483 close(priv->sock); 484 os_free(priv); 485 if (fname) { 486 unlink(fname); 487 os_free(fname); 488 } 489 os_free(buf); 490 return NULL; 491 } 492 493 494 void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv) 495 { 496 struct wpa_ctrl_dst *dst, *prev; 497 498 if (priv->sock > -1) { 499 char *fname; 500 char *buf, *dir = NULL, *gid_str = NULL; 501 eloop_unregister_read_sock(priv->sock); 502 if (!dl_list_empty(&priv->ctrl_dst)) { 503 /* 504 * Wait before closing the control socket if 505 * there are any attached monitors in order to allow 506 * them to receive any pending messages. 507 */ 508 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached " 509 "monitors to receive messages"); 510 os_sleep(0, 100000); 511 } 512 close(priv->sock); 513 priv->sock = -1; 514 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s); 515 if (fname) { 516 unlink(fname); 517 os_free(fname); 518 } 519 520 buf = os_strdup(priv->wpa_s->conf->ctrl_interface); 521 if (buf == NULL) 522 goto free_dst; 523 if (os_strncmp(buf, "DIR=", 4) == 0) { 524 dir = buf + 4; 525 gid_str = os_strstr(dir, " GROUP="); 526 if (gid_str) { 527 *gid_str = '\0'; 528 gid_str += 7; 529 } 530 } else 531 dir = buf; 532 533 if (rmdir(dir) < 0) { 534 if (errno == ENOTEMPTY) { 535 wpa_printf(MSG_DEBUG, "Control interface " 536 "directory not empty - leaving it " 537 "behind"); 538 } else { 539 wpa_printf(MSG_ERROR, 540 "rmdir[ctrl_interface=%s]: %s", 541 dir, strerror(errno)); 542 } 543 } 544 os_free(buf); 545 } 546 547 free_dst: 548 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 549 list) 550 os_free(dst); 551 os_free(priv); 552 } 553 554 555 /** 556 * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors 557 * @ifname: Interface name for global control socket or %NULL 558 * @sock: Local socket fd 559 * @ctrl_dst: List of attached listeners 560 * @level: Priority level of the message 561 * @buf: Message data 562 * @len: Message length 563 * 564 * Send a packet to all monitor programs attached to the control interface. 565 */ 566 static void wpa_supplicant_ctrl_iface_send(const char *ifname, int sock, 567 struct dl_list *ctrl_dst, 568 int level, const char *buf, 569 size_t len) 570 { 571 struct wpa_ctrl_dst *dst, *next; 572 char levelstr[10]; 573 int idx, res; 574 struct msghdr msg; 575 struct iovec io[5]; 576 577 if (sock < 0 || dl_list_empty(ctrl_dst)) 578 return; 579 580 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level); 581 if (res < 0 || (size_t) res >= sizeof(levelstr)) 582 return; 583 idx = 0; 584 if (ifname) { 585 io[idx].iov_base = "IFNAME="; 586 io[idx].iov_len = 7; 587 idx++; 588 io[idx].iov_base = (char *) ifname; 589 io[idx].iov_len = os_strlen(ifname); 590 idx++; 591 io[idx].iov_base = " "; 592 io[idx].iov_len = 1; 593 idx++; 594 } 595 io[idx].iov_base = levelstr; 596 io[idx].iov_len = os_strlen(levelstr); 597 idx++; 598 io[idx].iov_base = (char *) buf; 599 io[idx].iov_len = len; 600 idx++; 601 os_memset(&msg, 0, sizeof(msg)); 602 msg.msg_iov = io; 603 msg.msg_iovlen = idx; 604 605 idx = 0; 606 dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) { 607 if (level >= dst->debug_level) { 608 wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send", 609 (u8 *) dst->addr.sun_path, dst->addrlen - 610 offsetof(struct sockaddr_un, sun_path)); 611 msg.msg_name = (void *) &dst->addr; 612 msg.msg_namelen = dst->addrlen; 613 if (sendmsg(sock, &msg, MSG_DONTWAIT) < 0) { 614 int _errno = errno; 615 wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: " 616 "%d - %s", 617 idx, errno, strerror(errno)); 618 dst->errors++; 619 if (dst->errors > 1000 || 620 (_errno != ENOBUFS && dst->errors > 10) || 621 _errno == ENOENT) { 622 wpa_supplicant_ctrl_iface_detach( 623 ctrl_dst, &dst->addr, 624 dst->addrlen); 625 } 626 } else 627 dst->errors = 0; 628 } 629 idx++; 630 } 631 } 632 633 634 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv) 635 { 636 char buf[256]; 637 int res; 638 struct sockaddr_un from; 639 socklen_t fromlen = sizeof(from); 640 641 for (;;) { 642 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to " 643 "attach", priv->wpa_s->ifname); 644 eloop_wait_for_read_sock(priv->sock); 645 646 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0, 647 (struct sockaddr *) &from, &fromlen); 648 if (res < 0) { 649 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 650 strerror(errno)); 651 continue; 652 } 653 buf[res] = '\0'; 654 655 if (os_strcmp(buf, "ATTACH") == 0) { 656 /* handle ATTACH signal of first monitor interface */ 657 if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, 658 &from, fromlen)) { 659 sendto(priv->sock, "OK\n", 3, 0, 660 (struct sockaddr *) &from, fromlen); 661 /* OK to continue */ 662 return; 663 } else { 664 sendto(priv->sock, "FAIL\n", 5, 0, 665 (struct sockaddr *) &from, fromlen); 666 } 667 } else { 668 /* return FAIL for all other signals */ 669 sendto(priv->sock, "FAIL\n", 5, 0, 670 (struct sockaddr *) &from, fromlen); 671 } 672 } 673 } 674 675 676 /* Global ctrl_iface */ 677 678 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx, 679 void *sock_ctx) 680 { 681 struct wpa_global *global = eloop_ctx; 682 struct ctrl_iface_global_priv *priv = sock_ctx; 683 char buf[256]; 684 int res; 685 struct sockaddr_un from; 686 socklen_t fromlen = sizeof(from); 687 char *reply = NULL; 688 size_t reply_len; 689 690 res = recvfrom(sock, buf, sizeof(buf) - 1, 0, 691 (struct sockaddr *) &from, &fromlen); 692 if (res < 0) { 693 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s", 694 strerror(errno)); 695 return; 696 } 697 buf[res] = '\0'; 698 699 if (os_strcmp(buf, "ATTACH") == 0) { 700 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from, 701 fromlen)) 702 reply_len = 1; 703 else 704 reply_len = 2; 705 } else if (os_strcmp(buf, "DETACH") == 0) { 706 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from, 707 fromlen)) 708 reply_len = 1; 709 else 710 reply_len = 2; 711 } else { 712 reply = wpa_supplicant_global_ctrl_iface_process(global, buf, 713 &reply_len); 714 } 715 716 if (reply) { 717 sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from, 718 fromlen); 719 os_free(reply); 720 } else if (reply_len == 1) { 721 sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from, 722 fromlen); 723 } else if (reply_len == 2) { 724 sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from, fromlen); 725 } 726 } 727 728 729 struct ctrl_iface_global_priv * 730 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global) 731 { 732 struct ctrl_iface_global_priv *priv; 733 struct sockaddr_un addr; 734 const char *ctrl = global->params.ctrl_interface; 735 int flags; 736 737 priv = os_zalloc(sizeof(*priv)); 738 if (priv == NULL) 739 return NULL; 740 dl_list_init(&priv->ctrl_dst); 741 priv->global = global; 742 priv->sock = -1; 743 744 if (ctrl == NULL) 745 return priv; 746 747 wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl); 748 749 #ifdef ANDROID 750 if (os_strncmp(ctrl, "@android:", 9) == 0) { 751 priv->sock = android_get_control_socket(ctrl + 9); 752 if (priv->sock < 0) { 753 wpa_printf(MSG_ERROR, "Failed to open Android control " 754 "socket '%s'", ctrl + 9); 755 goto fail; 756 } 757 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'", 758 ctrl + 9); 759 goto havesock; 760 } 761 762 if (os_strncmp(ctrl, "@abstract:", 10) != 0) { 763 /* 764 * Backwards compatibility - try to open an Android control 765 * socket and if that fails, assume this was a UNIX domain 766 * socket instead. 767 */ 768 priv->sock = android_get_control_socket(ctrl); 769 if (priv->sock >= 0) { 770 wpa_printf(MSG_DEBUG, 771 "Using Android control socket '%s'", 772 ctrl); 773 goto havesock; 774 } 775 } 776 #endif /* ANDROID */ 777 778 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0); 779 if (priv->sock < 0) { 780 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 781 goto fail; 782 } 783 784 os_memset(&addr, 0, sizeof(addr)); 785 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) 786 addr.sun_len = sizeof(addr); 787 #endif /* __FreeBSD__ */ 788 addr.sun_family = AF_UNIX; 789 790 if (os_strncmp(ctrl, "@abstract:", 10) == 0) { 791 addr.sun_path[0] = '\0'; 792 os_strlcpy(addr.sun_path + 1, ctrl + 10, 793 sizeof(addr.sun_path) - 1); 794 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 795 0) { 796 wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: " 797 "bind(PF_UNIX;%s) failed: %s", 798 ctrl, strerror(errno)); 799 goto fail; 800 } 801 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'", 802 ctrl + 10); 803 goto havesock; 804 } 805 806 os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path)); 807 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 808 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s", 809 ctrl, strerror(errno)); 810 if (connect(priv->sock, (struct sockaddr *) &addr, 811 sizeof(addr)) < 0) { 812 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not" 813 " allow connections - assuming it was left" 814 "over from forced program termination"); 815 if (unlink(ctrl) < 0) { 816 wpa_printf(MSG_ERROR, 817 "Could not unlink existing ctrl_iface socket '%s': %s", 818 ctrl, strerror(errno)); 819 goto fail; 820 } 821 if (bind(priv->sock, (struct sockaddr *) &addr, 822 sizeof(addr)) < 0) { 823 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s", 824 ctrl, strerror(errno)); 825 goto fail; 826 } 827 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 828 "ctrl_iface socket '%s'", 829 ctrl); 830 } else { 831 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to " 832 "be in use - cannot override it"); 833 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 834 "not used anymore", 835 ctrl); 836 goto fail; 837 } 838 } 839 840 wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl); 841 842 if (global->params.ctrl_interface_group) { 843 char *gid_str = global->params.ctrl_interface_group; 844 gid_t gid = 0; 845 struct group *grp; 846 char *endp; 847 848 grp = getgrnam(gid_str); 849 if (grp) { 850 gid = grp->gr_gid; 851 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d" 852 " (from group name '%s')", 853 (int) gid, gid_str); 854 } else { 855 /* Group name not found - try to parse this as gid */ 856 gid = strtol(gid_str, &endp, 10); 857 if (*gid_str == '\0' || *endp != '\0') { 858 wpa_printf(MSG_ERROR, "CTRL: Invalid group " 859 "'%s'", gid_str); 860 goto fail; 861 } 862 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d", 863 (int) gid); 864 } 865 if (chown(ctrl, -1, gid) < 0) { 866 wpa_printf(MSG_ERROR, 867 "chown[global_ctrl_interface=%s,gid=%d]: %s", 868 ctrl, (int) gid, strerror(errno)); 869 goto fail; 870 } 871 872 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) { 873 wpa_printf(MSG_ERROR, 874 "chmod[global_ctrl_interface=%s]: %s", 875 ctrl, strerror(errno)); 876 goto fail; 877 } 878 } else { 879 chmod(ctrl, S_IRWXU); 880 } 881 882 havesock: 883 884 /* 885 * Make socket non-blocking so that we don't hang forever if 886 * target dies unexpectedly. 887 */ 888 flags = fcntl(priv->sock, F_GETFL); 889 if (flags >= 0) { 890 flags |= O_NONBLOCK; 891 if (fcntl(priv->sock, F_SETFL, flags) < 0) { 892 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s", 893 strerror(errno)); 894 /* Not fatal, continue on.*/ 895 } 896 } 897 898 eloop_register_read_sock(priv->sock, 899 wpa_supplicant_global_ctrl_iface_receive, 900 global, priv); 901 902 return priv; 903 904 fail: 905 if (priv->sock >= 0) 906 close(priv->sock); 907 os_free(priv); 908 return NULL; 909 } 910 911 912 void 913 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv) 914 { 915 struct wpa_ctrl_dst *dst, *prev; 916 917 if (priv->sock >= 0) { 918 eloop_unregister_read_sock(priv->sock); 919 close(priv->sock); 920 } 921 if (priv->global->params.ctrl_interface) 922 unlink(priv->global->params.ctrl_interface); 923 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst, 924 list) 925 os_free(dst); 926 os_free(priv); 927 } 928