LCOV - code coverage report
Current view: top level - wpa_supplicant - ctrl_iface_unix.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 336 515 65.2 %
Date: 2015-09-27 Functions: 16 18 88.9 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant / UNIX domain socket -based control interface
       3             :  * Copyright (c) 2004-2014, Jouni Malinen <j@w1.fi>
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : #include <sys/un.h>
      11             : #include <sys/stat.h>
      12             : #include <grp.h>
      13             : #include <stddef.h>
      14             : #include <unistd.h>
      15             : #include <fcntl.h>
      16             : #ifdef __linux__
      17             : #include <sys/ioctl.h>
      18             : #include <linux/sockios.h>
      19             : #endif /* __linux__ */
      20             : #ifdef ANDROID
      21             : #include <cutils/sockets.h>
      22             : #endif /* ANDROID */
      23             : 
      24             : #include "utils/common.h"
      25             : #include "utils/eloop.h"
      26             : #include "utils/list.h"
      27             : #include "eapol_supp/eapol_supp_sm.h"
      28             : #include "config.h"
      29             : #include "wpa_supplicant_i.h"
      30             : #include "ctrl_iface.h"
      31             : 
      32             : /* Per-interface ctrl_iface */
      33             : 
      34             : /**
      35             :  * struct wpa_ctrl_dst - Internal data structure of control interface monitors
      36             :  *
      37             :  * This structure is used to store information about registered control
      38             :  * interface monitors into struct wpa_supplicant. This data is private to
      39             :  * ctrl_iface_unix.c and should not be touched directly from other files.
      40             :  */
      41             : struct wpa_ctrl_dst {
      42             :         struct dl_list list;
      43             :         struct sockaddr_un addr;
      44             :         socklen_t addrlen;
      45             :         int debug_level;
      46             :         int errors;
      47             : };
      48             : 
      49             : 
      50             : struct ctrl_iface_priv {
      51             :         struct wpa_supplicant *wpa_s;
      52             :         int sock;
      53             :         struct dl_list ctrl_dst;
      54             :         int android_control_socket;
      55             : };
      56             : 
      57             : 
      58             : struct ctrl_iface_global_priv {
      59             :         struct wpa_global *global;
      60             :         int sock;
      61             :         struct dl_list ctrl_dst;
      62             :         int android_control_socket;
      63             : };
      64             : 
      65             : 
      66             : static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
      67             :                                            const char *ifname, int sock,
      68             :                                            struct dl_list *ctrl_dst,
      69             :                                            int level, const char *buf,
      70             :                                            size_t len,
      71             :                                            struct ctrl_iface_priv *priv,
      72             :                                            struct ctrl_iface_global_priv *gp);
      73             : static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
      74             :                                   struct ctrl_iface_priv *priv);
      75             : static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
      76             :                                          struct ctrl_iface_global_priv *priv);
      77             : 
      78             : 
      79      292735 : static void wpas_ctrl_sock_debug(const char *title, int sock, const char *buf,
      80             :                                  size_t len)
      81             : {
      82             : #ifdef __linux__
      83             :         socklen_t optlen;
      84             :         int sndbuf, outq;
      85      292735 :         int level = MSG_MSGDUMP;
      86             : 
      87      292735 :         if (len >= 5 && os_strncmp(buf, "PONG\n", 5) == 0)
      88       14829 :                 level = MSG_EXCESSIVE;
      89             : 
      90      292735 :         optlen = sizeof(sndbuf);
      91      292735 :         sndbuf = 0;
      92      292735 :         if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, &optlen) < 0)
      93           0 :                 sndbuf = -1;
      94             : 
      95      292735 :         if (ioctl(sock, SIOCOUTQ, &outq) < 0)
      96           0 :                 outq = -1;
      97             : 
      98      292735 :         wpa_printf(level,
      99             :                    "CTRL-DEBUG: %s: sock=%d sndbuf=%d outq=%d send_len=%d",
     100             :                    title, sock, sndbuf, outq, (int) len);
     101             : #endif /* __linux__ */
     102      292735 : }
     103             : 
     104             : 
     105        4523 : static int wpa_supplicant_ctrl_iface_attach(struct dl_list *ctrl_dst,
     106             :                                             struct sockaddr_un *from,
     107             :                                             socklen_t fromlen, int global)
     108             : {
     109             :         struct wpa_ctrl_dst *dst;
     110             :         char addr_txt[200];
     111             : 
     112        4523 :         dst = os_zalloc(sizeof(*dst));
     113        4523 :         if (dst == NULL)
     114           0 :                 return -1;
     115        4523 :         os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
     116        4523 :         dst->addrlen = fromlen;
     117        4523 :         dst->debug_level = MSG_INFO;
     118        4523 :         dl_list_add(ctrl_dst, &dst->list);
     119        9046 :         printf_encode(addr_txt, sizeof(addr_txt),
     120        4523 :                       (u8 *) from->sun_path,
     121             :                       fromlen - offsetof(struct sockaddr_un, sun_path));
     122        4523 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE %smonitor attached %s",
     123             :                    global ? "global " : "", addr_txt);
     124        4523 :         return 0;
     125             : }
     126             : 
     127             : 
     128        4519 : static int wpa_supplicant_ctrl_iface_detach(struct dl_list *ctrl_dst,
     129             :                                             struct sockaddr_un *from,
     130             :                                             socklen_t fromlen)
     131             : {
     132             :         struct wpa_ctrl_dst *dst;
     133             : 
     134        4652 :         dl_list_for_each(dst, ctrl_dst, struct wpa_ctrl_dst, list) {
     135        9271 :                 if (fromlen == dst->addrlen &&
     136        4632 :                     os_memcmp(from->sun_path, dst->addr.sun_path,
     137             :                               fromlen - offsetof(struct sockaddr_un, sun_path))
     138             :                     == 0) {
     139             :                         char addr_txt[200];
     140        9012 :                         printf_encode(addr_txt, sizeof(addr_txt),
     141        4506 :                                       (u8 *) from->sun_path,
     142             :                                       fromlen -
     143             :                                       offsetof(struct sockaddr_un, sun_path));
     144        4506 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor detached %s",
     145             :                                    addr_txt);
     146        4506 :                         dl_list_del(&dst->list);
     147        4506 :                         os_free(dst);
     148        4506 :                         return 0;
     149             :                 }
     150             :         }
     151          13 :         return -1;
     152             : }
     153             : 
     154             : 
     155           3 : static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
     156             :                                            struct sockaddr_un *from,
     157             :                                            socklen_t fromlen,
     158             :                                            char *level)
     159             : {
     160             :         struct wpa_ctrl_dst *dst;
     161             : 
     162           3 :         wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
     163             : 
     164           4 :         dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
     165           6 :                 if (fromlen == dst->addrlen &&
     166           3 :                     os_memcmp(from->sun_path, dst->addr.sun_path,
     167             :                               fromlen - offsetof(struct sockaddr_un, sun_path))
     168             :                     == 0) {
     169             :                         char addr_txt[200];
     170           2 :                         dst->debug_level = atoi(level);
     171           4 :                         printf_encode(addr_txt, sizeof(addr_txt),
     172           2 :                                       (u8 *) from->sun_path, fromlen -
     173             :                                       offsetof(struct sockaddr_un, sun_path));
     174           2 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE changed monitor level to %d for %s",
     175             :                                    dst->debug_level, addr_txt);
     176           2 :                         return 0;
     177             :                 }
     178             :         }
     179             : 
     180           1 :         return -1;
     181             : }
     182             : 
     183             : 
     184       74157 : static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
     185             :                                               void *sock_ctx)
     186             : {
     187       74157 :         struct wpa_supplicant *wpa_s = eloop_ctx;
     188       74157 :         struct ctrl_iface_priv *priv = sock_ctx;
     189             :         char buf[4096];
     190             :         int res;
     191             :         struct sockaddr_un from;
     192       74157 :         socklen_t fromlen = sizeof(from);
     193       74157 :         char *reply = NULL, *reply_buf = NULL;
     194       74157 :         size_t reply_len = 0;
     195       74157 :         int new_attached = 0;
     196             : 
     197       74157 :         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
     198             :                        (struct sockaddr *) &from, &fromlen);
     199       74157 :         if (res < 0) {
     200           0 :                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     201           0 :                            strerror(errno));
     202       74157 :                 return;
     203             :         }
     204       74157 :         buf[res] = '\0';
     205             : 
     206       74157 :         if (os_strcmp(buf, "ATTACH") == 0) {
     207         888 :                 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
     208             :                                                      fromlen, 0))
     209           0 :                         reply_len = 1;
     210             :                 else {
     211         888 :                         new_attached = 1;
     212         888 :                         reply_len = 2;
     213             :                 }
     214       73269 :         } else if (os_strcmp(buf, "DETACH") == 0) {
     215         854 :                 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
     216             :                                                      fromlen))
     217           5 :                         reply_len = 1;
     218             :                 else
     219         849 :                         reply_len = 2;
     220       72415 :         } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
     221           3 :                 if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
     222             :                                                     buf + 6))
     223           1 :                         reply_len = 1;
     224             :                 else
     225           2 :                         reply_len = 2;
     226             :         } else {
     227       72412 :                 reply_buf = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
     228             :                                                               &reply_len);
     229       72412 :                 reply = reply_buf;
     230             : 
     231             :                 /*
     232             :                  * There could be some password/key material in the command, so
     233             :                  * clear the buffer explicitly now that it is not needed
     234             :                  * anymore.
     235             :                  */
     236       72412 :                 os_memset(buf, 0, res);
     237             :         }
     238             : 
     239       74157 :         if (!reply && reply_len == 1) {
     240           6 :                 reply = "FAIL\n";
     241           6 :                 reply_len = 5;
     242       74151 :         } else if (!reply && reply_len == 2) {
     243        1739 :                 reply = "OK\n";
     244        1739 :                 reply_len = 3;
     245             :         }
     246             : 
     247       74157 :         if (reply) {
     248       74157 :                 wpas_ctrl_sock_debug("ctrl_sock-sendto", sock, reply,
     249             :                                      reply_len);
     250       74157 :                 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
     251             :                            fromlen) < 0) {
     252          42 :                         int _errno = errno;
     253          42 :                         wpa_dbg(wpa_s, MSG_DEBUG,
     254             :                                 "ctrl_iface sendto failed: %d - %s",
     255             :                                 _errno, strerror(_errno));
     256          42 :                         if (_errno == ENOBUFS || _errno == EAGAIN) {
     257             :                                 /*
     258             :                                  * The socket send buffer could be full. This
     259             :                                  * may happen if client programs are not
     260             :                                  * receiving their pending messages. Close and
     261             :                                  * reopen the socket as a workaround to avoid
     262             :                                  * getting stuck being unable to send any new
     263             :                                  * responses.
     264             :                                  */
     265           0 :                                 sock = wpas_ctrl_iface_reinit(wpa_s, priv);
     266           0 :                                 if (sock < 0) {
     267           0 :                                         wpa_dbg(wpa_s, MSG_DEBUG, "Failed to reinitialize ctrl_iface socket");
     268             :                                 }
     269             :                         }
     270          42 :                         if (new_attached) {
     271           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG, "Failed to send response to ATTACH - detaching");
     272           0 :                                 new_attached = 0;
     273           0 :                                 wpa_supplicant_ctrl_iface_detach(
     274             :                                         &priv->ctrl_dst, &from, fromlen);
     275             :                         }
     276             :                 }
     277             :         }
     278       74157 :         os_free(reply_buf);
     279             : 
     280       74157 :         if (new_attached)
     281         888 :                 eapol_sm_notify_ctrl_attached(wpa_s->eapol);
     282             : }
     283             : 
     284             : 
     285        1080 : static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s)
     286             : {
     287             :         char *buf;
     288             :         size_t len;
     289        1080 :         char *pbuf, *dir = NULL;
     290             :         int res;
     291             : 
     292        1080 :         if (wpa_s->conf->ctrl_interface == NULL)
     293           0 :                 return NULL;
     294             : 
     295        1080 :         pbuf = os_strdup(wpa_s->conf->ctrl_interface);
     296        1080 :         if (pbuf == NULL)
     297           0 :                 return NULL;
     298        1080 :         if (os_strncmp(pbuf, "DIR=", 4) == 0) {
     299             :                 char *gid_str;
     300        1080 :                 dir = pbuf + 4;
     301        1080 :                 gid_str = os_strstr(dir, " GROUP=");
     302        1080 :                 if (gid_str)
     303        1052 :                         *gid_str = '\0';
     304             :         } else
     305           0 :                 dir = pbuf;
     306             : 
     307        1080 :         len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2;
     308        1080 :         buf = os_malloc(len);
     309        1080 :         if (buf == NULL) {
     310           0 :                 os_free(pbuf);
     311           0 :                 return NULL;
     312             :         }
     313             : 
     314        1080 :         res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname);
     315        1080 :         if (os_snprintf_error(len, res)) {
     316           0 :                 os_free(pbuf);
     317           0 :                 os_free(buf);
     318           0 :                 return NULL;
     319             :         }
     320             : #ifdef __CYGWIN__
     321             :         {
     322             :                 /* Windows/WinPcap uses interface names that are not suitable
     323             :                  * as a file name - convert invalid chars to underscores */
     324             :                 char *pos = buf;
     325             :                 while (*pos) {
     326             :                         if (*pos == '\\')
     327             :                                 *pos = '_';
     328             :                         pos++;
     329             :                 }
     330             :         }
     331             : #endif /* __CYGWIN__ */
     332        1080 :         os_free(pbuf);
     333        1080 :         return buf;
     334             : }
     335             : 
     336             : 
     337     1115563 : static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
     338             :                                              enum wpa_msg_type type,
     339             :                                              const char *txt, size_t len)
     340             : {
     341     1115563 :         struct wpa_supplicant *wpa_s = ctx;
     342             : 
     343     1115563 :         if (wpa_s == NULL)
     344         243 :                 return;
     345             : 
     346     1115320 :         if (type != WPA_MSG_NO_GLOBAL && wpa_s->global->ctrl_iface) {
     347     1115274 :                 struct ctrl_iface_global_priv *priv = wpa_s->global->ctrl_iface;
     348     1115274 :                 if (!dl_list_empty(&priv->ctrl_dst)) {
     349     1113759 :                         wpa_supplicant_ctrl_iface_send(
     350             :                                 wpa_s,
     351             :                                 type != WPA_MSG_PER_INTERFACE ?
     352             :                                 NULL : wpa_s->ifname,
     353             :                                 priv->sock, &priv->ctrl_dst, level, txt, len,
     354             :                                 NULL, priv);
     355             :                 }
     356             :         }
     357             : 
     358     1115320 :         if (type == WPA_MSG_ONLY_GLOBAL || wpa_s->ctrl_iface == NULL)
     359        5214 :                 return;
     360     2220212 :         wpa_supplicant_ctrl_iface_send(wpa_s, NULL, wpa_s->ctrl_iface->sock,
     361     1110106 :                                        &wpa_s->ctrl_iface->ctrl_dst,
     362             :                                        level, txt, len, wpa_s->ctrl_iface,
     363             :                                        NULL);
     364             : }
     365             : 
     366             : 
     367         540 : static int wpas_ctrl_iface_open_sock(struct wpa_supplicant *wpa_s,
     368             :                                      struct ctrl_iface_priv *priv)
     369             : {
     370             :         struct sockaddr_un addr;
     371         540 :         char *fname = NULL;
     372         540 :         gid_t gid = 0;
     373         540 :         int gid_set = 0;
     374         540 :         char *buf, *dir = NULL, *gid_str = NULL;
     375             :         struct group *grp;
     376             :         char *endp;
     377             :         int flags;
     378             : 
     379         540 :         buf = os_strdup(wpa_s->conf->ctrl_interface);
     380         540 :         if (buf == NULL)
     381           0 :                 goto fail;
     382             : #ifdef ANDROID
     383             :         os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
     384             :                     wpa_s->conf->ctrl_interface);
     385             :         priv->sock = android_get_control_socket(addr.sun_path);
     386             :         if (priv->sock >= 0) {
     387             :                 priv->android_control_socket = 1;
     388             :                 goto havesock;
     389             :         }
     390             : #endif /* ANDROID */
     391         540 :         if (os_strncmp(buf, "DIR=", 4) == 0) {
     392         540 :                 dir = buf + 4;
     393         540 :                 gid_str = os_strstr(dir, " GROUP=");
     394         540 :                 if (gid_str) {
     395         526 :                         *gid_str = '\0';
     396         526 :                         gid_str += 7;
     397             :                 }
     398             :         } else {
     399           0 :                 dir = buf;
     400           0 :                 gid_str = wpa_s->conf->ctrl_interface_group;
     401             :         }
     402             : 
     403         540 :         if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
     404         534 :                 if (errno == EEXIST) {
     405         534 :                         wpa_printf(MSG_DEBUG, "Using existing control "
     406             :                                    "interface directory.");
     407             :                 } else {
     408           0 :                         wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s",
     409           0 :                                    dir, strerror(errno));
     410           0 :                         goto fail;
     411             :                 }
     412             :         }
     413             : 
     414             : #ifdef ANDROID
     415             :         /*
     416             :          * wpa_supplicant is started from /init.*.rc on Android and that seems
     417             :          * to be using umask 0077 which would leave the control interface
     418             :          * directory without group access. This breaks things since Wi-Fi
     419             :          * framework assumes that this directory can be accessed by other
     420             :          * applications in the wifi group. Fix this by adding group access even
     421             :          * if umask value would prevent this.
     422             :          */
     423             :         if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
     424             :                 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
     425             :                            strerror(errno));
     426             :                 /* Try to continue anyway */
     427             :         }
     428             : #endif /* ANDROID */
     429             : 
     430         540 :         if (gid_str) {
     431         526 :                 grp = getgrnam(gid_str);
     432         526 :                 if (grp) {
     433         526 :                         gid = grp->gr_gid;
     434         526 :                         gid_set = 1;
     435         526 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
     436             :                                    " (from group name '%s')",
     437             :                                    (int) gid, gid_str);
     438             :                 } else {
     439             :                         /* Group name not found - try to parse this as gid */
     440           0 :                         gid = strtol(gid_str, &endp, 10);
     441           0 :                         if (*gid_str == '\0' || *endp != '\0') {
     442           0 :                                 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
     443             :                                            "'%s'", gid_str);
     444           0 :                                 goto fail;
     445             :                         }
     446           0 :                         gid_set = 1;
     447           0 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
     448             :                                    (int) gid);
     449             :                 }
     450             :         }
     451             : 
     452         540 :         if (gid_set && chown(dir, -1, gid) < 0) {
     453           0 :                 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s",
     454           0 :                            dir, (int) gid, strerror(errno));
     455           0 :                 goto fail;
     456             :         }
     457             : 
     458             :         /* Make sure the group can enter and read the directory */
     459        1066 :         if (gid_set &&
     460         526 :             chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
     461           0 :                 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
     462           0 :                            strerror(errno));
     463           0 :                 goto fail;
     464             :         }
     465             : 
     466         540 :         if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
     467             :             sizeof(addr.sun_path)) {
     468           0 :                 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
     469           0 :                 goto fail;
     470             :         }
     471             : 
     472         540 :         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
     473         540 :         if (priv->sock < 0) {
     474           0 :                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
     475           0 :                 goto fail;
     476             :         }
     477             : 
     478         540 :         os_memset(&addr, 0, sizeof(addr));
     479             : #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
     480             :         addr.sun_len = sizeof(addr);
     481             : #endif /* __FreeBSD__ */
     482         540 :         addr.sun_family = AF_UNIX;
     483         540 :         fname = wpa_supplicant_ctrl_iface_path(wpa_s);
     484         540 :         if (fname == NULL)
     485           0 :                 goto fail;
     486         540 :         os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
     487         540 :         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
     488           0 :                 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
     489           0 :                            strerror(errno));
     490           0 :                 if (connect(priv->sock, (struct sockaddr *) &addr,
     491             :                             sizeof(addr)) < 0) {
     492           0 :                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
     493             :                                    " allow connections - assuming it was left"
     494             :                                    "over from forced program termination");
     495           0 :                         if (unlink(fname) < 0) {
     496           0 :                                 wpa_printf(MSG_ERROR,
     497             :                                            "Could not unlink existing ctrl_iface socket '%s': %s",
     498           0 :                                            fname, strerror(errno));
     499           0 :                                 goto fail;
     500             :                         }
     501           0 :                         if (bind(priv->sock, (struct sockaddr *) &addr,
     502             :                                  sizeof(addr)) < 0) {
     503           0 :                                 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s",
     504           0 :                                            strerror(errno));
     505           0 :                                 goto fail;
     506             :                         }
     507           0 :                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
     508             :                                    "ctrl_iface socket '%s'", fname);
     509             :                 } else {
     510           0 :                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
     511             :                                    "be in use - cannot override it");
     512           0 :                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
     513             :                                    "not used anymore", fname);
     514           0 :                         os_free(fname);
     515           0 :                         fname = NULL;
     516           0 :                         goto fail;
     517             :                 }
     518             :         }
     519             : 
     520         540 :         if (gid_set && chown(fname, -1, gid) < 0) {
     521           0 :                 wpa_printf(MSG_ERROR, "chown[ctrl_interface=%s,gid=%d]: %s",
     522           0 :                            fname, (int) gid, strerror(errno));
     523           0 :                 goto fail;
     524             :         }
     525             : 
     526         540 :         if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
     527           0 :                 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s",
     528           0 :                            fname, strerror(errno));
     529           0 :                 goto fail;
     530             :         }
     531         540 :         os_free(fname);
     532             : 
     533             : #ifdef ANDROID
     534             : havesock:
     535             : #endif /* ANDROID */
     536             : 
     537             :         /*
     538             :          * Make socket non-blocking so that we don't hang forever if
     539             :          * target dies unexpectedly.
     540             :          */
     541         540 :         flags = fcntl(priv->sock, F_GETFL);
     542         540 :         if (flags >= 0) {
     543         540 :                 flags |= O_NONBLOCK;
     544         540 :                 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
     545           0 :                         wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
     546           0 :                                    strerror(errno));
     547             :                         /* Not fatal, continue on.*/
     548             :                 }
     549             :         }
     550             : 
     551         540 :         eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
     552             :                                  wpa_s, priv);
     553         540 :         wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
     554             : 
     555         540 :         os_free(buf);
     556         540 :         return 0;
     557             : 
     558             : fail:
     559           0 :         if (priv->sock >= 0) {
     560           0 :                 close(priv->sock);
     561           0 :                 priv->sock = -1;
     562             :         }
     563           0 :         if (fname) {
     564           0 :                 unlink(fname);
     565           0 :                 os_free(fname);
     566             :         }
     567           0 :         os_free(buf);
     568           0 :         return -1;
     569             : }
     570             : 
     571             : 
     572             : struct ctrl_iface_priv *
     573         577 : wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
     574             : {
     575             :         struct ctrl_iface_priv *priv;
     576             : 
     577         577 :         priv = os_zalloc(sizeof(*priv));
     578         577 :         if (priv == NULL)
     579           1 :                 return NULL;
     580         576 :         dl_list_init(&priv->ctrl_dst);
     581         576 :         priv->wpa_s = wpa_s;
     582         576 :         priv->sock = -1;
     583             : 
     584         576 :         if (wpa_s->conf->ctrl_interface == NULL)
     585          36 :                 return priv;
     586             : 
     587             : #ifdef ANDROID
     588             :         if (wpa_s->global->params.ctrl_interface) {
     589             :                 int same = 0;
     590             : 
     591             :                 if (wpa_s->global->params.ctrl_interface[0] == '/') {
     592             :                         if (os_strcmp(wpa_s->global->params.ctrl_interface,
     593             :                                       wpa_s->conf->ctrl_interface) == 0)
     594             :                                 same = 1;
     595             :                 } else if (os_strncmp(wpa_s->global->params.ctrl_interface,
     596             :                                       "@android:", 9) == 0 ||
     597             :                            os_strncmp(wpa_s->global->params.ctrl_interface,
     598             :                                       "@abstract:", 10) == 0) {
     599             :                         char *pos;
     600             : 
     601             :                         /*
     602             :                          * Currently, Android uses @android:wpa_* as the naming
     603             :                          * convention for the global ctrl interface. This logic
     604             :                          * needs to be revisited if the above naming convention
     605             :                          * is modified.
     606             :                          */
     607             :                         pos = os_strchr(wpa_s->global->params.ctrl_interface,
     608             :                                         '_');
     609             :                         if (pos &&
     610             :                             os_strcmp(pos + 1,
     611             :                                       wpa_s->conf->ctrl_interface) == 0)
     612             :                                 same = 1;
     613             :                 }
     614             : 
     615             :                 if (same) {
     616             :                         /*
     617             :                          * The invalid configuration combination might be
     618             :                          * possible to hit in an Android OTA upgrade case, so
     619             :                          * instead of refusing to start the wpa_supplicant
     620             :                          * process, do not open the per-interface ctrl_iface
     621             :                          * and continue with the global control interface that
     622             :                          * was set from the command line since the Wi-Fi
     623             :                          * framework will use it for operations.
     624             :                          */
     625             :                         wpa_printf(MSG_ERROR,
     626             :                                    "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface",
     627             :                                    wpa_s->global->params.ctrl_interface,
     628             :                                    wpa_s->conf->ctrl_interface);
     629             :                         return priv;
     630             :                 }
     631             :         }
     632             : #endif /* ANDROID */
     633             : 
     634         540 :         if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) {
     635           0 :                 os_free(priv);
     636           0 :                 return NULL;
     637             :         }
     638             : 
     639         540 :         return priv;
     640             : }
     641             : 
     642             : 
     643           0 : static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
     644             :                                   struct ctrl_iface_priv *priv)
     645             : {
     646             :         int res;
     647             : 
     648           0 :         if (priv->sock <= 0)
     649           0 :                 return -1;
     650             : 
     651             :         /*
     652             :          * On Android, the control socket being used may be the socket
     653             :          * that is created when wpa_supplicant is started as a /init.*.rc
     654             :          * service. Such a socket is maintained as a key-value pair in
     655             :          * Android's environment. Closing this control socket would leave us
     656             :          * in a bad state with an invalid socket descriptor.
     657             :          */
     658           0 :         if (priv->android_control_socket)
     659           0 :                 return priv->sock;
     660             : 
     661           0 :         eloop_unregister_read_sock(priv->sock);
     662           0 :         close(priv->sock);
     663           0 :         priv->sock = -1;
     664           0 :         res = wpas_ctrl_iface_open_sock(wpa_s, priv);
     665           0 :         if (res < 0)
     666           0 :                 return -1;
     667           0 :         return priv->sock;
     668             : }
     669             : 
     670             : 
     671         576 : void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
     672             : {
     673             :         struct wpa_ctrl_dst *dst, *prev;
     674             : 
     675         576 :         if (priv->sock > -1) {
     676             :                 char *fname;
     677         540 :                 char *buf, *dir = NULL;
     678         540 :                 eloop_unregister_read_sock(priv->sock);
     679         540 :                 if (!dl_list_empty(&priv->ctrl_dst)) {
     680             :                         /*
     681             :                          * Wait before closing the control socket if
     682             :                          * there are any attached monitors in order to allow
     683             :                          * them to receive any pending messages.
     684             :                          */
     685          16 :                         wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
     686             :                                    "monitors to receive messages");
     687          16 :                         os_sleep(0, 100000);
     688             :                 }
     689         540 :                 close(priv->sock);
     690         540 :                 priv->sock = -1;
     691         540 :                 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
     692         540 :                 if (fname) {
     693         540 :                         unlink(fname);
     694         540 :                         os_free(fname);
     695             :                 }
     696             : 
     697         540 :                 if (priv->wpa_s->conf->ctrl_interface == NULL)
     698           0 :                         goto free_dst;
     699         540 :                 buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
     700         540 :                 if (buf == NULL)
     701           0 :                         goto free_dst;
     702         540 :                 if (os_strncmp(buf, "DIR=", 4) == 0) {
     703             :                         char *gid_str;
     704         540 :                         dir = buf + 4;
     705         540 :                         gid_str = os_strstr(dir, " GROUP=");
     706         540 :                         if (gid_str)
     707         526 :                                 *gid_str = '\0';
     708             :                 } else
     709           0 :                         dir = buf;
     710             : 
     711         540 :                 if (rmdir(dir) < 0) {
     712         534 :                         if (errno == ENOTEMPTY) {
     713         532 :                                 wpa_printf(MSG_DEBUG, "Control interface "
     714             :                                            "directory not empty - leaving it "
     715             :                                            "behind");
     716             :                         } else {
     717           2 :                                 wpa_printf(MSG_ERROR,
     718             :                                            "rmdir[ctrl_interface=%s]: %s",
     719           2 :                                            dir, strerror(errno));
     720             :                         }
     721             :                 }
     722         540 :                 os_free(buf);
     723             :         }
     724             : 
     725             : free_dst:
     726         593 :         dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
     727             :                               list)
     728          17 :                 os_free(dst);
     729         576 :         os_free(priv);
     730         576 : }
     731             : 
     732             : 
     733             : /**
     734             :  * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
     735             :  * @ifname: Interface name for global control socket or %NULL
     736             :  * @sock: Local socket fd
     737             :  * @ctrl_dst: List of attached listeners
     738             :  * @level: Priority level of the message
     739             :  * @buf: Message data
     740             :  * @len: Message length
     741             :  *
     742             :  * Send a packet to all monitor programs attached to the control interface.
     743             :  */
     744     2223865 : static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
     745             :                                            const char *ifname, int sock,
     746             :                                            struct dl_list *ctrl_dst,
     747             :                                            int level, const char *buf,
     748             :                                            size_t len,
     749             :                                            struct ctrl_iface_priv *priv,
     750             :                                            struct ctrl_iface_global_priv *gp)
     751             : {
     752             :         struct wpa_ctrl_dst *dst, *next;
     753             :         char levelstr[10];
     754             :         int idx, res;
     755             :         struct msghdr msg;
     756             :         struct iovec io[5];
     757             : 
     758     2223865 :         if (sock < 0 || dl_list_empty(ctrl_dst))
     759      465280 :                 return;
     760             : 
     761     1991225 :         res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
     762     1991225 :         if (os_snprintf_error(sizeof(levelstr), res))
     763           0 :                 return;
     764     1991225 :         idx = 0;
     765     1991225 :         if (ifname) {
     766      865291 :                 io[idx].iov_base = "IFNAME=";
     767      865291 :                 io[idx].iov_len = 7;
     768      865291 :                 idx++;
     769      865291 :                 io[idx].iov_base = (char *) ifname;
     770      865291 :                 io[idx].iov_len = os_strlen(ifname);
     771      865291 :                 idx++;
     772      865291 :                 io[idx].iov_base = " ";
     773      865291 :                 io[idx].iov_len = 1;
     774      865291 :                 idx++;
     775             :         }
     776     1991225 :         io[idx].iov_base = levelstr;
     777     1991225 :         io[idx].iov_len = os_strlen(levelstr);
     778     1991225 :         idx++;
     779     1991225 :         io[idx].iov_base = (char *) buf;
     780     1991225 :         io[idx].iov_len = len;
     781     1991225 :         idx++;
     782     1991225 :         os_memset(&msg, 0, sizeof(msg));
     783     1991225 :         msg.msg_iov = io;
     784     1991225 :         msg.msg_iovlen = idx;
     785             : 
     786     4043818 :         dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
     787             :                 int _errno;
     788             :                 char addr_txt[200];
     789             : 
     790     2052593 :                 if (level < dst->debug_level)
     791     3952794 :                         continue;
     792             : 
     793      304722 :                 printf_encode(addr_txt, sizeof(addr_txt),
     794      304722 :                               (u8 *) dst->addr.sun_path, dst->addrlen -
     795             :                               offsetof(struct sockaddr_un, sun_path));
     796      152361 :                 msg.msg_name = (void *) &dst->addr;
     797      152361 :                 msg.msg_namelen = dst->addrlen;
     798      152361 :                 wpas_ctrl_sock_debug("ctrl_sock-sendmsg", sock, buf, len);
     799      152361 :                 if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) {
     800      152330 :                         wpa_printf(MSG_MSGDUMP,
     801             :                                    "CTRL_IFACE monitor sent successfully to %s",
     802             :                                    addr_txt);
     803      152330 :                         dst->errors = 0;
     804      152330 :                         continue;
     805             :                 }
     806             : 
     807          31 :                 _errno = errno;
     808          62 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE monitor[%s]: %d - %s",
     809          62 :                            addr_txt, errno, strerror(errno));
     810          31 :                 dst->errors++;
     811             : 
     812          31 :                 if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) {
     813          31 :                         wpa_printf(MSG_INFO, "CTRL_IFACE: Detach monitor %s that cannot receive messages",
     814             :                                 addr_txt);
     815          31 :                         wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr,
     816             :                                                          dst->addrlen);
     817             :                 }
     818             : 
     819          31 :                 if (_errno == ENOBUFS || _errno == EAGAIN) {
     820             :                         /*
     821             :                          * The socket send buffer could be full. This may happen
     822             :                          * if client programs are not receiving their pending
     823             :                          * messages. Close and reopen the socket as a workaround
     824             :                          * to avoid getting stuck being unable to send any new
     825             :                          * responses.
     826             :                          */
     827           0 :                         if (priv)
     828           0 :                                 sock = wpas_ctrl_iface_reinit(wpa_s, priv);
     829           0 :                         else if (gp)
     830           0 :                                 sock = wpas_ctrl_iface_global_reinit(
     831             :                                         wpa_s->global, gp);
     832             :                         else
     833           0 :                                 break;
     834           0 :                         if (sock < 0) {
     835           0 :                                 wpa_dbg(wpa_s, MSG_DEBUG,
     836             :                                         "Failed to reinitialize ctrl_iface socket");
     837           0 :                                 break;
     838             :                         }
     839             :                 }
     840             :         }
     841             : }
     842             : 
     843             : 
     844           1 : void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
     845             : {
     846             :         char buf[256];
     847             :         int res;
     848             :         struct sockaddr_un from;
     849           1 :         socklen_t fromlen = sizeof(from);
     850             : 
     851             :         for (;;) {
     852           1 :                 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
     853           1 :                            "attach", priv->wpa_s->ifname);
     854           1 :                 eloop_wait_for_read_sock(priv->sock);
     855             : 
     856           1 :                 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
     857             :                                (struct sockaddr *) &from, &fromlen);
     858           1 :                 if (res < 0) {
     859           0 :                         wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     860           0 :                                    strerror(errno));
     861           0 :                         continue;
     862             :                 }
     863           1 :                 buf[res] = '\0';
     864             : 
     865           1 :                 if (os_strcmp(buf, "ATTACH") == 0) {
     866             :                         /* handle ATTACH signal of first monitor interface */
     867           1 :                         if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
     868             :                                                               &from, fromlen,
     869             :                                                               0)) {
     870           1 :                                 if (sendto(priv->sock, "OK\n", 3, 0,
     871             :                                            (struct sockaddr *) &from, fromlen) <
     872             :                                     0) {
     873           0 :                                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     874           0 :                                                    strerror(errno));
     875             :                                 }
     876             :                                 /* OK to continue */
     877           2 :                                 return;
     878             :                         } else {
     879           0 :                                 if (sendto(priv->sock, "FAIL\n", 5, 0,
     880             :                                            (struct sockaddr *) &from, fromlen) <
     881             :                                     0) {
     882           0 :                                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     883           0 :                                                    strerror(errno));
     884             :                                 }
     885             :                         }
     886             :                 } else {
     887             :                         /* return FAIL for all other signals */
     888           0 :                         if (sendto(priv->sock, "FAIL\n", 5, 0,
     889             :                                    (struct sockaddr *) &from, fromlen) < 0) {
     890           0 :                                 wpa_printf(MSG_DEBUG,
     891             :                                            "ctrl_iface sendto failed: %s",
     892           0 :                                            strerror(errno));
     893             :                         }
     894             :                 }
     895           0 :         }
     896             : }
     897             : 
     898             : 
     899             : /* Global ctrl_iface */
     900             : 
     901       66217 : static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
     902             :                                                      void *sock_ctx)
     903             : {
     904       66217 :         struct wpa_global *global = eloop_ctx;
     905       66217 :         struct ctrl_iface_global_priv *priv = sock_ctx;
     906             :         char buf[4096];
     907             :         int res;
     908             :         struct sockaddr_un from;
     909       66217 :         socklen_t fromlen = sizeof(from);
     910       66217 :         char *reply = NULL, *reply_buf = NULL;
     911             :         size_t reply_len;
     912             : 
     913       66217 :         res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
     914             :                        (struct sockaddr *) &from, &fromlen);
     915       66217 :         if (res < 0) {
     916           0 :                 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
     917           0 :                            strerror(errno));
     918       66217 :                 return;
     919             :         }
     920       66217 :         buf[res] = '\0';
     921             : 
     922       66217 :         if (os_strcmp(buf, "ATTACH") == 0) {
     923        3634 :                 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
     924             :                                                      fromlen, 1))
     925           0 :                         reply_len = 1;
     926             :                 else
     927        3634 :                         reply_len = 2;
     928       62583 :         } else if (os_strcmp(buf, "DETACH") == 0) {
     929        3634 :                 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
     930             :                                                      fromlen))
     931           8 :                         reply_len = 1;
     932             :                 else
     933        3626 :                         reply_len = 2;
     934             :         } else {
     935       58949 :                 reply_buf = wpa_supplicant_global_ctrl_iface_process(
     936             :                         global, buf, &reply_len);
     937       58949 :                 reply = reply_buf;
     938             : 
     939             :                 /*
     940             :                  * There could be some password/key material in the command, so
     941             :                  * clear the buffer explicitly now that it is not needed
     942             :                  * anymore.
     943             :                  */
     944       58949 :                 os_memset(buf, 0, res);
     945             :         }
     946             : 
     947       66217 :         if (!reply && reply_len == 1) {
     948          10 :                 reply = "FAIL\n";
     949          10 :                 reply_len = 5;
     950       66207 :         } else if (!reply && reply_len == 2) {
     951        7260 :                 reply = "OK\n";
     952        7260 :                 reply_len = 3;
     953             :         }
     954             : 
     955       66217 :         if (reply) {
     956       66217 :                 wpas_ctrl_sock_debug("global_ctrl_sock-sendto",
     957             :                                      sock, reply, reply_len);
     958       66217 :                 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
     959             :                            fromlen) < 0) {
     960          65 :                         wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
     961          65 :                                 strerror(errno));
     962             :                 }
     963             :         }
     964       66217 :         os_free(reply_buf);
     965             : }
     966             : 
     967             : 
     968          35 : static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global,
     969             :                                             struct ctrl_iface_global_priv *priv)
     970             : {
     971             :         struct sockaddr_un addr;
     972          35 :         const char *ctrl = global->params.ctrl_interface;
     973             :         int flags;
     974             : 
     975          35 :         wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl);
     976             : 
     977             : #ifdef ANDROID
     978             :         if (os_strncmp(ctrl, "@android:", 9) == 0) {
     979             :                 priv->sock = android_get_control_socket(ctrl + 9);
     980             :                 if (priv->sock < 0) {
     981             :                         wpa_printf(MSG_ERROR, "Failed to open Android control "
     982             :                                    "socket '%s'", ctrl + 9);
     983             :                         goto fail;
     984             :                 }
     985             :                 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'",
     986             :                            ctrl + 9);
     987             :                 priv->android_control_socket = 1;
     988             :                 goto havesock;
     989             :         }
     990             : 
     991             :         if (os_strncmp(ctrl, "@abstract:", 10) != 0) {
     992             :                 /*
     993             :                  * Backwards compatibility - try to open an Android control
     994             :                  * socket and if that fails, assume this was a UNIX domain
     995             :                  * socket instead.
     996             :                  */
     997             :                 priv->sock = android_get_control_socket(ctrl);
     998             :                 if (priv->sock >= 0) {
     999             :                         wpa_printf(MSG_DEBUG,
    1000             :                                    "Using Android control socket '%s'",
    1001             :                                    ctrl);
    1002             :                         priv->android_control_socket = 1;
    1003             :                         goto havesock;
    1004             :                 }
    1005             :         }
    1006             : #endif /* ANDROID */
    1007             : 
    1008          35 :         priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
    1009          35 :         if (priv->sock < 0) {
    1010           0 :                 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
    1011           0 :                 goto fail;
    1012             :         }
    1013             : 
    1014          35 :         os_memset(&addr, 0, sizeof(addr));
    1015             : #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
    1016             :         addr.sun_len = sizeof(addr);
    1017             : #endif /* __FreeBSD__ */
    1018          35 :         addr.sun_family = AF_UNIX;
    1019             : 
    1020          35 :         if (os_strncmp(ctrl, "@abstract:", 10) == 0) {
    1021           0 :                 addr.sun_path[0] = '\0';
    1022           0 :                 os_strlcpy(addr.sun_path + 1, ctrl + 10,
    1023             :                            sizeof(addr.sun_path) - 1);
    1024           0 :                 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) <
    1025             :                     0) {
    1026           0 :                         wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: "
    1027             :                                    "bind(PF_UNIX;%s) failed: %s",
    1028           0 :                                    ctrl, strerror(errno));
    1029           0 :                         goto fail;
    1030             :                 }
    1031           0 :                 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'",
    1032             :                            ctrl + 10);
    1033           0 :                 goto havesock;
    1034             :         }
    1035             : 
    1036          35 :         os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
    1037          35 :         if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
    1038           0 :                 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s",
    1039           0 :                            ctrl, strerror(errno));
    1040           0 :                 if (connect(priv->sock, (struct sockaddr *) &addr,
    1041             :                             sizeof(addr)) < 0) {
    1042           0 :                         wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
    1043             :                                    " allow connections - assuming it was left"
    1044             :                                    "over from forced program termination");
    1045           0 :                         if (unlink(ctrl) < 0) {
    1046           0 :                                 wpa_printf(MSG_ERROR,
    1047             :                                            "Could not unlink existing ctrl_iface socket '%s': %s",
    1048           0 :                                            ctrl, strerror(errno));
    1049           0 :                                 goto fail;
    1050             :                         }
    1051           0 :                         if (bind(priv->sock, (struct sockaddr *) &addr,
    1052             :                                  sizeof(addr)) < 0) {
    1053           0 :                                 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s",
    1054           0 :                                            ctrl, strerror(errno));
    1055           0 :                                 goto fail;
    1056             :                         }
    1057           0 :                         wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
    1058             :                                    "ctrl_iface socket '%s'",
    1059             :                                    ctrl);
    1060             :                 } else {
    1061           0 :                         wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
    1062             :                                    "be in use - cannot override it");
    1063           0 :                         wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
    1064             :                                    "not used anymore",
    1065             :                                    ctrl);
    1066           0 :                         goto fail;
    1067             :                 }
    1068             :         }
    1069             : 
    1070          35 :         wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl);
    1071             : 
    1072          35 :         if (global->params.ctrl_interface_group) {
    1073          24 :                 char *gid_str = global->params.ctrl_interface_group;
    1074          24 :                 gid_t gid = 0;
    1075             :                 struct group *grp;
    1076             :                 char *endp;
    1077             : 
    1078          24 :                 grp = getgrnam(gid_str);
    1079          24 :                 if (grp) {
    1080          24 :                         gid = grp->gr_gid;
    1081          24 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
    1082             :                                    " (from group name '%s')",
    1083             :                                    (int) gid, gid_str);
    1084             :                 } else {
    1085             :                         /* Group name not found - try to parse this as gid */
    1086           0 :                         gid = strtol(gid_str, &endp, 10);
    1087           0 :                         if (*gid_str == '\0' || *endp != '\0') {
    1088           0 :                                 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
    1089             :                                            "'%s'", gid_str);
    1090           0 :                                 goto fail;
    1091             :                         }
    1092           0 :                         wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
    1093             :                                    (int) gid);
    1094             :                 }
    1095          24 :                 if (chown(ctrl, -1, gid) < 0) {
    1096           0 :                         wpa_printf(MSG_ERROR,
    1097             :                                    "chown[global_ctrl_interface=%s,gid=%d]: %s",
    1098           0 :                                    ctrl, (int) gid, strerror(errno));
    1099           0 :                         goto fail;
    1100             :                 }
    1101             : 
    1102          24 :                 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) {
    1103           0 :                         wpa_printf(MSG_ERROR,
    1104             :                                    "chmod[global_ctrl_interface=%s]: %s",
    1105           0 :                                    ctrl, strerror(errno));
    1106           0 :                         goto fail;
    1107             :                 }
    1108             :         } else {
    1109          11 :                 if (chmod(ctrl, S_IRWXU) < 0) {
    1110           0 :                         wpa_printf(MSG_DEBUG,
    1111             :                                    "chmod[global_ctrl_interface=%s](S_IRWXU): %s",
    1112           0 :                                    ctrl, strerror(errno));
    1113             :                         /* continue anyway since group change was not required
    1114             :                          */
    1115             :                 }
    1116             :         }
    1117             : 
    1118             : havesock:
    1119             : 
    1120             :         /*
    1121             :          * Make socket non-blocking so that we don't hang forever if
    1122             :          * target dies unexpectedly.
    1123             :          */
    1124          35 :         flags = fcntl(priv->sock, F_GETFL);
    1125          35 :         if (flags >= 0) {
    1126          35 :                 flags |= O_NONBLOCK;
    1127          35 :                 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
    1128           0 :                         wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
    1129           0 :                                    strerror(errno));
    1130             :                         /* Not fatal, continue on.*/
    1131             :                 }
    1132             :         }
    1133             : 
    1134          35 :         eloop_register_read_sock(priv->sock,
    1135             :                                  wpa_supplicant_global_ctrl_iface_receive,
    1136             :                                  global, priv);
    1137             : 
    1138          35 :         return 0;
    1139             : 
    1140             : fail:
    1141           0 :         if (priv->sock >= 0) {
    1142           0 :                 close(priv->sock);
    1143           0 :                 priv->sock = -1;
    1144             :         }
    1145           0 :         return -1;
    1146             : }
    1147             : 
    1148             : 
    1149             : struct ctrl_iface_global_priv *
    1150          49 : wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
    1151             : {
    1152             :         struct ctrl_iface_global_priv *priv;
    1153             : 
    1154          49 :         priv = os_zalloc(sizeof(*priv));
    1155          49 :         if (priv == NULL)
    1156           0 :                 return NULL;
    1157          49 :         dl_list_init(&priv->ctrl_dst);
    1158          49 :         priv->global = global;
    1159          49 :         priv->sock = -1;
    1160             : 
    1161          49 :         if (global->params.ctrl_interface == NULL)
    1162          14 :                 return priv;
    1163             : 
    1164          35 :         if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) {
    1165           0 :                 os_free(priv);
    1166           0 :                 return NULL;
    1167             :         }
    1168             : 
    1169          35 :         wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
    1170             : 
    1171          35 :         return priv;
    1172             : }
    1173             : 
    1174             : 
    1175           0 : static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
    1176             :                                          struct ctrl_iface_global_priv *priv)
    1177             : {
    1178             :         int res;
    1179             : 
    1180           0 :         if (priv->sock <= 0)
    1181           0 :                 return -1;
    1182             : 
    1183             :         /*
    1184             :          * On Android, the control socket being used may be the socket
    1185             :          * that is created when wpa_supplicant is started as a /init.*.rc
    1186             :          * service. Such a socket is maintained as a key-value pair in
    1187             :          * Android's environment. Closing this control socket would leave us
    1188             :          * in a bad state with an invalid socket descriptor.
    1189             :          */
    1190           0 :         if (priv->android_control_socket)
    1191           0 :                 return priv->sock;
    1192             : 
    1193           0 :         eloop_unregister_read_sock(priv->sock);
    1194           0 :         close(priv->sock);
    1195           0 :         priv->sock = -1;
    1196           0 :         res = wpas_global_ctrl_iface_open_sock(global, priv);
    1197           0 :         if (res < 0)
    1198           0 :                 return -1;
    1199           0 :         return priv->sock;
    1200             : }
    1201             : 
    1202             : 
    1203             : void
    1204          49 : wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
    1205             : {
    1206             :         struct wpa_ctrl_dst *dst, *prev;
    1207             : 
    1208          49 :         if (priv->sock >= 0) {
    1209          35 :                 eloop_unregister_read_sock(priv->sock);
    1210          35 :                 close(priv->sock);
    1211             :         }
    1212          49 :         if (priv->global->params.ctrl_interface)
    1213          35 :                 unlink(priv->global->params.ctrl_interface);
    1214          49 :         dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
    1215             :                               list)
    1216           0 :                 os_free(dst);
    1217          49 :         os_free(priv);
    1218          49 : }

Generated by: LCOV version 1.10