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