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
510 buf = os_strdup(wpa_s->conf->ctrl_interface);
511 if (buf == NULL)
512 goto fail;
513 #ifdef ANDROID
514 os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
515 wpa_s->conf->ctrl_interface);
516 priv->sock = android_get_control_socket(addr.sun_path);
517 if (priv->sock >= 0) {
518 priv->android_control_socket = 1;
519 goto havesock;
520 }
521 #endif /* ANDROID */
522 if (os_strncmp(buf, "DIR=", 4) == 0) {
523 dir = buf + 4;
524 gid_str = os_strstr(dir, " GROUP=");
525 if (gid_str) {
526 *gid_str = '\0';
527 gid_str += 7;
528 }
529 } else {
530 dir = buf;
531 gid_str = wpa_s->conf->ctrl_interface_group;
532 }
533
534 if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
535 if (errno == EEXIST) {
536 wpa_printf(MSG_DEBUG, "Using existing control "
537 "interface directory.");
538 } else {
539 wpa_printf(MSG_ERROR, "mkdir[ctrl_interface=%s]: %s",
540 dir, strerror(errno));
541 goto fail;
542 }
543 }
544
545 #ifdef ANDROID
546 /*
547 * wpa_supplicant is started from /init.*.rc on Android and that seems
548 * to be using umask 0077 which would leave the control interface
549 * directory without group access. This breaks things since Wi-Fi
550 * framework assumes that this directory can be accessed by other
551 * applications in the wifi group. Fix this by adding group access even
552 * if umask value would prevent this.
553 */
554 if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
555 wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
556 strerror(errno));
557 /* Try to continue anyway */
558 }
559 #endif /* ANDROID */
560
561 if (gid_str) {
562 grp = getgrnam(gid_str);
563 if (grp) {
564 gid = grp->gr_gid;
565 gid_set = 1;
566 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
567 " (from group name '%s')",
568 (int) gid, gid_str);
569 } else {
570 /* Group name not found - try to parse this as gid */
571 gid = strtol(gid_str, &endp, 10);
572 if (*gid_str == '\0' || *endp != '\0') {
573 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
574 "'%s'", gid_str);
575 goto fail;
576 }
577 gid_set = 1;
578 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
579 (int) gid);
580 }
581 }
582
583 if (gid_set && lchown(dir, -1, gid) < 0) {
584 wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s",
585 dir, (int) gid, strerror(errno));
586 goto fail;
587 }
588
589 /* Make sure the group can enter and read the directory */
590 if (gid_set &&
591 chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
592 wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
593 strerror(errno));
594 goto fail;
595 }
596
597 if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
598 sizeof(addr.sun_path)) {
599 wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
600 goto fail;
601 }
602
603 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
604 if (priv->sock < 0) {
605 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
606 goto fail;
607 }
608
609 os_memset(&addr, 0, sizeof(addr));
610 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
611 addr.sun_len = sizeof(addr);
612 #endif /* __FreeBSD__ */
613 addr.sun_family = AF_UNIX;
614 fname = wpa_supplicant_ctrl_iface_path(wpa_s);
615 if (fname == NULL)
616 goto fail;
617 os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
618 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
619 wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
620 strerror(errno));
621 if (connect(priv->sock, (struct sockaddr *) &addr,
622 sizeof(addr)) < 0) {
623 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
624 " allow connections - assuming it was left"
625 "over from forced program termination");
626 if (unlink(fname) < 0) {
627 wpa_printf(MSG_ERROR,
628 "Could not unlink existing ctrl_iface socket '%s': %s",
629 fname, strerror(errno));
630 goto fail;
631 }
632 if (bind(priv->sock, (struct sockaddr *) &addr,
633 sizeof(addr)) < 0) {
634 wpa_printf(MSG_ERROR, "supp-ctrl-iface-init: bind(PF_UNIX): %s",
635 strerror(errno));
636 goto fail;
637 }
638 wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
639 "ctrl_iface socket '%s'", fname);
640 } else {
641 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
642 "be in use - cannot override it");
643 wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
644 "not used anymore", fname);
645 os_free(fname);
646 fname = NULL;
647 goto fail;
648 }
649 }
650
651 if (gid_set && lchown(fname, -1, gid) < 0) {
652 wpa_printf(MSG_ERROR, "lchown[ctrl_interface=%s,gid=%d]: %s",
653 fname, (int) gid, strerror(errno));
654 goto fail;
655 }
656
657 if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
658 wpa_printf(MSG_ERROR, "chmod[ctrl_interface=%s]: %s",
659 fname, strerror(errno));
660 goto fail;
661 }
662 os_free(fname);
663
664 #ifdef ANDROID
665 havesock:
666 #endif /* ANDROID */
667
668 /*
669 * Make socket non-blocking so that we don't hang forever if
670 * target dies unexpectedly.
671 */
672 flags = fcntl(priv->sock, F_GETFL);
673 if (flags >= 0) {
674 flags |= O_NONBLOCK;
675 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
676 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
677 strerror(errno));
678 /* Not fatal, continue on.*/
679 }
680 }
681
682 eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
683 wpa_s, priv);
684 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
685
686 os_free(buf);
687 return 0;
688
689 fail:
690 if (priv->sock >= 0) {
691 close(priv->sock);
692 priv->sock = -1;
693 }
694 if (fname) {
695 unlink(fname);
696 os_free(fname);
697 }
698 os_free(buf);
699 return -1;
700 }
701
702
703 struct ctrl_iface_priv *
wpa_supplicant_ctrl_iface_init(struct wpa_supplicant * wpa_s)704 wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
705 {
706 struct ctrl_iface_priv *priv;
707
708 priv = os_zalloc(sizeof(*priv));
709 if (priv == NULL)
710 return NULL;
711 dl_list_init(&priv->ctrl_dst);
712 dl_list_init(&priv->msg_queue);
713 priv->wpa_s = wpa_s;
714 priv->sock = -1;
715
716 if (wpa_s->conf->ctrl_interface == NULL)
717 return priv;
718
719 #ifdef ANDROID
720 if (wpa_s->global->params.ctrl_interface) {
721 int same = 0;
722
723 if (wpa_s->global->params.ctrl_interface[0] == '/') {
724 if (os_strcmp(wpa_s->global->params.ctrl_interface,
725 wpa_s->conf->ctrl_interface) == 0)
726 same = 1;
727 } else if (os_strncmp(wpa_s->global->params.ctrl_interface,
728 "@android:", 9) == 0 ||
729 os_strncmp(wpa_s->global->params.ctrl_interface,
730 "@abstract:", 10) == 0) {
731 char *pos;
732
733 /*
734 * Currently, Android uses @android:wpa_* as the naming
735 * convention for the global ctrl interface. This logic
736 * needs to be revisited if the above naming convention
737 * is modified.
738 */
739 pos = os_strchr(wpa_s->global->params.ctrl_interface,
740 '_');
741 if (pos &&
742 os_strcmp(pos + 1,
743 wpa_s->conf->ctrl_interface) == 0)
744 same = 1;
745 }
746
747 if (same) {
748 /*
749 * The invalid configuration combination might be
750 * possible to hit in an Android OTA upgrade case, so
751 * instead of refusing to start the wpa_supplicant
752 * process, do not open the per-interface ctrl_iface
753 * and continue with the global control interface that
754 * was set from the command line since the Wi-Fi
755 * framework will use it for operations.
756 */
757 wpa_printf(MSG_ERROR,
758 "global ctrl interface %s matches ctrl interface %s - do not open per-interface ctrl interface",
759 wpa_s->global->params.ctrl_interface,
760 wpa_s->conf->ctrl_interface);
761 return priv;
762 }
763 }
764 #endif /* ANDROID */
765
766 if (wpas_ctrl_iface_open_sock(wpa_s, priv) < 0) {
767 os_free(priv);
768 return NULL;
769 }
770
771 return priv;
772 }
773
774
wpas_ctrl_iface_reinit(struct wpa_supplicant * wpa_s,struct ctrl_iface_priv * priv)775 static int wpas_ctrl_iface_reinit(struct wpa_supplicant *wpa_s,
776 struct ctrl_iface_priv *priv)
777 {
778 int res;
779
780 if (priv->sock <= 0)
781 return -1;
782
783 /*
784 * On Android, the control socket being used may be the socket
785 * that is created when wpa_supplicant is started as a /init.*.rc
786 * service. Such a socket is maintained as a key-value pair in
787 * Android's environment. Closing this control socket would leave us
788 * in a bad state with an invalid socket descriptor.
789 */
790 if (priv->android_control_socket)
791 return priv->sock;
792
793 eloop_unregister_read_sock(priv->sock);
794 close(priv->sock);
795 priv->sock = -1;
796 res = wpas_ctrl_iface_open_sock(wpa_s, priv);
797 if (res < 0)
798 return -1;
799 return priv->sock;
800 }
801
802
803 static void
wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global * global,struct wpa_supplicant * wpa_s)804 wpas_global_ctrl_iface_flush_queued_msg(struct wpa_global *global,
805 struct wpa_supplicant *wpa_s)
806 {
807 struct ctrl_iface_global_priv *gpriv;
808 struct ctrl_iface_msg *msg, *prev_msg;
809 unsigned int count = 0;
810
811 if (!global || !global->ctrl_iface)
812 return;
813
814 gpriv = global->ctrl_iface;
815 dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
816 struct ctrl_iface_msg, list) {
817 if (msg->wpa_s == wpa_s) {
818 count++;
819 dl_list_del(&msg->list);
820 os_free(msg);
821 }
822 }
823
824 if (count) {
825 wpa_printf(MSG_DEBUG,
826 "CTRL: Dropped %u pending message(s) for interface that is being removed",
827 count);
828 }
829 }
830
831
wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant * wpa_s,struct ctrl_iface_priv * priv)832 void wpa_supplicant_ctrl_iface_deinit(struct wpa_supplicant *wpa_s,
833 struct ctrl_iface_priv *priv)
834 {
835 struct wpa_ctrl_dst *dst, *prev;
836 struct ctrl_iface_msg *msg, *prev_msg;
837 struct ctrl_iface_global_priv *gpriv;
838
839 if (!priv) {
840 /* Control interface has not yet been initialized, so there is
841 * nothing to deinitialize here. However, there might be a
842 * pending message for this interface, so get rid of any such
843 * entry before completing interface removal. */
844 wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
845 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, wpa_s, NULL);
846 return;
847 }
848
849 if (priv->sock > -1) {
850 char *fname;
851 char *buf, *dir = NULL;
852 eloop_unregister_read_sock(priv->sock);
853 if (!dl_list_empty(&priv->ctrl_dst)) {
854 /*
855 * Wait before closing the control socket if
856 * there are any attached monitors in order to allow
857 * them to receive any pending messages.
858 */
859 wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
860 "monitors to receive messages");
861 os_sleep(0, 100000);
862 }
863 close(priv->sock);
864 priv->sock = -1;
865 fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
866 if (fname) {
867 unlink(fname);
868 os_free(fname);
869 }
870
871 if (priv->wpa_s->conf->ctrl_interface == NULL)
872 goto free_dst;
873 buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
874 if (buf == NULL)
875 goto free_dst;
876 if (os_strncmp(buf, "DIR=", 4) == 0) {
877 char *gid_str;
878 dir = buf + 4;
879 gid_str = os_strstr(dir, " GROUP=");
880 if (gid_str)
881 *gid_str = '\0';
882 } else
883 dir = buf;
884
885 if (rmdir(dir) < 0) {
886 if (errno == ENOTEMPTY) {
887 wpa_printf(MSG_DEBUG, "Control interface "
888 "directory not empty - leaving it "
889 "behind");
890 } else {
891 wpa_printf(MSG_ERROR,
892 "rmdir[ctrl_interface=%s]: %s",
893 dir, strerror(errno));
894 }
895 }
896 os_free(buf);
897 }
898
899 free_dst:
900 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
901 list) {
902 dl_list_del(&dst->list);
903 os_free(dst);
904 }
905 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue,
906 struct ctrl_iface_msg, list) {
907 dl_list_del(&msg->list);
908 os_free(msg);
909 }
910 gpriv = priv->wpa_s->global->ctrl_iface;
911 if (gpriv) {
912 dl_list_for_each_safe(msg, prev_msg, &gpriv->msg_queue,
913 struct ctrl_iface_msg, list) {
914 if (msg->wpa_s == priv->wpa_s) {
915 dl_list_del(&msg->list);
916 os_free(msg);
917 }
918 }
919 }
920 wpas_global_ctrl_iface_flush_queued_msg(wpa_s->global, wpa_s);
921 eloop_cancel_timeout(wpas_ctrl_msg_queue_timeout, priv->wpa_s, NULL);
922 os_free(priv);
923 }
924
925
926 /**
927 * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
928 * @ifname: Interface name for global control socket or %NULL
929 * @sock: Local socket fd
930 * @ctrl_dst: List of attached listeners
931 * @level: Priority level of the message
932 * @buf: Message data
933 * @len: Message length
934 *
935 * Send a packet to all monitor programs attached to the control interface.
936 */
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)937 static void wpa_supplicant_ctrl_iface_send(struct wpa_supplicant *wpa_s,
938 const char *ifname, int sock,
939 struct dl_list *ctrl_dst,
940 int level, const char *buf,
941 size_t len,
942 struct ctrl_iface_priv *priv,
943 struct ctrl_iface_global_priv *gp)
944 {
945 struct wpa_ctrl_dst *dst, *next;
946 char levelstr[10];
947 int idx, res;
948 struct msghdr msg;
949 struct iovec io[5];
950
951 if (sock < 0 || dl_list_empty(ctrl_dst))
952 return;
953
954 res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
955 if (os_snprintf_error(sizeof(levelstr), res))
956 return;
957 idx = 0;
958 if (ifname) {
959 io[idx].iov_base = "IFNAME=";
960 io[idx].iov_len = 7;
961 idx++;
962 io[idx].iov_base = (char *) ifname;
963 io[idx].iov_len = os_strlen(ifname);
964 idx++;
965 io[idx].iov_base = " ";
966 io[idx].iov_len = 1;
967 idx++;
968 }
969 io[idx].iov_base = levelstr;
970 io[idx].iov_len = os_strlen(levelstr);
971 idx++;
972 io[idx].iov_base = (char *) buf;
973 io[idx].iov_len = len;
974 idx++;
975 os_memset(&msg, 0, sizeof(msg));
976 msg.msg_iov = io;
977 msg.msg_iovlen = idx;
978
979 dl_list_for_each_safe(dst, next, ctrl_dst, struct wpa_ctrl_dst, list) {
980 int _errno;
981 char txt[200];
982
983 if (level < dst->debug_level)
984 continue;
985
986 msg.msg_name = (void *) &dst->addr;
987 msg.msg_namelen = dst->addrlen;
988 wpas_ctrl_sock_debug("ctrl_sock-sendmsg", sock, buf, len);
989 if (sendmsg(sock, &msg, MSG_DONTWAIT) >= 0) {
990 sockaddr_print(MSG_MSGDUMP,
991 "CTRL_IFACE monitor sent successfully to",
992 &dst->addr, dst->addrlen);
993 dst->errors = 0;
994 continue;
995 }
996
997 _errno = errno;
998 os_snprintf(txt, sizeof(txt), "CTRL_IFACE monitor: %d (%s) for",
999 _errno, strerror(_errno));
1000 sockaddr_print(MSG_DEBUG, txt, &dst->addr, dst->addrlen);
1001 dst->errors++;
1002
1003 if (dst->errors > 10 || _errno == ENOENT || _errno == EPERM) {
1004 sockaddr_print(MSG_INFO, "CTRL_IFACE: Detach monitor that cannot receive messages:",
1005 &dst->addr, dst->addrlen);
1006 wpa_supplicant_ctrl_iface_detach(ctrl_dst, &dst->addr,
1007 dst->addrlen);
1008 }
1009
1010 if (_errno == ENOBUFS || _errno == EAGAIN) {
1011 /*
1012 * The socket send buffer could be full. This may happen
1013 * if client programs are not receiving their pending
1014 * messages. Close and reopen the socket as a workaround
1015 * to avoid getting stuck being unable to send any new
1016 * responses.
1017 */
1018 if (priv)
1019 sock = wpas_ctrl_iface_reinit(wpa_s, priv);
1020 else if (gp)
1021 sock = wpas_ctrl_iface_global_reinit(
1022 wpa_s->global, gp);
1023 else
1024 break;
1025 if (sock < 0) {
1026 wpa_dbg(wpa_s, MSG_DEBUG,
1027 "Failed to reinitialize ctrl_iface socket");
1028 break;
1029 }
1030 }
1031 }
1032 }
1033
1034
wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv * priv)1035 void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
1036 {
1037 char buf[256];
1038 int res;
1039 struct sockaddr_storage from;
1040 socklen_t fromlen = sizeof(from);
1041
1042 if (priv->sock == -1)
1043 return;
1044
1045 for (;;) {
1046 wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
1047 "attach", priv->wpa_s->ifname);
1048 eloop_wait_for_read_sock(priv->sock);
1049
1050 res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
1051 (struct sockaddr *) &from, &fromlen);
1052 if (res < 0) {
1053 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
1054 strerror(errno));
1055 continue;
1056 }
1057 buf[res] = '\0';
1058
1059 if (os_strcmp(buf, "ATTACH") == 0) {
1060 /* handle ATTACH signal of first monitor interface */
1061 if (!wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst,
1062 &from, fromlen,
1063 0)) {
1064 if (sendto(priv->sock, "OK\n", 3, 0,
1065 (struct sockaddr *) &from, fromlen) <
1066 0) {
1067 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
1068 strerror(errno));
1069 }
1070 /* OK to continue */
1071 return;
1072 } else {
1073 if (sendto(priv->sock, "FAIL\n", 5, 0,
1074 (struct sockaddr *) &from, fromlen) <
1075 0) {
1076 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
1077 strerror(errno));
1078 }
1079 }
1080 } else {
1081 /* return FAIL for all other signals */
1082 if (sendto(priv->sock, "FAIL\n", 5, 0,
1083 (struct sockaddr *) &from, fromlen) < 0) {
1084 wpa_printf(MSG_DEBUG,
1085 "ctrl_iface sendto failed: %s",
1086 strerror(errno));
1087 }
1088 }
1089 }
1090 }
1091
1092
1093 /* Global ctrl_iface */
1094
wpa_supplicant_global_ctrl_iface_receive(int sock,void * eloop_ctx,void * sock_ctx)1095 static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
1096 void *sock_ctx)
1097 {
1098 struct wpa_global *global = eloop_ctx;
1099 struct ctrl_iface_global_priv *priv = sock_ctx;
1100 char *buf;
1101 int res;
1102 struct sockaddr_storage from;
1103 socklen_t fromlen = sizeof(from);
1104 char *reply = NULL, *reply_buf = NULL;
1105 size_t reply_len;
1106
1107 buf = os_malloc(CTRL_IFACE_MAX_LEN + 1);
1108 if (!buf)
1109 return;
1110 res = recvfrom(sock, buf, CTRL_IFACE_MAX_LEN + 1, 0,
1111 (struct sockaddr *) &from, &fromlen);
1112 if (res < 0) {
1113 wpa_printf(MSG_ERROR, "recvfrom(ctrl_iface): %s",
1114 strerror(errno));
1115 os_free(buf);
1116 return;
1117 }
1118 if ((size_t) res > CTRL_IFACE_MAX_LEN) {
1119 wpa_printf(MSG_ERROR, "recvform(ctrl_iface): input truncated");
1120 os_free(buf);
1121 return;
1122 }
1123 buf[res] = '\0';
1124
1125 if (os_strcmp(buf, "ATTACH") == 0) {
1126 if (wpa_supplicant_ctrl_iface_attach(&priv->ctrl_dst, &from,
1127 fromlen, 1))
1128 reply_len = 1;
1129 else
1130 reply_len = 2;
1131 } else if (os_strcmp(buf, "DETACH") == 0) {
1132 if (wpa_supplicant_ctrl_iface_detach(&priv->ctrl_dst, &from,
1133 fromlen))
1134 reply_len = 1;
1135 else
1136 reply_len = 2;
1137 } else {
1138 reply_buf = wpa_supplicant_global_ctrl_iface_process(
1139 global, buf, &reply_len);
1140 reply = reply_buf;
1141
1142 /*
1143 * There could be some password/key material in the command, so
1144 * clear the buffer explicitly now that it is not needed
1145 * anymore.
1146 */
1147 os_memset(buf, 0, res);
1148 }
1149
1150 if (!reply && reply_len == 1) {
1151 reply = "FAIL\n";
1152 reply_len = 5;
1153 } else if (!reply && reply_len == 2) {
1154 reply = "OK\n";
1155 reply_len = 3;
1156 }
1157
1158 if (reply) {
1159 wpas_ctrl_sock_debug("global_ctrl_sock-sendto",
1160 sock, reply, reply_len);
1161 if (sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
1162 fromlen) < 0) {
1163 wpa_printf(MSG_DEBUG, "ctrl_iface sendto failed: %s",
1164 strerror(errno));
1165 }
1166 }
1167 os_free(reply_buf);
1168 os_free(buf);
1169 }
1170
1171
wpas_global_ctrl_iface_open_sock(struct wpa_global * global,struct ctrl_iface_global_priv * priv)1172 static int wpas_global_ctrl_iface_open_sock(struct wpa_global *global,
1173 struct ctrl_iface_global_priv *priv)
1174 {
1175 struct sockaddr_un addr;
1176 const char *ctrl = global->params.ctrl_interface;
1177 int flags;
1178
1179 wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl);
1180
1181 #ifdef ANDROID
1182 if (os_strncmp(ctrl, "@android:", 9) == 0) {
1183 priv->sock = android_get_control_socket(ctrl + 9);
1184 if (priv->sock < 0) {
1185 wpa_printf(MSG_ERROR, "Failed to open Android control "
1186 "socket '%s'", ctrl + 9);
1187 goto fail;
1188 }
1189 wpa_printf(MSG_DEBUG, "Using Android control socket '%s'",
1190 ctrl + 9);
1191 priv->android_control_socket = 1;
1192 goto havesock;
1193 }
1194
1195 if (os_strncmp(ctrl, "@abstract:", 10) != 0) {
1196 /*
1197 * Backwards compatibility - try to open an Android control
1198 * socket and if that fails, assume this was a UNIX domain
1199 * socket instead.
1200 */
1201 priv->sock = android_get_control_socket(ctrl);
1202 if (priv->sock >= 0) {
1203 wpa_printf(MSG_DEBUG,
1204 "Using Android control socket '%s'",
1205 ctrl);
1206 priv->android_control_socket = 1;
1207 goto havesock;
1208 }
1209 }
1210 #endif /* ANDROID */
1211
1212 priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
1213 if (priv->sock < 0) {
1214 wpa_printf(MSG_ERROR, "socket(PF_UNIX): %s", strerror(errno));
1215 goto fail;
1216 }
1217
1218 os_memset(&addr, 0, sizeof(addr));
1219 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1220 addr.sun_len = sizeof(addr);
1221 #endif /* __FreeBSD__ */
1222 addr.sun_family = AF_UNIX;
1223
1224 if (os_strncmp(ctrl, "@abstract:", 10) == 0) {
1225 addr.sun_path[0] = '\0';
1226 os_strlcpy(addr.sun_path + 1, ctrl + 10,
1227 sizeof(addr.sun_path) - 1);
1228 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) <
1229 0) {
1230 wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: "
1231 "bind(PF_UNIX;%s) failed: %s",
1232 ctrl, strerror(errno));
1233 goto fail;
1234 }
1235 wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'",
1236 ctrl + 10);
1237 goto havesock;
1238 }
1239
1240 os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
1241 if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
1242 wpa_printf(MSG_INFO, "supp-global-ctrl-iface-init(%s) (will try fixup): bind(PF_UNIX): %s",
1243 ctrl, strerror(errno));
1244 if (connect(priv->sock, (struct sockaddr *) &addr,
1245 sizeof(addr)) < 0) {
1246 wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
1247 " allow connections - assuming it was left"
1248 "over from forced program termination");
1249 if (unlink(ctrl) < 0) {
1250 wpa_printf(MSG_ERROR,
1251 "Could not unlink existing ctrl_iface socket '%s': %s",
1252 ctrl, strerror(errno));
1253 goto fail;
1254 }
1255 if (bind(priv->sock, (struct sockaddr *) &addr,
1256 sizeof(addr)) < 0) {
1257 wpa_printf(MSG_ERROR, "supp-glb-iface-init: bind(PF_UNIX;%s): %s",
1258 ctrl, strerror(errno));
1259 goto fail;
1260 }
1261 wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
1262 "ctrl_iface socket '%s'",
1263 ctrl);
1264 } else {
1265 wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
1266 "be in use - cannot override it");
1267 wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
1268 "not used anymore",
1269 ctrl);
1270 goto fail;
1271 }
1272 }
1273
1274 wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl);
1275
1276 if (global->params.ctrl_interface_group) {
1277 char *gid_str = global->params.ctrl_interface_group;
1278 gid_t gid = 0;
1279 struct group *grp;
1280 char *endp;
1281
1282 grp = getgrnam(gid_str);
1283 if (grp) {
1284 gid = grp->gr_gid;
1285 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
1286 " (from group name '%s')",
1287 (int) gid, gid_str);
1288 } else {
1289 /* Group name not found - try to parse this as gid */
1290 gid = strtol(gid_str, &endp, 10);
1291 if (*gid_str == '\0' || *endp != '\0') {
1292 wpa_printf(MSG_ERROR, "CTRL: Invalid group "
1293 "'%s'", gid_str);
1294 goto fail;
1295 }
1296 wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
1297 (int) gid);
1298 }
1299 if (lchown(ctrl, -1, gid) < 0) {
1300 wpa_printf(MSG_ERROR,
1301 "lchown[global_ctrl_interface=%s,gid=%d]: %s",
1302 ctrl, (int) gid, strerror(errno));
1303 goto fail;
1304 }
1305
1306 if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) {
1307 wpa_printf(MSG_ERROR,
1308 "chmod[global_ctrl_interface=%s]: %s",
1309 ctrl, strerror(errno));
1310 goto fail;
1311 }
1312 } else {
1313 if (chmod(ctrl, S_IRWXU) < 0) {
1314 wpa_printf(MSG_DEBUG,
1315 "chmod[global_ctrl_interface=%s](S_IRWXU): %s",
1316 ctrl, strerror(errno));
1317 /* continue anyway since group change was not required
1318 */
1319 }
1320 }
1321
1322 havesock:
1323
1324 /*
1325 * Make socket non-blocking so that we don't hang forever if
1326 * target dies unexpectedly.
1327 */
1328 flags = fcntl(priv->sock, F_GETFL);
1329 if (flags >= 0) {
1330 flags |= O_NONBLOCK;
1331 if (fcntl(priv->sock, F_SETFL, flags) < 0) {
1332 wpa_printf(MSG_INFO, "fcntl(ctrl, O_NONBLOCK): %s",
1333 strerror(errno));
1334 /* Not fatal, continue on.*/
1335 }
1336 }
1337
1338 eloop_register_read_sock(priv->sock,
1339 wpa_supplicant_global_ctrl_iface_receive,
1340 global, priv);
1341
1342 return 0;
1343
1344 fail:
1345 if (priv->sock >= 0) {
1346 close(priv->sock);
1347 priv->sock = -1;
1348 }
1349 return -1;
1350 }
1351
1352
1353 struct ctrl_iface_global_priv *
wpa_supplicant_global_ctrl_iface_init(struct wpa_global * global)1354 wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
1355 {
1356 struct ctrl_iface_global_priv *priv;
1357
1358 priv = os_zalloc(sizeof(*priv));
1359 if (priv == NULL)
1360 return NULL;
1361 dl_list_init(&priv->ctrl_dst);
1362 dl_list_init(&priv->msg_queue);
1363 priv->global = global;
1364 priv->sock = -1;
1365
1366 if (global->params.ctrl_interface == NULL)
1367 return priv;
1368
1369 if (wpas_global_ctrl_iface_open_sock(global, priv) < 0) {
1370 os_free(priv);
1371 return NULL;
1372 }
1373
1374 wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
1375
1376 return priv;
1377 }
1378
1379
wpas_ctrl_iface_global_reinit(struct wpa_global * global,struct ctrl_iface_global_priv * priv)1380 static int wpas_ctrl_iface_global_reinit(struct wpa_global *global,
1381 struct ctrl_iface_global_priv *priv)
1382 {
1383 int res;
1384
1385 if (priv->sock <= 0)
1386 return -1;
1387
1388 /*
1389 * On Android, the control socket being used may be the socket
1390 * that is created when wpa_supplicant is started as a /init.*.rc
1391 * service. Such a socket is maintained as a key-value pair in
1392 * Android's environment. Closing this control socket would leave us
1393 * in a bad state with an invalid socket descriptor.
1394 */
1395 if (priv->android_control_socket)
1396 return priv->sock;
1397
1398 eloop_unregister_read_sock(priv->sock);
1399 close(priv->sock);
1400 priv->sock = -1;
1401 res = wpas_global_ctrl_iface_open_sock(global, priv);
1402 if (res < 0)
1403 return -1;
1404 return priv->sock;
1405 }
1406
1407
1408 void
wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv * priv)1409 wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
1410 {
1411 struct wpa_ctrl_dst *dst, *prev;
1412 struct ctrl_iface_msg *msg, *prev_msg;
1413
1414 if (priv->sock >= 0) {
1415 eloop_unregister_read_sock(priv->sock);
1416 close(priv->sock);
1417 }
1418 if (priv->global->params.ctrl_interface)
1419 unlink(priv->global->params.ctrl_interface);
1420 dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
1421 list) {
1422 dl_list_del(&dst->list);
1423 os_free(dst);
1424 }
1425 dl_list_for_each_safe(msg, prev_msg, &priv->msg_queue,
1426 struct ctrl_iface_msg, list) {
1427 dl_list_del(&msg->list);
1428 os_free(msg);
1429 }
1430 os_free(priv);
1431 }
1432