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