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