00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016 #include <sys/un.h>
00017
00018 #include "common.h"
00019 #include "driver.h"
00020 #include "eloop.h"
00021 #include "common/privsep_commands.h"
00022
00023
00024 struct wpa_driver_privsep_data {
00025 void *ctx;
00026 u8 own_addr[ETH_ALEN];
00027 int priv_socket;
00028 char *own_socket_path;
00029 int cmd_socket;
00030 char *own_cmd_path;
00031 struct sockaddr_un priv_addr;
00032 char ifname[16];
00033 };
00034
00035
00036 static int wpa_priv_reg_cmd(struct wpa_driver_privsep_data *drv, int cmd)
00037 {
00038 int res;
00039
00040 res = sendto(drv->priv_socket, &cmd, sizeof(cmd), 0,
00041 (struct sockaddr *) &drv->priv_addr,
00042 sizeof(drv->priv_addr));
00043 if (res < 0)
00044 perror("sendto");
00045 return res < 0 ? -1 : 0;
00046 }
00047
00048
00049 static int wpa_priv_cmd(struct wpa_driver_privsep_data *drv, int cmd,
00050 const void *data, size_t data_len,
00051 void *reply, size_t *reply_len)
00052 {
00053 struct msghdr msg;
00054 struct iovec io[2];
00055
00056 io[0].iov_base = &cmd;
00057 io[0].iov_len = sizeof(cmd);
00058 io[1].iov_base = (u8 *) data;
00059 io[1].iov_len = data_len;
00060
00061 os_memset(&msg, 0, sizeof(msg));
00062 msg.msg_iov = io;
00063 msg.msg_iovlen = data ? 2 : 1;
00064 msg.msg_name = &drv->priv_addr;
00065 msg.msg_namelen = sizeof(drv->priv_addr);
00066
00067 if (sendmsg(drv->cmd_socket, &msg, 0) < 0) {
00068 perror("sendmsg(cmd_socket)");
00069 return -1;
00070 }
00071
00072 if (reply) {
00073 fd_set rfds;
00074 struct timeval tv;
00075 int res;
00076
00077 FD_ZERO(&rfds);
00078 FD_SET(drv->cmd_socket, &rfds);
00079 tv.tv_sec = 5;
00080 tv.tv_usec = 0;
00081 res = select(drv->cmd_socket + 1, &rfds, NULL, NULL, &tv);
00082 if (res < 0 && errno != EINTR) {
00083 perror("select");
00084 return -1;
00085 }
00086
00087 if (FD_ISSET(drv->cmd_socket, &rfds)) {
00088 res = recv(drv->cmd_socket, reply, *reply_len, 0);
00089 if (res < 0) {
00090 perror("recv");
00091 return -1;
00092 }
00093 *reply_len = res;
00094 } else {
00095 wpa_printf(MSG_DEBUG, "PRIVSEP: Timeout while waiting "
00096 "for reply (cmd=%d)", cmd);
00097 return -1;
00098 }
00099 }
00100
00101 return 0;
00102 }
00103
00104
00105 static int wpa_driver_privsep_scan(void *priv,
00106 struct wpa_driver_scan_params *params)
00107 {
00108 struct wpa_driver_privsep_data *drv = priv;
00109 const u8 *ssid = params->ssids[0].ssid;
00110 size_t ssid_len = params->ssids[0].ssid_len;
00111 wpa_printf(MSG_DEBUG, "%s: priv=%p", __func__, priv);
00112 return wpa_priv_cmd(drv, PRIVSEP_CMD_SCAN, ssid, ssid_len,
00113 NULL, NULL);
00114 }
00115
00116
00117 static struct wpa_scan_results *
00118 wpa_driver_privsep_get_scan_results2(void *priv)
00119 {
00120 struct wpa_driver_privsep_data *drv = priv;
00121 int res, num;
00122 u8 *buf, *pos, *end;
00123 size_t reply_len = 60000;
00124 struct wpa_scan_results *results;
00125 struct wpa_scan_res *r;
00126
00127 buf = os_malloc(reply_len);
00128 if (buf == NULL)
00129 return NULL;
00130 res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SCAN_RESULTS,
00131 NULL, 0, buf, &reply_len);
00132 if (res < 0) {
00133 os_free(buf);
00134 return NULL;
00135 }
00136
00137 wpa_printf(MSG_DEBUG, "privsep: Received %lu bytes of scan results",
00138 (unsigned long) reply_len);
00139 if (reply_len < sizeof(int)) {
00140 wpa_printf(MSG_DEBUG, "privsep: Invalid scan result len %lu",
00141 (unsigned long) reply_len);
00142 os_free(buf);
00143 return NULL;
00144 }
00145
00146 pos = buf;
00147 end = buf + reply_len;
00148 os_memcpy(&num, pos, sizeof(int));
00149 if (num < 0 || num > 1000) {
00150 os_free(buf);
00151 return NULL;
00152 }
00153 pos += sizeof(int);
00154
00155 results = os_zalloc(sizeof(*results));
00156 if (results == NULL) {
00157 os_free(buf);
00158 return NULL;
00159 }
00160
00161 results->res = os_zalloc(num * sizeof(struct wpa_scan_res *));
00162 if (results->res == NULL) {
00163 os_free(results);
00164 os_free(buf);
00165 return NULL;
00166 }
00167
00168 while (results->num < (size_t) num && pos + sizeof(int) < end) {
00169 int len;
00170 os_memcpy(&len, pos, sizeof(int));
00171 pos += sizeof(int);
00172 if (len < 0 || len > 10000 || pos + len > end)
00173 break;
00174
00175 r = os_malloc(len);
00176 if (r == NULL)
00177 break;
00178 os_memcpy(r, pos, len);
00179 pos += len;
00180 if (sizeof(*r) + r->ie_len > (size_t) len) {
00181 os_free(r);
00182 break;
00183 }
00184
00185 results->res[results->num++] = r;
00186 }
00187
00188 os_free(buf);
00189 return results;
00190 }
00191
00192
00193 static int wpa_driver_privsep_set_key(const char *ifname, void *priv,
00194 enum wpa_alg alg, const u8 *addr,
00195 int key_idx, int set_tx,
00196 const u8 *seq, size_t seq_len,
00197 const u8 *key, size_t key_len)
00198 {
00199 struct wpa_driver_privsep_data *drv = priv;
00200 struct privsep_cmd_set_key cmd;
00201
00202 wpa_printf(MSG_DEBUG, "%s: priv=%p alg=%d key_idx=%d set_tx=%d",
00203 __func__, priv, alg, key_idx, set_tx);
00204
00205 os_memset(&cmd, 0, sizeof(cmd));
00206 cmd.alg = alg;
00207 if (addr)
00208 os_memcpy(cmd.addr, addr, ETH_ALEN);
00209 else
00210 os_memset(cmd.addr, 0xff, ETH_ALEN);
00211 cmd.key_idx = key_idx;
00212 cmd.set_tx = set_tx;
00213 if (seq && seq_len > 0 && seq_len < sizeof(cmd.seq)) {
00214 os_memcpy(cmd.seq, seq, seq_len);
00215 cmd.seq_len = seq_len;
00216 }
00217 if (key && key_len > 0 && key_len < sizeof(cmd.key)) {
00218 os_memcpy(cmd.key, key, key_len);
00219 cmd.key_len = key_len;
00220 }
00221
00222 return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_KEY, &cmd, sizeof(cmd),
00223 NULL, NULL);
00224 }
00225
00226
00227 static int wpa_driver_privsep_associate(
00228 void *priv, struct wpa_driver_associate_params *params)
00229 {
00230 struct wpa_driver_privsep_data *drv = priv;
00231 struct privsep_cmd_associate *data;
00232 int res;
00233 size_t buflen;
00234
00235 wpa_printf(MSG_DEBUG, "%s: priv=%p freq=%d pairwise_suite=%d "
00236 "group_suite=%d key_mgmt_suite=%d auth_alg=%d mode=%d",
00237 __func__, priv, params->freq, params->pairwise_suite,
00238 params->group_suite, params->key_mgmt_suite,
00239 params->auth_alg, params->mode);
00240
00241 buflen = sizeof(*data) + params->wpa_ie_len;
00242 data = os_zalloc(buflen);
00243 if (data == NULL)
00244 return -1;
00245
00246 if (params->bssid)
00247 os_memcpy(data->bssid, params->bssid, ETH_ALEN);
00248 os_memcpy(data->ssid, params->ssid, params->ssid_len);
00249 data->ssid_len = params->ssid_len;
00250 data->freq = params->freq;
00251 data->pairwise_suite = params->pairwise_suite;
00252 data->group_suite = params->group_suite;
00253 data->key_mgmt_suite = params->key_mgmt_suite;
00254 data->auth_alg = params->auth_alg;
00255 data->mode = params->mode;
00256 data->wpa_ie_len = params->wpa_ie_len;
00257 if (params->wpa_ie)
00258 os_memcpy(data + 1, params->wpa_ie, params->wpa_ie_len);
00259
00260
00261 res = wpa_priv_cmd(drv, PRIVSEP_CMD_ASSOCIATE, data, buflen,
00262 NULL, NULL);
00263 os_free(data);
00264
00265 return res;
00266 }
00267
00268
00269 static int wpa_driver_privsep_get_bssid(void *priv, u8 *bssid)
00270 {
00271 struct wpa_driver_privsep_data *drv = priv;
00272 int res;
00273 size_t len = ETH_ALEN;
00274
00275 res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_BSSID, NULL, 0, bssid, &len);
00276 if (res < 0 || len != ETH_ALEN)
00277 return -1;
00278 return 0;
00279 }
00280
00281
00282 static int wpa_driver_privsep_get_ssid(void *priv, u8 *ssid)
00283 {
00284 struct wpa_driver_privsep_data *drv = priv;
00285 int res, ssid_len;
00286 u8 reply[sizeof(int) + 32];
00287 size_t len = sizeof(reply);
00288
00289 res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_SSID, NULL, 0, reply, &len);
00290 if (res < 0 || len < sizeof(int))
00291 return -1;
00292 os_memcpy(&ssid_len, reply, sizeof(int));
00293 if (ssid_len < 0 || ssid_len > 32 || sizeof(int) + ssid_len > len) {
00294 wpa_printf(MSG_DEBUG, "privsep: Invalid get SSID reply");
00295 return -1;
00296 }
00297 os_memcpy(ssid, &reply[sizeof(int)], ssid_len);
00298 return ssid_len;
00299 }
00300
00301
00302 static int wpa_driver_privsep_deauthenticate(void *priv, const u8 *addr,
00303 int reason_code)
00304 {
00305
00306 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
00307 __func__, MAC2STR(addr), reason_code);
00308 wpa_printf(MSG_DEBUG, "%s - TODO", __func__);
00309 return 0;
00310 }
00311
00312
00313 static int wpa_driver_privsep_disassociate(void *priv, const u8 *addr,
00314 int reason_code)
00315 {
00316
00317 wpa_printf(MSG_DEBUG, "%s addr=" MACSTR " reason_code=%d",
00318 __func__, MAC2STR(addr), reason_code);
00319 wpa_printf(MSG_DEBUG, "%s - TODO", __func__);
00320 return 0;
00321 }
00322
00323
00324 static void wpa_driver_privsep_event_assoc(void *ctx,
00325 enum wpa_event_type event,
00326 u8 *buf, size_t len)
00327 {
00328 union wpa_event_data data;
00329 int inc_data = 0;
00330 u8 *pos, *end;
00331 int ie_len;
00332
00333 os_memset(&data, 0, sizeof(data));
00334
00335 pos = buf;
00336 end = buf + len;
00337
00338 if (end - pos < (int) sizeof(int))
00339 return;
00340 os_memcpy(&ie_len, pos, sizeof(int));
00341 pos += sizeof(int);
00342 if (ie_len < 0 || ie_len > end - pos)
00343 return;
00344 if (ie_len) {
00345 data.assoc_info.req_ies = pos;
00346 data.assoc_info.req_ies_len = ie_len;
00347 pos += ie_len;
00348 inc_data = 1;
00349 }
00350
00351 wpa_supplicant_event(ctx, event, inc_data ? &data : NULL);
00352 }
00353
00354
00355 static void wpa_driver_privsep_event_interface_status(void *ctx, u8 *buf,
00356 size_t len)
00357 {
00358 union wpa_event_data data;
00359 int ievent;
00360
00361 if (len < sizeof(int) ||
00362 len - sizeof(int) > sizeof(data.interface_status.ifname))
00363 return;
00364
00365 os_memcpy(&ievent, buf, sizeof(int));
00366
00367 os_memset(&data, 0, sizeof(data));
00368 data.interface_status.ievent = ievent;
00369 os_memcpy(data.interface_status.ifname, buf + sizeof(int),
00370 len - sizeof(int));
00371 wpa_supplicant_event(ctx, EVENT_INTERFACE_STATUS, &data);
00372 }
00373
00374
00375 static void wpa_driver_privsep_event_michael_mic_failure(
00376 void *ctx, u8 *buf, size_t len)
00377 {
00378 union wpa_event_data data;
00379
00380 if (len != sizeof(int))
00381 return;
00382
00383 os_memset(&data, 0, sizeof(data));
00384 os_memcpy(&data.michael_mic_failure.unicast, buf, sizeof(int));
00385 wpa_supplicant_event(ctx, EVENT_MICHAEL_MIC_FAILURE, &data);
00386 }
00387
00388
00389 static void wpa_driver_privsep_event_pmkid_candidate(void *ctx, u8 *buf,
00390 size_t len)
00391 {
00392 union wpa_event_data data;
00393
00394 if (len != sizeof(struct pmkid_candidate))
00395 return;
00396
00397 os_memset(&data, 0, sizeof(data));
00398 os_memcpy(&data.pmkid_candidate, buf, len);
00399 wpa_supplicant_event(ctx, EVENT_PMKID_CANDIDATE, &data);
00400 }
00401
00402
00403 static void wpa_driver_privsep_event_stkstart(void *ctx, u8 *buf, size_t len)
00404 {
00405 union wpa_event_data data;
00406
00407 if (len != ETH_ALEN)
00408 return;
00409
00410 os_memset(&data, 0, sizeof(data));
00411 os_memcpy(data.stkstart.peer, buf, ETH_ALEN);
00412 wpa_supplicant_event(ctx, EVENT_STKSTART, &data);
00413 }
00414
00415
00416 static void wpa_driver_privsep_event_ft_response(void *ctx, u8 *buf,
00417 size_t len)
00418 {
00419 union wpa_event_data data;
00420
00421 if (len < sizeof(int) + ETH_ALEN)
00422 return;
00423
00424 os_memset(&data, 0, sizeof(data));
00425 os_memcpy(&data.ft_ies.ft_action, buf, sizeof(int));
00426 os_memcpy(data.ft_ies.target_ap, buf + sizeof(int), ETH_ALEN);
00427 data.ft_ies.ies = buf + sizeof(int) + ETH_ALEN;
00428 data.ft_ies.ies_len = len - sizeof(int) - ETH_ALEN;
00429 wpa_supplicant_event(ctx, EVENT_FT_RESPONSE, &data);
00430 }
00431
00432
00433 static void wpa_driver_privsep_event_rx_eapol(void *ctx, u8 *buf, size_t len)
00434 {
00435 if (len < ETH_ALEN)
00436 return;
00437 drv_event_eapol_rx(ctx, buf, buf + ETH_ALEN, len - ETH_ALEN);
00438 }
00439
00440
00441 static void wpa_driver_privsep_receive(int sock, void *eloop_ctx,
00442 void *sock_ctx)
00443 {
00444 struct wpa_driver_privsep_data *drv = eloop_ctx;
00445 u8 *buf, *event_buf;
00446 size_t event_len;
00447 int res, event;
00448 enum privsep_event e;
00449 struct sockaddr_un from;
00450 socklen_t fromlen = sizeof(from);
00451 const size_t buflen = 2000;
00452
00453 buf = os_malloc(buflen);
00454 if (buf == NULL)
00455 return;
00456 res = recvfrom(sock, buf, buflen, 0,
00457 (struct sockaddr *) &from, &fromlen);
00458 if (res < 0) {
00459 perror("recvfrom(priv_socket)");
00460 os_free(buf);
00461 return;
00462 }
00463
00464 wpa_printf(MSG_DEBUG, "privsep_driver: received %u bytes", res);
00465
00466 if (res < (int) sizeof(int)) {
00467 wpa_printf(MSG_DEBUG, "Too short event message (len=%d)", res);
00468 return;
00469 }
00470
00471 os_memcpy(&event, buf, sizeof(int));
00472 event_buf = &buf[sizeof(int)];
00473 event_len = res - sizeof(int);
00474 wpa_printf(MSG_DEBUG, "privsep: Event %d received (len=%lu)",
00475 event, (unsigned long) event_len);
00476
00477 e = event;
00478 switch (e) {
00479 case PRIVSEP_EVENT_SCAN_RESULTS:
00480 wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, NULL);
00481 break;
00482 case PRIVSEP_EVENT_ASSOC:
00483 wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOC,
00484 event_buf, event_len);
00485 break;
00486 case PRIVSEP_EVENT_DISASSOC:
00487 wpa_supplicant_event(drv->ctx, EVENT_DISASSOC, NULL);
00488 break;
00489 case PRIVSEP_EVENT_ASSOCINFO:
00490 wpa_driver_privsep_event_assoc(drv->ctx, EVENT_ASSOCINFO,
00491 event_buf, event_len);
00492 break;
00493 case PRIVSEP_EVENT_MICHAEL_MIC_FAILURE:
00494 wpa_driver_privsep_event_michael_mic_failure(
00495 drv->ctx, event_buf, event_len);
00496 break;
00497 case PRIVSEP_EVENT_INTERFACE_STATUS:
00498 wpa_driver_privsep_event_interface_status(drv->ctx, event_buf,
00499 event_len);
00500 break;
00501 case PRIVSEP_EVENT_PMKID_CANDIDATE:
00502 wpa_driver_privsep_event_pmkid_candidate(drv->ctx, event_buf,
00503 event_len);
00504 break;
00505 case PRIVSEP_EVENT_STKSTART:
00506 wpa_driver_privsep_event_stkstart(drv->ctx, event_buf,
00507 event_len);
00508 break;
00509 case PRIVSEP_EVENT_FT_RESPONSE:
00510 wpa_driver_privsep_event_ft_response(drv->ctx, event_buf,
00511 event_len);
00512 break;
00513 case PRIVSEP_EVENT_RX_EAPOL:
00514 wpa_driver_privsep_event_rx_eapol(drv->ctx, event_buf,
00515 event_len);
00516 break;
00517 }
00518
00519 os_free(buf);
00520 }
00521
00522
00523 static void * wpa_driver_privsep_init(void *ctx, const char *ifname)
00524 {
00525 struct wpa_driver_privsep_data *drv;
00526
00527 drv = os_zalloc(sizeof(*drv));
00528 if (drv == NULL)
00529 return NULL;
00530 drv->ctx = ctx;
00531 drv->priv_socket = -1;
00532 drv->cmd_socket = -1;
00533 os_strlcpy(drv->ifname, ifname, sizeof(drv->ifname));
00534
00535 return drv;
00536 }
00537
00538
00539 static void wpa_driver_privsep_deinit(void *priv)
00540 {
00541 struct wpa_driver_privsep_data *drv = priv;
00542
00543 if (drv->priv_socket >= 0) {
00544 wpa_priv_reg_cmd(drv, PRIVSEP_CMD_UNREGISTER);
00545 eloop_unregister_read_sock(drv->priv_socket);
00546 close(drv->priv_socket);
00547 }
00548
00549 if (drv->own_socket_path) {
00550 unlink(drv->own_socket_path);
00551 os_free(drv->own_socket_path);
00552 }
00553
00554 if (drv->cmd_socket >= 0) {
00555 eloop_unregister_read_sock(drv->cmd_socket);
00556 close(drv->cmd_socket);
00557 }
00558
00559 if (drv->own_cmd_path) {
00560 unlink(drv->own_cmd_path);
00561 os_free(drv->own_cmd_path);
00562 }
00563
00564 os_free(drv);
00565 }
00566
00567
00568 static int wpa_driver_privsep_set_param(void *priv, const char *param)
00569 {
00570 struct wpa_driver_privsep_data *drv = priv;
00571 const char *pos;
00572 char *own_dir, *priv_dir;
00573 static unsigned int counter = 0;
00574 size_t len;
00575 struct sockaddr_un addr;
00576
00577 wpa_printf(MSG_DEBUG, "%s: param='%s'", __func__, param);
00578 if (param == NULL)
00579 pos = NULL;
00580 else
00581 pos = os_strstr(param, "own_dir=");
00582 if (pos) {
00583 char *end;
00584 own_dir = os_strdup(pos + 8);
00585 if (own_dir == NULL)
00586 return -1;
00587 end = os_strchr(own_dir, ' ');
00588 if (end)
00589 *end = '\0';
00590 } else {
00591 own_dir = os_strdup("/tmp");
00592 if (own_dir == NULL)
00593 return -1;
00594 }
00595
00596 if (param == NULL)
00597 pos = NULL;
00598 else
00599 pos = os_strstr(param, "priv_dir=");
00600 if (pos) {
00601 char *end;
00602 priv_dir = os_strdup(pos + 9);
00603 if (priv_dir == NULL) {
00604 os_free(own_dir);
00605 return -1;
00606 }
00607 end = os_strchr(priv_dir, ' ');
00608 if (end)
00609 *end = '\0';
00610 } else {
00611 priv_dir = os_strdup("/var/run/wpa_priv");
00612 if (priv_dir == NULL) {
00613 os_free(own_dir);
00614 return -1;
00615 }
00616 }
00617
00618 len = os_strlen(own_dir) + 50;
00619 drv->own_socket_path = os_malloc(len);
00620 if (drv->own_socket_path == NULL) {
00621 os_free(priv_dir);
00622 os_free(own_dir);
00623 return -1;
00624 }
00625 os_snprintf(drv->own_socket_path, len, "%s/wpa_privsep-%d-%d",
00626 own_dir, getpid(), counter++);
00627
00628 len = os_strlen(own_dir) + 50;
00629 drv->own_cmd_path = os_malloc(len);
00630 if (drv->own_cmd_path == NULL) {
00631 os_free(drv->own_socket_path);
00632 drv->own_socket_path = NULL;
00633 os_free(priv_dir);
00634 os_free(own_dir);
00635 return -1;
00636 }
00637 os_snprintf(drv->own_cmd_path, len, "%s/wpa_privsep-%d-%d",
00638 own_dir, getpid(), counter++);
00639
00640 os_free(own_dir);
00641
00642 drv->priv_addr.sun_family = AF_UNIX;
00643 os_snprintf(drv->priv_addr.sun_path, sizeof(drv->priv_addr.sun_path),
00644 "%s/%s", priv_dir, drv->ifname);
00645 os_free(priv_dir);
00646
00647 drv->priv_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
00648 if (drv->priv_socket < 0) {
00649 perror("socket(PF_UNIX)");
00650 os_free(drv->own_socket_path);
00651 drv->own_socket_path = NULL;
00652 return -1;
00653 }
00654
00655 os_memset(&addr, 0, sizeof(addr));
00656 addr.sun_family = AF_UNIX;
00657 os_strlcpy(addr.sun_path, drv->own_socket_path, sizeof(addr.sun_path));
00658 if (bind(drv->priv_socket, (struct sockaddr *) &addr, sizeof(addr)) <
00659 0) {
00660 perror("bind(PF_UNIX)");
00661 close(drv->priv_socket);
00662 drv->priv_socket = -1;
00663 unlink(drv->own_socket_path);
00664 os_free(drv->own_socket_path);
00665 drv->own_socket_path = NULL;
00666 return -1;
00667 }
00668
00669 eloop_register_read_sock(drv->priv_socket, wpa_driver_privsep_receive,
00670 drv, NULL);
00671
00672 drv->cmd_socket = socket(PF_UNIX, SOCK_DGRAM, 0);
00673 if (drv->cmd_socket < 0) {
00674 perror("socket(PF_UNIX)");
00675 os_free(drv->own_cmd_path);
00676 drv->own_cmd_path = NULL;
00677 return -1;
00678 }
00679
00680 os_memset(&addr, 0, sizeof(addr));
00681 addr.sun_family = AF_UNIX;
00682 os_strlcpy(addr.sun_path, drv->own_cmd_path, sizeof(addr.sun_path));
00683 if (bind(drv->cmd_socket, (struct sockaddr *) &addr, sizeof(addr)) < 0)
00684 {
00685 perror("bind(PF_UNIX)");
00686 close(drv->cmd_socket);
00687 drv->cmd_socket = -1;
00688 unlink(drv->own_cmd_path);
00689 os_free(drv->own_cmd_path);
00690 drv->own_cmd_path = NULL;
00691 return -1;
00692 }
00693
00694 if (wpa_priv_reg_cmd(drv, PRIVSEP_CMD_REGISTER) < 0) {
00695 wpa_printf(MSG_ERROR, "Failed to register with wpa_priv");
00696 return -1;
00697 }
00698
00699 return 0;
00700 }
00701
00702
00703 static int wpa_driver_privsep_get_capa(void *priv,
00704 struct wpa_driver_capa *capa)
00705 {
00706 struct wpa_driver_privsep_data *drv = priv;
00707 int res;
00708 size_t len = sizeof(*capa);
00709
00710 res = wpa_priv_cmd(drv, PRIVSEP_CMD_GET_CAPA, NULL, 0, capa, &len);
00711 if (res < 0 || len != sizeof(*capa))
00712 return -1;
00713 return 0;
00714 }
00715
00716
00717 static const u8 * wpa_driver_privsep_get_mac_addr(void *priv)
00718 {
00719 struct wpa_driver_privsep_data *drv = priv;
00720 wpa_printf(MSG_DEBUG, "%s", __func__);
00721 return drv->own_addr;
00722 }
00723
00724
00725 static int wpa_driver_privsep_set_country(void *priv, const char *alpha2)
00726 {
00727 struct wpa_driver_privsep_data *drv = priv;
00728 wpa_printf(MSG_DEBUG, "%s country='%s'", __func__, alpha2);
00729 return wpa_priv_cmd(drv, PRIVSEP_CMD_SET_COUNTRY, alpha2,
00730 os_strlen(alpha2), NULL, NULL);
00731 }
00732
00733
00734 struct wpa_driver_ops wpa_driver_privsep_ops = {
00735 "privsep",
00736 "wpa_supplicant privilege separated driver",
00737 .get_bssid = wpa_driver_privsep_get_bssid,
00738 .get_ssid = wpa_driver_privsep_get_ssid,
00739 .set_key = wpa_driver_privsep_set_key,
00740 .init = wpa_driver_privsep_init,
00741 .deinit = wpa_driver_privsep_deinit,
00742 .set_param = wpa_driver_privsep_set_param,
00743 .scan2 = wpa_driver_privsep_scan,
00744 .deauthenticate = wpa_driver_privsep_deauthenticate,
00745 .disassociate = wpa_driver_privsep_disassociate,
00746 .associate = wpa_driver_privsep_associate,
00747 .get_capa = wpa_driver_privsep_get_capa,
00748 .get_mac_addr = wpa_driver_privsep_get_mac_addr,
00749 .get_scan_results2 = wpa_driver_privsep_get_scan_results2,
00750 .set_country = wpa_driver_privsep_set_country,
00751 };
00752
00753
00754 struct wpa_driver_ops *wpa_drivers[] =
00755 {
00756 &wpa_driver_privsep_ops,
00757 NULL
00758 };