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