ctrl_iface_unix.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797
  1. /*
  2. * WPA Supplicant / UNIX domain socket -based control interface
  3. * Copyright (c) 2004-2013, 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. #include "includes.h"
  9. #include <sys/un.h>
  10. #include <sys/stat.h>
  11. #include <grp.h>
  12. #include <stddef.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #ifdef ANDROID
  16. #include <cutils/sockets.h>
  17. #endif /* ANDROID */
  18. #include "utils/common.h"
  19. #include "utils/eloop.h"
  20. #include "utils/list.h"
  21. #include "eapol_supp/eapol_supp_sm.h"
  22. #include "config.h"
  23. #include "wpa_supplicant_i.h"
  24. #include "ctrl_iface.h"
  25. /* Per-interface ctrl_iface */
  26. /**
  27. * struct wpa_ctrl_dst - Internal data structure of control interface monitors
  28. *
  29. * This structure is used to store information about registered control
  30. * interface monitors into struct wpa_supplicant. This data is private to
  31. * ctrl_iface_unix.c and should not be touched directly from other files.
  32. */
  33. struct wpa_ctrl_dst {
  34. struct dl_list list;
  35. struct sockaddr_un addr;
  36. socklen_t addrlen;
  37. int debug_level;
  38. int errors;
  39. };
  40. struct ctrl_iface_priv {
  41. struct wpa_supplicant *wpa_s;
  42. int sock;
  43. struct dl_list ctrl_dst;
  44. };
  45. static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
  46. int level, const char *buf,
  47. size_t len);
  48. static int wpa_supplicant_ctrl_iface_attach(struct ctrl_iface_priv *priv,
  49. struct sockaddr_un *from,
  50. socklen_t fromlen)
  51. {
  52. struct wpa_ctrl_dst *dst;
  53. dst = os_zalloc(sizeof(*dst));
  54. if (dst == NULL)
  55. return -1;
  56. os_memcpy(&dst->addr, from, sizeof(struct sockaddr_un));
  57. dst->addrlen = fromlen;
  58. dst->debug_level = MSG_INFO;
  59. dl_list_add(&priv->ctrl_dst, &dst->list);
  60. wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor attached",
  61. (u8 *) from->sun_path,
  62. fromlen - offsetof(struct sockaddr_un, sun_path));
  63. return 0;
  64. }
  65. static int wpa_supplicant_ctrl_iface_detach(struct ctrl_iface_priv *priv,
  66. struct sockaddr_un *from,
  67. socklen_t fromlen)
  68. {
  69. struct wpa_ctrl_dst *dst;
  70. dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
  71. if (fromlen == dst->addrlen &&
  72. os_memcmp(from->sun_path, dst->addr.sun_path,
  73. fromlen - offsetof(struct sockaddr_un, sun_path))
  74. == 0) {
  75. dl_list_del(&dst->list);
  76. os_free(dst);
  77. wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor detached",
  78. (u8 *) from->sun_path,
  79. fromlen -
  80. offsetof(struct sockaddr_un, sun_path));
  81. return 0;
  82. }
  83. }
  84. return -1;
  85. }
  86. static int wpa_supplicant_ctrl_iface_level(struct ctrl_iface_priv *priv,
  87. struct sockaddr_un *from,
  88. socklen_t fromlen,
  89. char *level)
  90. {
  91. struct wpa_ctrl_dst *dst;
  92. wpa_printf(MSG_DEBUG, "CTRL_IFACE LEVEL %s", level);
  93. dl_list_for_each(dst, &priv->ctrl_dst, struct wpa_ctrl_dst, list) {
  94. if (fromlen == dst->addrlen &&
  95. os_memcmp(from->sun_path, dst->addr.sun_path,
  96. fromlen - offsetof(struct sockaddr_un, sun_path))
  97. == 0) {
  98. wpa_hexdump(MSG_DEBUG, "CTRL_IFACE changed monitor "
  99. "level", (u8 *) from->sun_path,
  100. fromlen -
  101. offsetof(struct sockaddr_un, sun_path));
  102. dst->debug_level = atoi(level);
  103. return 0;
  104. }
  105. }
  106. return -1;
  107. }
  108. static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx,
  109. void *sock_ctx)
  110. {
  111. struct wpa_supplicant *wpa_s = eloop_ctx;
  112. struct ctrl_iface_priv *priv = sock_ctx;
  113. char buf[4096];
  114. int res;
  115. struct sockaddr_un from;
  116. socklen_t fromlen = sizeof(from);
  117. char *reply = NULL;
  118. size_t reply_len = 0;
  119. int new_attached = 0;
  120. res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
  121. (struct sockaddr *) &from, &fromlen);
  122. if (res < 0) {
  123. perror("recvfrom(ctrl_iface)");
  124. return;
  125. }
  126. buf[res] = '\0';
  127. if (os_strcmp(buf, "ATTACH") == 0) {
  128. if (wpa_supplicant_ctrl_iface_attach(priv, &from, fromlen))
  129. reply_len = 1;
  130. else {
  131. new_attached = 1;
  132. reply_len = 2;
  133. }
  134. } else if (os_strcmp(buf, "DETACH") == 0) {
  135. if (wpa_supplicant_ctrl_iface_detach(priv, &from, fromlen))
  136. reply_len = 1;
  137. else
  138. reply_len = 2;
  139. } else if (os_strncmp(buf, "LEVEL ", 6) == 0) {
  140. if (wpa_supplicant_ctrl_iface_level(priv, &from, fromlen,
  141. buf + 6))
  142. reply_len = 1;
  143. else
  144. reply_len = 2;
  145. } else {
  146. reply = wpa_supplicant_ctrl_iface_process(wpa_s, buf,
  147. &reply_len);
  148. }
  149. if (reply) {
  150. sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
  151. fromlen);
  152. os_free(reply);
  153. } else if (reply_len == 1) {
  154. sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
  155. fromlen);
  156. } else if (reply_len == 2) {
  157. sendto(sock, "OK\n", 3, 0, (struct sockaddr *) &from,
  158. fromlen);
  159. }
  160. if (new_attached)
  161. eapol_sm_notify_ctrl_attached(wpa_s->eapol);
  162. }
  163. static char * wpa_supplicant_ctrl_iface_path(struct wpa_supplicant *wpa_s)
  164. {
  165. char *buf;
  166. size_t len;
  167. char *pbuf, *dir = NULL, *gid_str = NULL;
  168. int res;
  169. if (wpa_s->conf->ctrl_interface == NULL)
  170. return NULL;
  171. pbuf = os_strdup(wpa_s->conf->ctrl_interface);
  172. if (pbuf == NULL)
  173. return NULL;
  174. if (os_strncmp(pbuf, "DIR=", 4) == 0) {
  175. dir = pbuf + 4;
  176. gid_str = os_strstr(dir, " GROUP=");
  177. if (gid_str) {
  178. *gid_str = '\0';
  179. gid_str += 7;
  180. }
  181. } else
  182. dir = pbuf;
  183. len = os_strlen(dir) + os_strlen(wpa_s->ifname) + 2;
  184. buf = os_malloc(len);
  185. if (buf == NULL) {
  186. os_free(pbuf);
  187. return NULL;
  188. }
  189. res = os_snprintf(buf, len, "%s/%s", dir, wpa_s->ifname);
  190. if (res < 0 || (size_t) res >= len) {
  191. os_free(pbuf);
  192. os_free(buf);
  193. return NULL;
  194. }
  195. #ifdef __CYGWIN__
  196. {
  197. /* Windows/WinPcap uses interface names that are not suitable
  198. * as a file name - convert invalid chars to underscores */
  199. char *pos = buf;
  200. while (*pos) {
  201. if (*pos == '\\')
  202. *pos = '_';
  203. pos++;
  204. }
  205. }
  206. #endif /* __CYGWIN__ */
  207. os_free(pbuf);
  208. return buf;
  209. }
  210. static void wpa_supplicant_ctrl_iface_msg_cb(void *ctx, int level,
  211. const char *txt, size_t len)
  212. {
  213. struct wpa_supplicant *wpa_s = ctx;
  214. if (wpa_s == NULL || wpa_s->ctrl_iface == NULL)
  215. return;
  216. wpa_supplicant_ctrl_iface_send(wpa_s->ctrl_iface, level, txt, len);
  217. }
  218. struct ctrl_iface_priv *
  219. wpa_supplicant_ctrl_iface_init(struct wpa_supplicant *wpa_s)
  220. {
  221. struct ctrl_iface_priv *priv;
  222. struct sockaddr_un addr;
  223. char *fname = NULL;
  224. gid_t gid = 0;
  225. int gid_set = 0;
  226. char *buf, *dir = NULL, *gid_str = NULL;
  227. struct group *grp;
  228. char *endp;
  229. int flags;
  230. priv = os_zalloc(sizeof(*priv));
  231. if (priv == NULL)
  232. return NULL;
  233. dl_list_init(&priv->ctrl_dst);
  234. priv->wpa_s = wpa_s;
  235. priv->sock = -1;
  236. if (wpa_s->conf->ctrl_interface == NULL)
  237. return priv;
  238. buf = os_strdup(wpa_s->conf->ctrl_interface);
  239. if (buf == NULL)
  240. goto fail;
  241. #ifdef ANDROID
  242. os_snprintf(addr.sun_path, sizeof(addr.sun_path), "wpa_%s",
  243. wpa_s->conf->ctrl_interface);
  244. priv->sock = android_get_control_socket(addr.sun_path);
  245. if (priv->sock >= 0)
  246. goto havesock;
  247. #endif /* ANDROID */
  248. if (os_strncmp(buf, "DIR=", 4) == 0) {
  249. dir = buf + 4;
  250. gid_str = os_strstr(dir, " GROUP=");
  251. if (gid_str) {
  252. *gid_str = '\0';
  253. gid_str += 7;
  254. }
  255. } else {
  256. dir = buf;
  257. gid_str = wpa_s->conf->ctrl_interface_group;
  258. }
  259. if (mkdir(dir, S_IRWXU | S_IRWXG) < 0) {
  260. if (errno == EEXIST) {
  261. wpa_printf(MSG_DEBUG, "Using existing control "
  262. "interface directory.");
  263. } else {
  264. perror("mkdir[ctrl_interface]");
  265. goto fail;
  266. }
  267. }
  268. #ifdef ANDROID
  269. /*
  270. * wpa_supplicant is started from /init.*.rc on Android and that seems
  271. * to be using umask 0077 which would leave the control interface
  272. * directory without group access. This breaks things since Wi-Fi
  273. * framework assumes that this directory can be accessed by other
  274. * applications in the wifi group. Fix this by adding group access even
  275. * if umask value would prevent this.
  276. */
  277. if (chmod(dir, S_IRWXU | S_IRWXG) < 0) {
  278. wpa_printf(MSG_ERROR, "CTRL: Could not chmod directory: %s",
  279. strerror(errno));
  280. /* Try to continue anyway */
  281. }
  282. #endif /* ANDROID */
  283. if (gid_str) {
  284. grp = getgrnam(gid_str);
  285. if (grp) {
  286. gid = grp->gr_gid;
  287. gid_set = 1;
  288. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
  289. " (from group name '%s')",
  290. (int) gid, gid_str);
  291. } else {
  292. /* Group name not found - try to parse this as gid */
  293. gid = strtol(gid_str, &endp, 10);
  294. if (*gid_str == '\0' || *endp != '\0') {
  295. wpa_printf(MSG_ERROR, "CTRL: Invalid group "
  296. "'%s'", gid_str);
  297. goto fail;
  298. }
  299. gid_set = 1;
  300. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
  301. (int) gid);
  302. }
  303. }
  304. if (gid_set && chown(dir, -1, gid) < 0) {
  305. perror("chown[ctrl_interface]");
  306. goto fail;
  307. }
  308. /* Make sure the group can enter and read the directory */
  309. if (gid_set &&
  310. chmod(dir, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP) < 0) {
  311. wpa_printf(MSG_ERROR, "CTRL: chmod[ctrl_interface]: %s",
  312. strerror(errno));
  313. goto fail;
  314. }
  315. if (os_strlen(dir) + 1 + os_strlen(wpa_s->ifname) >=
  316. sizeof(addr.sun_path)) {
  317. wpa_printf(MSG_ERROR, "ctrl_iface path limit exceeded");
  318. goto fail;
  319. }
  320. priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
  321. if (priv->sock < 0) {
  322. perror("socket(PF_UNIX)");
  323. goto fail;
  324. }
  325. os_memset(&addr, 0, sizeof(addr));
  326. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  327. addr.sun_len = sizeof(addr);
  328. #endif /* __FreeBSD__ */
  329. addr.sun_family = AF_UNIX;
  330. fname = wpa_supplicant_ctrl_iface_path(wpa_s);
  331. if (fname == NULL)
  332. goto fail;
  333. os_strlcpy(addr.sun_path, fname, sizeof(addr.sun_path));
  334. if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  335. wpa_printf(MSG_DEBUG, "ctrl_iface bind(PF_UNIX) failed: %s",
  336. strerror(errno));
  337. if (connect(priv->sock, (struct sockaddr *) &addr,
  338. sizeof(addr)) < 0) {
  339. wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
  340. " allow connections - assuming it was left"
  341. "over from forced program termination");
  342. if (unlink(fname) < 0) {
  343. perror("unlink[ctrl_iface]");
  344. wpa_printf(MSG_ERROR, "Could not unlink "
  345. "existing ctrl_iface socket '%s'",
  346. fname);
  347. goto fail;
  348. }
  349. if (bind(priv->sock, (struct sockaddr *) &addr,
  350. sizeof(addr)) < 0) {
  351. perror("supp-ctrl-iface-init: bind(PF_UNIX)");
  352. goto fail;
  353. }
  354. wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
  355. "ctrl_iface socket '%s'", fname);
  356. } else {
  357. wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
  358. "be in use - cannot override it");
  359. wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
  360. "not used anymore", fname);
  361. os_free(fname);
  362. fname = NULL;
  363. goto fail;
  364. }
  365. }
  366. if (gid_set && chown(fname, -1, gid) < 0) {
  367. perror("chown[ctrl_interface/ifname]");
  368. goto fail;
  369. }
  370. if (chmod(fname, S_IRWXU | S_IRWXG) < 0) {
  371. perror("chmod[ctrl_interface/ifname]");
  372. goto fail;
  373. }
  374. os_free(fname);
  375. #ifdef ANDROID
  376. havesock:
  377. #endif /* ANDROID */
  378. /*
  379. * Make socket non-blocking so that we don't hang forever if
  380. * target dies unexpectedly.
  381. */
  382. flags = fcntl(priv->sock, F_GETFL);
  383. if (flags >= 0) {
  384. flags |= O_NONBLOCK;
  385. if (fcntl(priv->sock, F_SETFL, flags) < 0) {
  386. perror("fcntl(ctrl, O_NONBLOCK)");
  387. /* Not fatal, continue on.*/
  388. }
  389. }
  390. eloop_register_read_sock(priv->sock, wpa_supplicant_ctrl_iface_receive,
  391. wpa_s, priv);
  392. wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
  393. os_free(buf);
  394. return priv;
  395. fail:
  396. if (priv->sock >= 0)
  397. close(priv->sock);
  398. os_free(priv);
  399. if (fname) {
  400. unlink(fname);
  401. os_free(fname);
  402. }
  403. os_free(buf);
  404. return NULL;
  405. }
  406. void wpa_supplicant_ctrl_iface_deinit(struct ctrl_iface_priv *priv)
  407. {
  408. struct wpa_ctrl_dst *dst, *prev;
  409. if (priv->sock > -1) {
  410. char *fname;
  411. char *buf, *dir = NULL, *gid_str = NULL;
  412. eloop_unregister_read_sock(priv->sock);
  413. if (!dl_list_empty(&priv->ctrl_dst)) {
  414. /*
  415. * Wait a second before closing the control socket if
  416. * there are any attached monitors in order to allow
  417. * them to receive any pending messages.
  418. */
  419. wpa_printf(MSG_DEBUG, "CTRL_IFACE wait for attached "
  420. "monitors to receive messages");
  421. os_sleep(1, 0);
  422. }
  423. close(priv->sock);
  424. priv->sock = -1;
  425. fname = wpa_supplicant_ctrl_iface_path(priv->wpa_s);
  426. if (fname) {
  427. unlink(fname);
  428. os_free(fname);
  429. }
  430. buf = os_strdup(priv->wpa_s->conf->ctrl_interface);
  431. if (buf == NULL)
  432. goto free_dst;
  433. if (os_strncmp(buf, "DIR=", 4) == 0) {
  434. dir = buf + 4;
  435. gid_str = os_strstr(dir, " GROUP=");
  436. if (gid_str) {
  437. *gid_str = '\0';
  438. gid_str += 7;
  439. }
  440. } else
  441. dir = buf;
  442. if (rmdir(dir) < 0) {
  443. if (errno == ENOTEMPTY) {
  444. wpa_printf(MSG_DEBUG, "Control interface "
  445. "directory not empty - leaving it "
  446. "behind");
  447. } else {
  448. perror("rmdir[ctrl_interface]");
  449. }
  450. }
  451. os_free(buf);
  452. }
  453. free_dst:
  454. dl_list_for_each_safe(dst, prev, &priv->ctrl_dst, struct wpa_ctrl_dst,
  455. list)
  456. os_free(dst);
  457. os_free(priv);
  458. }
  459. /**
  460. * wpa_supplicant_ctrl_iface_send - Send a control interface packet to monitors
  461. * @priv: Pointer to private data from wpa_supplicant_ctrl_iface_init()
  462. * @level: Priority level of the message
  463. * @buf: Message data
  464. * @len: Message length
  465. *
  466. * Send a packet to all monitor programs attached to the control interface.
  467. */
  468. static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv,
  469. int level, const char *buf,
  470. size_t len)
  471. {
  472. struct wpa_ctrl_dst *dst, *next;
  473. char levelstr[10];
  474. int idx, res;
  475. struct msghdr msg;
  476. struct iovec io[2];
  477. if (priv->sock < 0 || dl_list_empty(&priv->ctrl_dst))
  478. return;
  479. res = os_snprintf(levelstr, sizeof(levelstr), "<%d>", level);
  480. if (res < 0 || (size_t) res >= sizeof(levelstr))
  481. return;
  482. io[0].iov_base = levelstr;
  483. io[0].iov_len = os_strlen(levelstr);
  484. io[1].iov_base = (char *) buf;
  485. io[1].iov_len = len;
  486. os_memset(&msg, 0, sizeof(msg));
  487. msg.msg_iov = io;
  488. msg.msg_iovlen = 2;
  489. idx = 0;
  490. dl_list_for_each_safe(dst, next, &priv->ctrl_dst, struct wpa_ctrl_dst,
  491. list) {
  492. if (level >= dst->debug_level) {
  493. wpa_hexdump(MSG_DEBUG, "CTRL_IFACE monitor send",
  494. (u8 *) dst->addr.sun_path, dst->addrlen -
  495. offsetof(struct sockaddr_un, sun_path));
  496. msg.msg_name = (void *) &dst->addr;
  497. msg.msg_namelen = dst->addrlen;
  498. if (sendmsg(priv->sock, &msg, 0) < 0) {
  499. int _errno = errno;
  500. wpa_printf(MSG_INFO, "CTRL_IFACE monitor[%d]: "
  501. "%d - %s",
  502. idx, errno, strerror(errno));
  503. dst->errors++;
  504. if (dst->errors > 1000 ||
  505. (_errno != ENOBUFS && dst->errors > 10) ||
  506. _errno == ENOENT) {
  507. wpa_supplicant_ctrl_iface_detach(
  508. priv, &dst->addr,
  509. dst->addrlen);
  510. }
  511. } else
  512. dst->errors = 0;
  513. }
  514. idx++;
  515. }
  516. }
  517. void wpa_supplicant_ctrl_iface_wait(struct ctrl_iface_priv *priv)
  518. {
  519. char buf[256];
  520. int res;
  521. struct sockaddr_un from;
  522. socklen_t fromlen = sizeof(from);
  523. for (;;) {
  524. wpa_printf(MSG_DEBUG, "CTRL_IFACE - %s - wait for monitor to "
  525. "attach", priv->wpa_s->ifname);
  526. eloop_wait_for_read_sock(priv->sock);
  527. res = recvfrom(priv->sock, buf, sizeof(buf) - 1, 0,
  528. (struct sockaddr *) &from, &fromlen);
  529. if (res < 0) {
  530. perror("recvfrom(ctrl_iface)");
  531. continue;
  532. }
  533. buf[res] = '\0';
  534. if (os_strcmp(buf, "ATTACH") == 0) {
  535. /* handle ATTACH signal of first monitor interface */
  536. if (!wpa_supplicant_ctrl_iface_attach(priv, &from,
  537. fromlen)) {
  538. sendto(priv->sock, "OK\n", 3, 0,
  539. (struct sockaddr *) &from, fromlen);
  540. /* OK to continue */
  541. return;
  542. } else {
  543. sendto(priv->sock, "FAIL\n", 5, 0,
  544. (struct sockaddr *) &from, fromlen);
  545. }
  546. } else {
  547. /* return FAIL for all other signals */
  548. sendto(priv->sock, "FAIL\n", 5, 0,
  549. (struct sockaddr *) &from, fromlen);
  550. }
  551. }
  552. }
  553. /* Global ctrl_iface */
  554. struct ctrl_iface_global_priv {
  555. struct wpa_global *global;
  556. int sock;
  557. };
  558. static void wpa_supplicant_global_ctrl_iface_receive(int sock, void *eloop_ctx,
  559. void *sock_ctx)
  560. {
  561. struct wpa_global *global = eloop_ctx;
  562. char buf[256];
  563. int res;
  564. struct sockaddr_un from;
  565. socklen_t fromlen = sizeof(from);
  566. char *reply;
  567. size_t reply_len;
  568. res = recvfrom(sock, buf, sizeof(buf) - 1, 0,
  569. (struct sockaddr *) &from, &fromlen);
  570. if (res < 0) {
  571. perror("recvfrom(ctrl_iface)");
  572. return;
  573. }
  574. buf[res] = '\0';
  575. reply = wpa_supplicant_global_ctrl_iface_process(global, buf,
  576. &reply_len);
  577. if (reply) {
  578. sendto(sock, reply, reply_len, 0, (struct sockaddr *) &from,
  579. fromlen);
  580. os_free(reply);
  581. } else if (reply_len) {
  582. sendto(sock, "FAIL\n", 5, 0, (struct sockaddr *) &from,
  583. fromlen);
  584. }
  585. }
  586. struct ctrl_iface_global_priv *
  587. wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
  588. {
  589. struct ctrl_iface_global_priv *priv;
  590. struct sockaddr_un addr;
  591. priv = os_zalloc(sizeof(*priv));
  592. if (priv == NULL)
  593. return NULL;
  594. priv->global = global;
  595. priv->sock = -1;
  596. if (global->params.ctrl_interface == NULL)
  597. return priv;
  598. #ifdef ANDROID
  599. priv->sock = android_get_control_socket(global->params.ctrl_interface);
  600. if (priv->sock >= 0)
  601. goto havesock;
  602. #endif /* ANDROID */
  603. wpa_printf(MSG_DEBUG, "Global control interface '%s'",
  604. global->params.ctrl_interface);
  605. priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
  606. if (priv->sock < 0) {
  607. perror("socket(PF_UNIX)");
  608. goto fail;
  609. }
  610. os_memset(&addr, 0, sizeof(addr));
  611. #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
  612. addr.sun_len = sizeof(addr);
  613. #endif /* __FreeBSD__ */
  614. addr.sun_family = AF_UNIX;
  615. os_strlcpy(addr.sun_path, global->params.ctrl_interface,
  616. sizeof(addr.sun_path));
  617. if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
  618. perror("supp-global-ctrl-iface-init (will try fixup): "
  619. "bind(PF_UNIX)");
  620. if (connect(priv->sock, (struct sockaddr *) &addr,
  621. sizeof(addr)) < 0) {
  622. wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
  623. " allow connections - assuming it was left"
  624. "over from forced program termination");
  625. if (unlink(global->params.ctrl_interface) < 0) {
  626. perror("unlink[ctrl_iface]");
  627. wpa_printf(MSG_ERROR, "Could not unlink "
  628. "existing ctrl_iface socket '%s'",
  629. global->params.ctrl_interface);
  630. goto fail;
  631. }
  632. if (bind(priv->sock, (struct sockaddr *) &addr,
  633. sizeof(addr)) < 0) {
  634. perror("supp-glb-iface-init: bind(PF_UNIX)");
  635. goto fail;
  636. }
  637. wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
  638. "ctrl_iface socket '%s'",
  639. global->params.ctrl_interface);
  640. } else {
  641. wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
  642. "be in use - cannot override it");
  643. wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
  644. "not used anymore",
  645. global->params.ctrl_interface);
  646. goto fail;
  647. }
  648. }
  649. if (global->params.ctrl_interface_group) {
  650. char *gid_str = global->params.ctrl_interface_group;
  651. gid_t gid = 0;
  652. struct group *grp;
  653. char *endp;
  654. grp = getgrnam(gid_str);
  655. if (grp) {
  656. gid = grp->gr_gid;
  657. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d"
  658. " (from group name '%s')",
  659. (int) gid, gid_str);
  660. } else {
  661. /* Group name not found - try to parse this as gid */
  662. gid = strtol(gid_str, &endp, 10);
  663. if (*gid_str == '\0' || *endp != '\0') {
  664. wpa_printf(MSG_ERROR, "CTRL: Invalid group "
  665. "'%s'", gid_str);
  666. goto fail;
  667. }
  668. wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
  669. (int) gid);
  670. }
  671. if (chown(global->params.ctrl_interface, -1, gid) < 0) {
  672. perror("chown[global_ctrl_interface/ifname]");
  673. goto fail;
  674. }
  675. if (chmod(global->params.ctrl_interface, S_IRWXU | S_IRWXG) < 0)
  676. {
  677. perror("chmod[global_ctrl_interface/ifname]");
  678. goto fail;
  679. }
  680. }
  681. #ifdef ANDROID
  682. havesock:
  683. #endif /* ANDROID */
  684. eloop_register_read_sock(priv->sock,
  685. wpa_supplicant_global_ctrl_iface_receive,
  686. global, NULL);
  687. return priv;
  688. fail:
  689. if (priv->sock >= 0)
  690. close(priv->sock);
  691. os_free(priv);
  692. return NULL;
  693. }
  694. void
  695. wpa_supplicant_global_ctrl_iface_deinit(struct ctrl_iface_global_priv *priv)
  696. {
  697. if (priv->sock >= 0) {
  698. eloop_unregister_read_sock(priv->sock);
  699. close(priv->sock);
  700. }
  701. if (priv->global->params.ctrl_interface)
  702. unlink(priv->global->params.ctrl_interface);
  703. os_free(priv);
  704. }