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