driver_privsep.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant - privilege separated driver interface
00003  * Copyright (c) 2007-2009, Jouni Malinen <j@w1.fi>
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
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         /* TODO: add support for other assoc parameters */
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         //struct wpa_driver_privsep_data *drv = priv;
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         //struct wpa_driver_privsep_data *drv = priv;
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 };


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34