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