1 /* 2 * WPA Supplicant / privileged helper program 3 * Copyright (c) 2007-2009, 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 #ifdef __linux__ 11 #include <fcntl.h> 12 #endif /* __linux__ */ 13 #include <sys/un.h> 14 #include <sys/stat.h> 15 16 #include "common.h" 17 #include "eloop.h" 18 #include "common/version.h" 19 #include "drivers/driver.h" 20 #include "l2_packet/l2_packet.h" 21 #include "common/privsep_commands.h" 22 #include "common/ieee802_11_defs.h" 23 24 25 struct wpa_priv_interface { 26 struct wpa_priv_interface *next; 27 char *driver_name; 28 char *ifname; 29 char *sock_name; 30 int fd; 31 32 void *ctx; 33 34 const struct wpa_driver_ops *driver; 35 void *drv_priv; 36 void *drv_global_priv; 37 struct sockaddr_un drv_addr; 38 int wpas_registered; 39 40 /* TODO: add support for multiple l2 connections */ 41 struct l2_packet_data *l2; 42 struct sockaddr_un l2_addr; 43 }; 44 45 struct wpa_priv_global { 46 struct wpa_priv_interface *interfaces; 47 }; 48 49 50 static void wpa_priv_cmd_register(struct wpa_priv_interface *iface, 51 struct sockaddr_un *from) 52 { 53 if (iface->drv_priv) { 54 wpa_printf(MSG_DEBUG, "Cleaning up forgotten driver instance"); 55 if (iface->driver->deinit) 56 iface->driver->deinit(iface->drv_priv); 57 iface->drv_priv = NULL; 58 if (iface->drv_global_priv) { 59 iface->driver->global_deinit(iface->drv_global_priv); 60 iface->drv_global_priv = NULL; 61 } 62 iface->wpas_registered = 0; 63 } 64 65 if (iface->l2) { 66 wpa_printf(MSG_DEBUG, "Cleaning up forgotten l2_packet " 67 "instance"); 68 l2_packet_deinit(iface->l2); 69 iface->l2 = NULL; 70 } 71 72 if (iface->driver->init2) { 73 if (iface->driver->global_init) { 74 iface->drv_global_priv = 75 iface->driver->global_init(iface->ctx); 76 if (!iface->drv_global_priv) { 77 wpa_printf(MSG_INFO, 78 "Failed to initialize driver global context"); 79 return; 80 } 81 } else { 82 iface->drv_global_priv = NULL; 83 } 84 iface->drv_priv = iface->driver->init2(iface, iface->ifname, 85 iface->drv_global_priv); 86 } else if (iface->driver->init) { 87 iface->drv_priv = iface->driver->init(iface, iface->ifname); 88 } else { 89 return; 90 } 91 if (iface->drv_priv == NULL) { 92 wpa_printf(MSG_DEBUG, "Failed to initialize driver wrapper"); 93 return; 94 } 95 96 wpa_printf(MSG_DEBUG, "Driver wrapper '%s' initialized for interface " 97 "'%s'", iface->driver_name, iface->ifname); 98 99 os_memcpy(&iface->drv_addr, from, sizeof(iface->drv_addr)); 100 iface->wpas_registered = 1; 101 102 if (iface->driver->set_param && 103 iface->driver->set_param(iface->drv_priv, NULL) < 0) { 104 wpa_printf(MSG_ERROR, "Driver interface rejected param"); 105 } 106 } 107 108 109 static void wpa_priv_cmd_unregister(struct wpa_priv_interface *iface, 110 struct sockaddr_un *from) 111 { 112 if (iface->drv_priv) { 113 if (iface->driver->deinit) 114 iface->driver->deinit(iface->drv_priv); 115 iface->drv_priv = NULL; 116 if (iface->drv_global_priv) { 117 iface->driver->global_deinit(iface->drv_global_priv); 118 iface->drv_global_priv = NULL; 119 } 120 iface->wpas_registered = 0; 121 } 122 } 123 124 125 static void wpa_priv_cmd_scan(struct wpa_priv_interface *iface, 126 char *buf, size_t len) 127 { 128 struct wpa_driver_scan_params params; 129 130 if (iface->drv_priv == NULL) 131 return; 132 133 os_memset(¶ms, 0, sizeof(params)); 134 if (len) { 135 params.ssids[0].ssid = (u8 *) buf; 136 params.ssids[0].ssid_len = len; 137 params.num_ssids = 1; 138 } 139 140 if (iface->driver->scan2) 141 iface->driver->scan2(iface->drv_priv, ¶ms); 142 } 143 144 145 static void wpa_priv_get_scan_results2(struct wpa_priv_interface *iface, 146 struct sockaddr_un *from) 147 { 148 struct wpa_scan_results *res; 149 u8 *buf = NULL, *pos, *end; 150 int val; 151 size_t i; 152 153 res = iface->driver->get_scan_results2(iface->drv_priv); 154 if (res == NULL) 155 goto fail; 156 157 buf = os_malloc(60000); 158 if (buf == NULL) 159 goto fail; 160 pos = buf; 161 end = buf + 60000; 162 val = res->num; 163 os_memcpy(pos, &val, sizeof(int)); 164 pos += sizeof(int); 165 166 for (i = 0; i < res->num; i++) { 167 struct wpa_scan_res *r = res->res[i]; 168 val = sizeof(*r) + r->ie_len; 169 if (end - pos < (int) sizeof(int) + val) 170 break; 171 os_memcpy(pos, &val, sizeof(int)); 172 pos += sizeof(int); 173 os_memcpy(pos, r, val); 174 pos += val; 175 } 176 177 sendto(iface->fd, buf, pos - buf, 0, (struct sockaddr *) from, 178 sizeof(*from)); 179 180 os_free(buf); 181 wpa_scan_results_free(res); 182 return; 183 184 fail: 185 os_free(buf); 186 wpa_scan_results_free(res); 187 sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); 188 } 189 190 191 static void wpa_priv_cmd_get_scan_results(struct wpa_priv_interface *iface, 192 struct sockaddr_un *from) 193 { 194 if (iface->drv_priv == NULL) 195 return; 196 197 if (iface->driver->get_scan_results2) 198 wpa_priv_get_scan_results2(iface, from); 199 else 200 sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, 201 sizeof(*from)); 202 } 203 204 205 static void wpa_priv_cmd_authenticate(struct wpa_priv_interface *iface, 206 void *buf, size_t len) 207 { 208 struct wpa_driver_auth_params params; 209 struct privsep_cmd_authenticate *auth; 210 int res, i; 211 212 if (iface->drv_priv == NULL || iface->driver->authenticate == NULL) 213 return; 214 215 if (len < sizeof(*auth)) { 216 wpa_printf(MSG_DEBUG, "Invalid authentication request"); 217 return; 218 } 219 220 auth = buf; 221 if (sizeof(*auth) + auth->ie_len + auth->sae_data_len > len) { 222 wpa_printf(MSG_DEBUG, "Authentication request overflow"); 223 return; 224 } 225 226 os_memset(¶ms, 0, sizeof(params)); 227 params.freq = auth->freq; 228 params.bssid = auth->bssid; 229 params.ssid = auth->ssid; 230 if (auth->ssid_len > SSID_MAX_LEN) 231 return; 232 params.ssid_len = auth->ssid_len; 233 params.auth_alg = auth->auth_alg; 234 for (i = 0; i < 4; i++) { 235 if (auth->wep_key_len[i]) { 236 params.wep_key[i] = auth->wep_key[i]; 237 params.wep_key_len[i] = auth->wep_key_len[i]; 238 } 239 } 240 params.wep_tx_keyidx = auth->wep_tx_keyidx; 241 params.local_state_change = auth->local_state_change; 242 params.p2p = auth->p2p; 243 if (auth->ie_len) { 244 params.ie = (u8 *) (auth + 1); 245 params.ie_len = auth->ie_len; 246 } 247 if (auth->sae_data_len) { 248 params.sae_data = ((u8 *) (auth + 1)) + auth->ie_len; 249 params.sae_data_len = auth->sae_data_len; 250 } 251 252 res = iface->driver->authenticate(iface->drv_priv, ¶ms); 253 wpa_printf(MSG_DEBUG, "drv->authenticate: res=%d", res); 254 } 255 256 257 static void wpa_priv_cmd_associate(struct wpa_priv_interface *iface, 258 void *buf, size_t len) 259 { 260 struct wpa_driver_associate_params params; 261 struct privsep_cmd_associate *assoc; 262 u8 *bssid; 263 int res; 264 265 if (iface->drv_priv == NULL || iface->driver->associate == NULL) 266 return; 267 268 if (len < sizeof(*assoc)) { 269 wpa_printf(MSG_DEBUG, "Invalid association request"); 270 return; 271 } 272 273 assoc = buf; 274 if (sizeof(*assoc) + assoc->wpa_ie_len > len) { 275 wpa_printf(MSG_DEBUG, "Association request overflow"); 276 return; 277 } 278 279 os_memset(¶ms, 0, sizeof(params)); 280 bssid = assoc->bssid; 281 if (bssid[0] | bssid[1] | bssid[2] | bssid[3] | bssid[4] | bssid[5]) 282 params.bssid = bssid; 283 params.ssid = assoc->ssid; 284 if (assoc->ssid_len > SSID_MAX_LEN) 285 return; 286 params.ssid_len = assoc->ssid_len; 287 params.freq.mode = assoc->hwmode; 288 params.freq.freq = assoc->freq; 289 params.freq.channel = assoc->channel; 290 if (assoc->wpa_ie_len) { 291 params.wpa_ie = (u8 *) (assoc + 1); 292 params.wpa_ie_len = assoc->wpa_ie_len; 293 } 294 params.pairwise_suite = assoc->pairwise_suite; 295 params.group_suite = assoc->group_suite; 296 params.key_mgmt_suite = assoc->key_mgmt_suite; 297 params.auth_alg = assoc->auth_alg; 298 params.mode = assoc->mode; 299 300 res = iface->driver->associate(iface->drv_priv, ¶ms); 301 wpa_printf(MSG_DEBUG, "drv->associate: res=%d", res); 302 } 303 304 305 static void wpa_priv_cmd_get_bssid(struct wpa_priv_interface *iface, 306 struct sockaddr_un *from) 307 { 308 u8 bssid[ETH_ALEN]; 309 310 if (iface->drv_priv == NULL) 311 goto fail; 312 313 if (iface->driver->get_bssid == NULL || 314 iface->driver->get_bssid(iface->drv_priv, bssid) < 0) 315 goto fail; 316 317 sendto(iface->fd, bssid, ETH_ALEN, 0, (struct sockaddr *) from, 318 sizeof(*from)); 319 return; 320 321 fail: 322 sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); 323 } 324 325 326 static void wpa_priv_cmd_get_ssid(struct wpa_priv_interface *iface, 327 struct sockaddr_un *from) 328 { 329 u8 ssid[sizeof(int) + SSID_MAX_LEN]; 330 int res; 331 332 if (iface->drv_priv == NULL) 333 goto fail; 334 335 if (iface->driver->get_ssid == NULL) 336 goto fail; 337 338 res = iface->driver->get_ssid(iface->drv_priv, &ssid[sizeof(int)]); 339 if (res < 0 || res > SSID_MAX_LEN) 340 goto fail; 341 os_memcpy(ssid, &res, sizeof(int)); 342 343 sendto(iface->fd, ssid, sizeof(ssid), 0, (struct sockaddr *) from, 344 sizeof(*from)); 345 return; 346 347 fail: 348 sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); 349 } 350 351 352 static void wpa_priv_cmd_set_key(struct wpa_priv_interface *iface, 353 void *buf, size_t len) 354 { 355 struct privsep_cmd_set_key *params; 356 int res; 357 358 if (iface->drv_priv == NULL || iface->driver->set_key == NULL) 359 return; 360 361 if (len != sizeof(*params)) { 362 wpa_printf(MSG_DEBUG, "Invalid set_key request"); 363 return; 364 } 365 366 params = buf; 367 368 res = iface->driver->set_key(iface->ifname, iface->drv_priv, 369 params->alg, 370 params->addr, params->key_idx, 371 params->set_tx, 372 params->seq_len ? params->seq : NULL, 373 params->seq_len, 374 params->key_len ? params->key : NULL, 375 params->key_len); 376 wpa_printf(MSG_DEBUG, "drv->set_key: res=%d", res); 377 } 378 379 380 static void wpa_priv_cmd_get_capa(struct wpa_priv_interface *iface, 381 struct sockaddr_un *from) 382 { 383 struct wpa_driver_capa capa; 384 385 if (iface->drv_priv == NULL) 386 goto fail; 387 388 if (iface->driver->get_capa == NULL || 389 iface->driver->get_capa(iface->drv_priv, &capa) < 0) 390 goto fail; 391 392 /* For now, no support for passing extended_capa pointers */ 393 capa.extended_capa = NULL; 394 capa.extended_capa_mask = NULL; 395 capa.extended_capa_len = 0; 396 sendto(iface->fd, &capa, sizeof(capa), 0, (struct sockaddr *) from, 397 sizeof(*from)); 398 return; 399 400 fail: 401 sendto(iface->fd, "", 0, 0, (struct sockaddr *) from, sizeof(*from)); 402 } 403 404 405 static void wpa_priv_l2_rx(void *ctx, const u8 *src_addr, const u8 *buf, 406 size_t len) 407 { 408 struct wpa_priv_interface *iface = ctx; 409 struct msghdr msg; 410 struct iovec io[2]; 411 412 io[0].iov_base = (u8 *) src_addr; 413 io[0].iov_len = ETH_ALEN; 414 io[1].iov_base = (u8 *) buf; 415 io[1].iov_len = len; 416 417 os_memset(&msg, 0, sizeof(msg)); 418 msg.msg_iov = io; 419 msg.msg_iovlen = 2; 420 msg.msg_name = &iface->l2_addr; 421 msg.msg_namelen = sizeof(iface->l2_addr); 422 423 if (sendmsg(iface->fd, &msg, 0) < 0) { 424 wpa_printf(MSG_ERROR, "sendmsg(l2 rx): %s", strerror(errno)); 425 } 426 } 427 428 429 static void wpa_priv_cmd_l2_register(struct wpa_priv_interface *iface, 430 struct sockaddr_un *from, 431 void *buf, size_t len) 432 { 433 int *reg_cmd = buf; 434 u8 own_addr[ETH_ALEN]; 435 int res; 436 u16 proto; 437 438 if (len != 2 * sizeof(int)) { 439 wpa_printf(MSG_DEBUG, "Invalid l2_register length %lu", 440 (unsigned long) len); 441 return; 442 } 443 444 proto = reg_cmd[0]; 445 if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH && 446 proto != ETH_P_80211_ENCAP) { 447 wpa_printf(MSG_DEBUG, "Refused l2_packet connection for " 448 "ethertype 0x%x", proto); 449 return; 450 } 451 452 if (iface->l2) { 453 wpa_printf(MSG_DEBUG, "Cleaning up forgotten l2_packet " 454 "instance"); 455 l2_packet_deinit(iface->l2); 456 iface->l2 = NULL; 457 } 458 459 os_memcpy(&iface->l2_addr, from, sizeof(iface->l2_addr)); 460 461 iface->l2 = l2_packet_init(iface->ifname, NULL, proto, 462 wpa_priv_l2_rx, iface, reg_cmd[1]); 463 if (iface->l2 == NULL) { 464 wpa_printf(MSG_DEBUG, "Failed to initialize l2_packet " 465 "instance for protocol %d", proto); 466 return; 467 } 468 469 if (l2_packet_get_own_addr(iface->l2, own_addr) < 0) { 470 wpa_printf(MSG_DEBUG, "Failed to get own address from " 471 "l2_packet"); 472 l2_packet_deinit(iface->l2); 473 iface->l2 = NULL; 474 return; 475 } 476 477 res = sendto(iface->fd, own_addr, ETH_ALEN, 0, 478 (struct sockaddr *) from, sizeof(*from)); 479 wpa_printf(MSG_DEBUG, "L2 registration: res=%d", res); 480 } 481 482 483 static void wpa_priv_cmd_l2_unregister(struct wpa_priv_interface *iface, 484 struct sockaddr_un *from) 485 { 486 if (iface->l2) { 487 l2_packet_deinit(iface->l2); 488 iface->l2 = NULL; 489 } 490 } 491 492 493 static void wpa_priv_cmd_l2_notify_auth_start(struct wpa_priv_interface *iface, 494 struct sockaddr_un *from) 495 { 496 if (iface->l2) 497 l2_packet_notify_auth_start(iface->l2); 498 } 499 500 501 static void wpa_priv_cmd_l2_send(struct wpa_priv_interface *iface, 502 struct sockaddr_un *from, 503 void *buf, size_t len) 504 { 505 u8 *dst_addr; 506 u16 proto; 507 int res; 508 509 if (iface->l2 == NULL) 510 return; 511 512 if (len < ETH_ALEN + 2) { 513 wpa_printf(MSG_DEBUG, "Too short L2 send packet (len=%lu)", 514 (unsigned long) len); 515 return; 516 } 517 518 dst_addr = buf; 519 os_memcpy(&proto, buf + ETH_ALEN, 2); 520 521 if (proto != ETH_P_EAPOL && proto != ETH_P_RSN_PREAUTH) { 522 wpa_printf(MSG_DEBUG, "Refused l2_packet send for ethertype " 523 "0x%x", proto); 524 return; 525 } 526 527 res = l2_packet_send(iface->l2, dst_addr, proto, buf + ETH_ALEN + 2, 528 len - ETH_ALEN - 2); 529 wpa_printf(MSG_DEBUG, "L2 send: res=%d", res); 530 } 531 532 533 static void wpa_priv_cmd_set_country(struct wpa_priv_interface *iface, 534 char *buf) 535 { 536 if (iface->drv_priv == NULL || iface->driver->set_country == NULL || 537 *buf == '\0') 538 return; 539 540 iface->driver->set_country(iface->drv_priv, buf); 541 } 542 543 544 static void wpa_priv_receive(int sock, void *eloop_ctx, void *sock_ctx) 545 { 546 struct wpa_priv_interface *iface = eloop_ctx; 547 char buf[2000], *pos; 548 void *cmd_buf; 549 size_t cmd_len; 550 int res, cmd; 551 struct sockaddr_un from; 552 socklen_t fromlen = sizeof(from); 553 554 res = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &from, 555 &fromlen); 556 if (res < 0) { 557 wpa_printf(MSG_ERROR, "recvfrom: %s", strerror(errno)); 558 return; 559 } 560 561 if (res < (int) sizeof(int)) { 562 wpa_printf(MSG_DEBUG, "Too short command (len=%d)", res); 563 return; 564 } 565 566 os_memcpy(&cmd, buf, sizeof(int)); 567 wpa_printf(MSG_DEBUG, "Command %d for interface %s", 568 cmd, iface->ifname); 569 cmd_buf = &buf[sizeof(int)]; 570 cmd_len = res - sizeof(int); 571 572 switch (cmd) { 573 case PRIVSEP_CMD_REGISTER: 574 wpa_priv_cmd_register(iface, &from); 575 break; 576 case PRIVSEP_CMD_UNREGISTER: 577 wpa_priv_cmd_unregister(iface, &from); 578 break; 579 case PRIVSEP_CMD_SCAN: 580 wpa_priv_cmd_scan(iface, cmd_buf, cmd_len); 581 break; 582 case PRIVSEP_CMD_GET_SCAN_RESULTS: 583 wpa_priv_cmd_get_scan_results(iface, &from); 584 break; 585 case PRIVSEP_CMD_ASSOCIATE: 586 wpa_priv_cmd_associate(iface, cmd_buf, cmd_len); 587 break; 588 case PRIVSEP_CMD_GET_BSSID: 589 wpa_priv_cmd_get_bssid(iface, &from); 590 break; 591 case PRIVSEP_CMD_GET_SSID: 592 wpa_priv_cmd_get_ssid(iface, &from); 593 break; 594 case PRIVSEP_CMD_SET_KEY: 595 wpa_priv_cmd_set_key(iface, cmd_buf, cmd_len); 596 break; 597 case PRIVSEP_CMD_GET_CAPA: 598 wpa_priv_cmd_get_capa(iface, &from); 599 break; 600 case PRIVSEP_CMD_L2_REGISTER: 601 wpa_priv_cmd_l2_register(iface, &from, cmd_buf, cmd_len); 602 break; 603 case PRIVSEP_CMD_L2_UNREGISTER: 604 wpa_priv_cmd_l2_unregister(iface, &from); 605 break; 606 case PRIVSEP_CMD_L2_NOTIFY_AUTH_START: 607 wpa_priv_cmd_l2_notify_auth_start(iface, &from); 608 break; 609 case PRIVSEP_CMD_L2_SEND: 610 wpa_priv_cmd_l2_send(iface, &from, cmd_buf, cmd_len); 611 break; 612 case PRIVSEP_CMD_SET_COUNTRY: 613 pos = cmd_buf; 614 if (pos + cmd_len >= buf + sizeof(buf)) 615 break; 616 pos[cmd_len] = '\0'; 617 wpa_priv_cmd_set_country(iface, pos); 618 break; 619 case PRIVSEP_CMD_AUTHENTICATE: 620 wpa_priv_cmd_authenticate(iface, cmd_buf, cmd_len); 621 break; 622 } 623 } 624 625 626 static void wpa_priv_interface_deinit(struct wpa_priv_interface *iface) 627 { 628 if (iface->drv_priv && iface->driver->deinit) 629 iface->driver->deinit(iface->drv_priv); 630 631 if (iface->fd >= 0) { 632 eloop_unregister_read_sock(iface->fd); 633 close(iface->fd); 634 unlink(iface->sock_name); 635 } 636 637 if (iface->l2) 638 l2_packet_deinit(iface->l2); 639 640 os_free(iface->ifname); 641 os_free(iface->driver_name); 642 os_free(iface->sock_name); 643 os_free(iface); 644 } 645 646 647 static struct wpa_priv_interface * 648 wpa_priv_interface_init(void *ctx, const char *dir, const char *params) 649 { 650 struct wpa_priv_interface *iface; 651 char *pos; 652 size_t len; 653 struct sockaddr_un addr; 654 int i; 655 656 pos = os_strchr(params, ':'); 657 if (pos == NULL) 658 return NULL; 659 660 iface = os_zalloc(sizeof(*iface)); 661 if (iface == NULL) 662 return NULL; 663 iface->fd = -1; 664 iface->ctx = ctx; 665 666 len = pos - params; 667 iface->driver_name = dup_binstr(params, len); 668 if (iface->driver_name == NULL) { 669 wpa_priv_interface_deinit(iface); 670 return NULL; 671 } 672 673 for (i = 0; wpa_drivers[i]; i++) { 674 if (os_strcmp(iface->driver_name, 675 wpa_drivers[i]->name) == 0) { 676 iface->driver = wpa_drivers[i]; 677 break; 678 } 679 } 680 if (iface->driver == NULL) { 681 wpa_printf(MSG_ERROR, "Unsupported driver '%s'", 682 iface->driver_name); 683 wpa_priv_interface_deinit(iface); 684 return NULL; 685 } 686 687 pos++; 688 iface->ifname = os_strdup(pos); 689 if (iface->ifname == NULL) { 690 wpa_priv_interface_deinit(iface); 691 return NULL; 692 } 693 694 len = os_strlen(dir) + 1 + os_strlen(iface->ifname); 695 iface->sock_name = os_malloc(len + 1); 696 if (iface->sock_name == NULL) { 697 wpa_priv_interface_deinit(iface); 698 return NULL; 699 } 700 701 os_snprintf(iface->sock_name, len + 1, "%s/%s", dir, iface->ifname); 702 if (os_strlen(iface->sock_name) >= sizeof(addr.sun_path)) { 703 wpa_priv_interface_deinit(iface); 704 return NULL; 705 } 706 707 iface->fd = socket(PF_UNIX, SOCK_DGRAM, 0); 708 if (iface->fd < 0) { 709 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno)); 710 wpa_priv_interface_deinit(iface); 711 return NULL; 712 } 713 714 os_memset(&addr, 0, sizeof(addr)); 715 addr.sun_family = AF_UNIX; 716 os_strlcpy(addr.sun_path, iface->sock_name, sizeof(addr.sun_path)); 717 718 if (bind(iface->fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { 719 wpa_printf(MSG_DEBUG, "bind(PF_UNIX) failed: %s", 720 strerror(errno)); 721 if (connect(iface->fd, (struct sockaddr *) &addr, 722 sizeof(addr)) < 0) { 723 wpa_printf(MSG_DEBUG, "Socket exists, but does not " 724 "allow connections - assuming it was " 725 "leftover from forced program termination"); 726 if (unlink(iface->sock_name) < 0) { 727 wpa_printf(MSG_ERROR, 728 "Could not unlink existing ctrl_iface socket '%s': %s", 729 iface->sock_name, strerror(errno)); 730 goto fail; 731 } 732 if (bind(iface->fd, (struct sockaddr *) &addr, 733 sizeof(addr)) < 0) { 734 wpa_printf(MSG_ERROR, 735 "wpa-priv-iface-init: bind(PF_UNIX): %s", 736 strerror(errno)); 737 goto fail; 738 } 739 wpa_printf(MSG_DEBUG, "Successfully replaced leftover " 740 "socket '%s'", iface->sock_name); 741 } else { 742 wpa_printf(MSG_INFO, "Socket exists and seems to be " 743 "in use - cannot override it"); 744 wpa_printf(MSG_INFO, "Delete '%s' manually if it is " 745 "not used anymore", iface->sock_name); 746 goto fail; 747 } 748 } 749 750 if (chmod(iface->sock_name, S_IRWXU | S_IRWXG | S_IRWXO) < 0) { 751 wpa_printf(MSG_ERROR, "chmod: %s", strerror(errno)); 752 goto fail; 753 } 754 755 eloop_register_read_sock(iface->fd, wpa_priv_receive, iface, NULL); 756 757 return iface; 758 759 fail: 760 wpa_priv_interface_deinit(iface); 761 return NULL; 762 } 763 764 765 static int wpa_priv_send_event(struct wpa_priv_interface *iface, int event, 766 const void *data, size_t data_len) 767 { 768 struct msghdr msg; 769 struct iovec io[2]; 770 771 io[0].iov_base = &event; 772 io[0].iov_len = sizeof(event); 773 io[1].iov_base = (u8 *) data; 774 io[1].iov_len = data_len; 775 776 os_memset(&msg, 0, sizeof(msg)); 777 msg.msg_iov = io; 778 msg.msg_iovlen = data ? 2 : 1; 779 msg.msg_name = &iface->drv_addr; 780 msg.msg_namelen = sizeof(iface->drv_addr); 781 782 if (sendmsg(iface->fd, &msg, 0) < 0) { 783 wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s", 784 strerror(errno)); 785 return -1; 786 } 787 788 return 0; 789 } 790 791 792 static void wpa_priv_send_auth(struct wpa_priv_interface *iface, 793 union wpa_event_data *data) 794 { 795 size_t buflen = sizeof(struct privsep_event_auth) + data->auth.ies_len; 796 struct privsep_event_auth *auth; 797 u8 *buf, *pos; 798 799 buf = os_malloc(buflen); 800 if (buf == NULL) 801 return; 802 803 auth = (struct privsep_event_auth *) buf; 804 pos = (u8 *) (auth + 1); 805 806 os_memcpy(auth->peer, data->auth.peer, ETH_ALEN); 807 os_memcpy(auth->bssid, data->auth.bssid, ETH_ALEN); 808 auth->auth_type = data->auth.auth_type; 809 auth->auth_transaction = data->auth.auth_transaction; 810 auth->status_code = data->auth.status_code; 811 if (data->auth.ies) { 812 os_memcpy(pos, data->auth.ies, data->auth.ies_len); 813 auth->ies_len = data->auth.ies_len; 814 } 815 816 wpa_priv_send_event(iface, PRIVSEP_EVENT_AUTH, buf, buflen); 817 818 os_free(buf); 819 } 820 821 822 static void wpa_priv_send_assoc(struct wpa_priv_interface *iface, int event, 823 union wpa_event_data *data) 824 { 825 size_t buflen = 3 * sizeof(int); 826 u8 *buf, *pos; 827 int len; 828 829 if (data) { 830 buflen += data->assoc_info.req_ies_len + 831 data->assoc_info.resp_ies_len + 832 data->assoc_info.beacon_ies_len; 833 } 834 835 buf = os_malloc(buflen); 836 if (buf == NULL) 837 return; 838 839 pos = buf; 840 841 if (data && data->assoc_info.req_ies) { 842 len = data->assoc_info.req_ies_len; 843 os_memcpy(pos, &len, sizeof(int)); 844 pos += sizeof(int); 845 os_memcpy(pos, data->assoc_info.req_ies, len); 846 pos += len; 847 } else { 848 len = 0; 849 os_memcpy(pos, &len, sizeof(int)); 850 pos += sizeof(int); 851 } 852 853 if (data && data->assoc_info.resp_ies) { 854 len = data->assoc_info.resp_ies_len; 855 os_memcpy(pos, &len, sizeof(int)); 856 pos += sizeof(int); 857 os_memcpy(pos, data->assoc_info.resp_ies, len); 858 pos += len; 859 } else { 860 len = 0; 861 os_memcpy(pos, &len, sizeof(int)); 862 pos += sizeof(int); 863 } 864 865 if (data && data->assoc_info.beacon_ies) { 866 len = data->assoc_info.beacon_ies_len; 867 os_memcpy(pos, &len, sizeof(int)); 868 pos += sizeof(int); 869 os_memcpy(pos, data->assoc_info.beacon_ies, len); 870 pos += len; 871 } else { 872 len = 0; 873 os_memcpy(pos, &len, sizeof(int)); 874 pos += sizeof(int); 875 } 876 877 wpa_priv_send_event(iface, event, buf, buflen); 878 879 os_free(buf); 880 } 881 882 883 static void wpa_priv_send_interface_status(struct wpa_priv_interface *iface, 884 union wpa_event_data *data) 885 { 886 int ievent; 887 size_t len, maxlen; 888 u8 *buf; 889 char *ifname; 890 891 if (data == NULL) 892 return; 893 894 ievent = data->interface_status.ievent; 895 maxlen = sizeof(data->interface_status.ifname); 896 ifname = data->interface_status.ifname; 897 for (len = 0; len < maxlen && ifname[len]; len++) 898 ; 899 900 buf = os_malloc(sizeof(int) + len); 901 if (buf == NULL) 902 return; 903 904 os_memcpy(buf, &ievent, sizeof(int)); 905 os_memcpy(buf + sizeof(int), ifname, len); 906 907 wpa_priv_send_event(iface, PRIVSEP_EVENT_INTERFACE_STATUS, 908 buf, sizeof(int) + len); 909 910 os_free(buf); 911 912 } 913 914 915 static void wpa_priv_send_ft_response(struct wpa_priv_interface *iface, 916 union wpa_event_data *data) 917 { 918 size_t len; 919 u8 *buf, *pos; 920 921 if (data == NULL || data->ft_ies.ies == NULL) 922 return; 923 924 len = sizeof(int) + ETH_ALEN + data->ft_ies.ies_len; 925 buf = os_malloc(len); 926 if (buf == NULL) 927 return; 928 929 pos = buf; 930 os_memcpy(pos, &data->ft_ies.ft_action, sizeof(int)); 931 pos += sizeof(int); 932 os_memcpy(pos, data->ft_ies.target_ap, ETH_ALEN); 933 pos += ETH_ALEN; 934 os_memcpy(pos, data->ft_ies.ies, data->ft_ies.ies_len); 935 936 wpa_priv_send_event(iface, PRIVSEP_EVENT_FT_RESPONSE, buf, len); 937 938 os_free(buf); 939 940 } 941 942 943 void wpa_supplicant_event(void *ctx, enum wpa_event_type event, 944 union wpa_event_data *data) 945 { 946 struct wpa_priv_interface *iface = ctx; 947 948 wpa_printf(MSG_DEBUG, "%s - event=%d", __func__, event); 949 950 if (!iface->wpas_registered) { 951 wpa_printf(MSG_DEBUG, "Driver event received, but " 952 "wpa_supplicant not registered"); 953 return; 954 } 955 956 switch (event) { 957 case EVENT_ASSOC: 958 wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOC, data); 959 break; 960 case EVENT_DISASSOC: 961 wpa_priv_send_event(iface, PRIVSEP_EVENT_DISASSOC, NULL, 0); 962 break; 963 case EVENT_ASSOCINFO: 964 if (data == NULL) 965 return; 966 wpa_priv_send_assoc(iface, PRIVSEP_EVENT_ASSOCINFO, data); 967 break; 968 case EVENT_MICHAEL_MIC_FAILURE: 969 if (data == NULL) 970 return; 971 wpa_priv_send_event(iface, PRIVSEP_EVENT_MICHAEL_MIC_FAILURE, 972 &data->michael_mic_failure.unicast, 973 sizeof(int)); 974 break; 975 case EVENT_SCAN_STARTED: 976 wpa_priv_send_event(iface, PRIVSEP_EVENT_SCAN_STARTED, NULL, 977 0); 978 break; 979 case EVENT_SCAN_RESULTS: 980 wpa_priv_send_event(iface, PRIVSEP_EVENT_SCAN_RESULTS, NULL, 981 0); 982 break; 983 case EVENT_INTERFACE_STATUS: 984 wpa_priv_send_interface_status(iface, data); 985 break; 986 case EVENT_PMKID_CANDIDATE: 987 if (data == NULL) 988 return; 989 wpa_priv_send_event(iface, PRIVSEP_EVENT_PMKID_CANDIDATE, 990 &data->pmkid_candidate, 991 sizeof(struct pmkid_candidate)); 992 break; 993 case EVENT_STKSTART: 994 if (data == NULL) 995 return; 996 wpa_priv_send_event(iface, PRIVSEP_EVENT_STKSTART, 997 &data->stkstart.peer, ETH_ALEN); 998 break; 999 case EVENT_FT_RESPONSE: 1000 wpa_priv_send_ft_response(iface, data); 1001 break; 1002 case EVENT_AUTH: 1003 wpa_priv_send_auth(iface, data); 1004 break; 1005 default: 1006 wpa_printf(MSG_DEBUG, "Unsupported driver event %d (%s) - TODO", 1007 event, event_to_string(event)); 1008 break; 1009 } 1010 } 1011 1012 1013 void wpa_supplicant_event_global(void *ctx, enum wpa_event_type event, 1014 union wpa_event_data *data) 1015 { 1016 struct wpa_priv_global *global = ctx; 1017 struct wpa_priv_interface *iface; 1018 1019 if (event != EVENT_INTERFACE_STATUS) 1020 return; 1021 1022 for (iface = global->interfaces; iface; iface = iface->next) { 1023 if (os_strcmp(iface->ifname, data->interface_status.ifname) == 1024 0) 1025 break; 1026 } 1027 if (iface && iface->driver->get_ifindex) { 1028 unsigned int ifindex; 1029 1030 ifindex = iface->driver->get_ifindex(iface->drv_priv); 1031 if (ifindex != data->interface_status.ifindex) { 1032 wpa_printf(MSG_DEBUG, 1033 "%s: interface status ifindex %d mismatch (%d)", 1034 iface->ifname, ifindex, 1035 data->interface_status.ifindex); 1036 return; 1037 } 1038 } 1039 if (iface) 1040 wpa_supplicant_event(iface, event, data); 1041 } 1042 1043 1044 void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr, 1045 const u8 *buf, size_t len) 1046 { 1047 struct wpa_priv_interface *iface = ctx; 1048 struct msghdr msg; 1049 struct iovec io[3]; 1050 int event = PRIVSEP_EVENT_RX_EAPOL; 1051 1052 wpa_printf(MSG_DEBUG, "RX EAPOL from driver"); 1053 io[0].iov_base = &event; 1054 io[0].iov_len = sizeof(event); 1055 io[1].iov_base = (u8 *) src_addr; 1056 io[1].iov_len = ETH_ALEN; 1057 io[2].iov_base = (u8 *) buf; 1058 io[2].iov_len = len; 1059 1060 os_memset(&msg, 0, sizeof(msg)); 1061 msg.msg_iov = io; 1062 msg.msg_iovlen = 3; 1063 msg.msg_name = &iface->drv_addr; 1064 msg.msg_namelen = sizeof(iface->drv_addr); 1065 1066 if (sendmsg(iface->fd, &msg, 0) < 0) 1067 wpa_printf(MSG_ERROR, "sendmsg(wpas_socket): %s", 1068 strerror(errno)); 1069 } 1070 1071 1072 static void wpa_priv_terminate(int sig, void *signal_ctx) 1073 { 1074 wpa_printf(MSG_DEBUG, "wpa_priv termination requested"); 1075 eloop_terminate(); 1076 } 1077 1078 1079 static void wpa_priv_fd_workaround(void) 1080 { 1081 #ifdef __linux__ 1082 int s, i; 1083 /* When started from pcmcia-cs scripts, wpa_supplicant might start with 1084 * fd 0, 1, and 2 closed. This will cause some issues because many 1085 * places in wpa_supplicant are still printing out to stdout. As a 1086 * workaround, make sure that fd's 0, 1, and 2 are not used for other 1087 * sockets. */ 1088 for (i = 0; i < 3; i++) { 1089 s = open("/dev/null", O_RDWR); 1090 if (s > 2) { 1091 close(s); 1092 break; 1093 } 1094 } 1095 #endif /* __linux__ */ 1096 } 1097 1098 1099 static void usage(void) 1100 { 1101 printf("wpa_priv v" VERSION_STR "\n" 1102 "Copyright (c) 2007-2016, Jouni Malinen <j@w1.fi> and " 1103 "contributors\n" 1104 "\n" 1105 "usage:\n" 1106 " wpa_priv [-Bdd] [-c<ctrl dir>] [-P<pid file>] " 1107 "<driver:ifname> \\\n" 1108 " [driver:ifname ...]\n"); 1109 } 1110 1111 1112 int main(int argc, char *argv[]) 1113 { 1114 int c, i; 1115 int ret = -1; 1116 char *pid_file = NULL; 1117 int daemonize = 0; 1118 char *ctrl_dir = "/var/run/wpa_priv"; 1119 struct wpa_priv_global global; 1120 struct wpa_priv_interface *iface; 1121 1122 if (os_program_init()) 1123 return -1; 1124 1125 wpa_priv_fd_workaround(); 1126 1127 os_memset(&global, 0, sizeof(global)); 1128 global.interfaces = NULL; 1129 1130 for (;;) { 1131 c = getopt(argc, argv, "Bc:dP:"); 1132 if (c < 0) 1133 break; 1134 switch (c) { 1135 case 'B': 1136 daemonize++; 1137 break; 1138 case 'c': 1139 ctrl_dir = optarg; 1140 break; 1141 case 'd': 1142 wpa_debug_level--; 1143 break; 1144 case 'P': 1145 pid_file = os_rel2abs_path(optarg); 1146 break; 1147 default: 1148 usage(); 1149 goto out2; 1150 } 1151 } 1152 1153 if (optind >= argc) { 1154 usage(); 1155 goto out2; 1156 } 1157 1158 wpa_printf(MSG_DEBUG, "wpa_priv control directory: '%s'", ctrl_dir); 1159 1160 if (eloop_init()) { 1161 wpa_printf(MSG_ERROR, "Failed to initialize event loop"); 1162 goto out2; 1163 } 1164 1165 for (i = optind; i < argc; i++) { 1166 wpa_printf(MSG_DEBUG, "Adding driver:interface %s", argv[i]); 1167 iface = wpa_priv_interface_init(&global, ctrl_dir, argv[i]); 1168 if (iface == NULL) 1169 goto out; 1170 iface->next = global.interfaces; 1171 global.interfaces = iface; 1172 } 1173 1174 if (daemonize && os_daemonize(pid_file) && eloop_sock_requeue()) 1175 goto out; 1176 1177 eloop_register_signal_terminate(wpa_priv_terminate, NULL); 1178 eloop_run(); 1179 1180 ret = 0; 1181 1182 out: 1183 iface = global.interfaces; 1184 while (iface) { 1185 struct wpa_priv_interface *prev = iface; 1186 iface = iface->next; 1187 wpa_priv_interface_deinit(prev); 1188 } 1189 1190 eloop_destroy(); 1191 1192 out2: 1193 if (daemonize) 1194 os_daemonize_terminate(pid_file); 1195 os_free(pid_file); 1196 os_program_deinit(); 1197 1198 return ret; 1199 } 1200