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