Abstract and Android sockets for global ctrl_iface
The wpa_supplicant global control interface parameter can now be used to explicitly specify an abstract UNIX domain socket (Linux specific extension) with "@abstract:" prefix and an Android control socket with "@android:" prefix. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
6fd5ceaf70
commit
d2a9e2c76d
2 changed files with 88 additions and 26 deletions
|
@ -82,6 +82,9 @@ struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
if (ctrl_path == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
ctrl = os_malloc(sizeof(*ctrl));
|
ctrl = os_malloc(sizeof(*ctrl));
|
||||||
if (ctrl == NULL)
|
if (ctrl == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -126,13 +129,27 @@ try_again:
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||||
chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
|
chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
|
||||||
|
|
||||||
|
if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
|
||||||
|
if (socket_local_client_connect(
|
||||||
|
ctrl->s, ctrl_path + 9,
|
||||||
|
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||||
|
SOCK_DGRAM) < 0) {
|
||||||
|
close(ctrl->s);
|
||||||
|
unlink(ctrl->local.sun_path);
|
||||||
|
os_free(ctrl);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ctrl;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the ctrl_path isn't an absolute pathname, assume that
|
* If the ctrl_path isn't an absolute pathname, assume that
|
||||||
* it's the name of a socket in the Android reserved namespace.
|
* it's the name of a socket in the Android reserved namespace.
|
||||||
* Otherwise, it's a normal UNIX domain socket appearing in the
|
* Otherwise, it's a normal UNIX domain socket appearing in the
|
||||||
* filesystem.
|
* filesystem.
|
||||||
*/
|
*/
|
||||||
if (ctrl_path != NULL && *ctrl_path != '/') {
|
if (*ctrl_path != '/') {
|
||||||
char buf[21];
|
char buf[21];
|
||||||
os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
|
os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
|
||||||
if (socket_local_client_connect(
|
if (socket_local_client_connect(
|
||||||
|
@ -149,6 +166,11 @@ try_again:
|
||||||
#endif /* ANDROID */
|
#endif /* ANDROID */
|
||||||
|
|
||||||
ctrl->dest.sun_family = AF_UNIX;
|
ctrl->dest.sun_family = AF_UNIX;
|
||||||
|
if (os_strncmp(ctrl_path, "@abstract:", 10) == 0) {
|
||||||
|
ctrl->dest.sun_path[0] = '\0';
|
||||||
|
os_strlcpy(ctrl->dest.sun_path + 1, ctrl_path + 10,
|
||||||
|
sizeof(ctrl->dest.sun_path) - 1);
|
||||||
|
} else {
|
||||||
res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
|
res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
|
||||||
sizeof(ctrl->dest.sun_path));
|
sizeof(ctrl->dest.sun_path));
|
||||||
if (res >= sizeof(ctrl->dest.sun_path)) {
|
if (res >= sizeof(ctrl->dest.sun_path)) {
|
||||||
|
@ -156,6 +178,7 @@ try_again:
|
||||||
os_free(ctrl);
|
os_free(ctrl);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
||||||
sizeof(ctrl->dest)) < 0) {
|
sizeof(ctrl->dest)) < 0) {
|
||||||
close(ctrl->s);
|
close(ctrl->s);
|
||||||
|
|
|
@ -667,6 +667,7 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
{
|
{
|
||||||
struct ctrl_iface_global_priv *priv;
|
struct ctrl_iface_global_priv *priv;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
|
const char *ctrl = global->params.ctrl_interface;
|
||||||
|
|
||||||
priv = os_zalloc(sizeof(*priv));
|
priv = os_zalloc(sizeof(*priv));
|
||||||
if (priv == NULL)
|
if (priv == NULL)
|
||||||
|
@ -674,17 +675,39 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
priv->global = global;
|
priv->global = global;
|
||||||
priv->sock = -1;
|
priv->sock = -1;
|
||||||
|
|
||||||
if (global->params.ctrl_interface == NULL)
|
if (ctrl == NULL)
|
||||||
return priv;
|
return priv;
|
||||||
|
|
||||||
#ifdef ANDROID
|
wpa_printf(MSG_DEBUG, "Global control interface '%s'", ctrl);
|
||||||
priv->sock = android_get_control_socket(global->params.ctrl_interface);
|
|
||||||
if (priv->sock >= 0)
|
|
||||||
goto havesock;
|
|
||||||
#endif /* ANDROID */
|
|
||||||
|
|
||||||
wpa_printf(MSG_DEBUG, "Global control interface '%s'",
|
#ifdef ANDROID
|
||||||
global->params.ctrl_interface);
|
if (os_strncmp(ctrl, "@android:", 9) == 0) {
|
||||||
|
priv->sock = android_get_control_socket(ctrl + 9);
|
||||||
|
if (priv->sock < 0) {
|
||||||
|
wpa_printf(MSG_ERROR, "Failed to open Android control "
|
||||||
|
"socket '%s'", ctrl + 9);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "Using Android control socket '%s'",
|
||||||
|
ctrl + 9);
|
||||||
|
goto havesock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (os_strncmp(ctrl, "@abstract:", 10) != 0) {
|
||||||
|
/*
|
||||||
|
* Backwards compatibility - try to open an Android control
|
||||||
|
* socket and if that fails, assume this was a UNIX domain
|
||||||
|
* socket instead.
|
||||||
|
*/
|
||||||
|
priv->sock = android_get_control_socket(ctrl);
|
||||||
|
if (priv->sock >= 0) {
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"Using Android control socket '%s'",
|
||||||
|
ctrl);
|
||||||
|
goto havesock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ANDROID */
|
||||||
|
|
||||||
priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
|
priv->sock = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||||
if (priv->sock < 0) {
|
if (priv->sock < 0) {
|
||||||
|
@ -697,8 +720,23 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
addr.sun_len = sizeof(addr);
|
addr.sun_len = sizeof(addr);
|
||||||
#endif /* __FreeBSD__ */
|
#endif /* __FreeBSD__ */
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
os_strlcpy(addr.sun_path, global->params.ctrl_interface,
|
|
||||||
sizeof(addr.sun_path));
|
if (os_strncmp(ctrl, "@abstract:", 10) == 0) {
|
||||||
|
addr.sun_path[0] = '\0';
|
||||||
|
os_strlcpy(addr.sun_path + 1, ctrl + 10,
|
||||||
|
sizeof(addr.sun_path) - 1);
|
||||||
|
if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) <
|
||||||
|
0) {
|
||||||
|
wpa_printf(MSG_ERROR, "supp-global-ctrl-iface-init: "
|
||||||
|
"bind(PF_UNIX) failed: %s", strerror(errno));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
wpa_printf(MSG_DEBUG, "Using Abstract control socket '%s'",
|
||||||
|
ctrl + 10);
|
||||||
|
goto havesock;
|
||||||
|
}
|
||||||
|
|
||||||
|
os_strlcpy(addr.sun_path, ctrl, sizeof(addr.sun_path));
|
||||||
if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
if (bind(priv->sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||||
perror("supp-global-ctrl-iface-init (will try fixup): "
|
perror("supp-global-ctrl-iface-init (will try fixup): "
|
||||||
"bind(PF_UNIX)");
|
"bind(PF_UNIX)");
|
||||||
|
@ -707,11 +745,11 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
|
wpa_printf(MSG_DEBUG, "ctrl_iface exists, but does not"
|
||||||
" allow connections - assuming it was left"
|
" allow connections - assuming it was left"
|
||||||
"over from forced program termination");
|
"over from forced program termination");
|
||||||
if (unlink(global->params.ctrl_interface) < 0) {
|
if (unlink(ctrl) < 0) {
|
||||||
perror("unlink[ctrl_iface]");
|
perror("unlink[ctrl_iface]");
|
||||||
wpa_printf(MSG_ERROR, "Could not unlink "
|
wpa_printf(MSG_ERROR, "Could not unlink "
|
||||||
"existing ctrl_iface socket '%s'",
|
"existing ctrl_iface socket '%s'",
|
||||||
global->params.ctrl_interface);
|
ctrl);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
if (bind(priv->sock, (struct sockaddr *) &addr,
|
if (bind(priv->sock, (struct sockaddr *) &addr,
|
||||||
|
@ -721,17 +759,19 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
}
|
}
|
||||||
wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
|
wpa_printf(MSG_DEBUG, "Successfully replaced leftover "
|
||||||
"ctrl_iface socket '%s'",
|
"ctrl_iface socket '%s'",
|
||||||
global->params.ctrl_interface);
|
ctrl);
|
||||||
} else {
|
} else {
|
||||||
wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
|
wpa_printf(MSG_INFO, "ctrl_iface exists and seems to "
|
||||||
"be in use - cannot override it");
|
"be in use - cannot override it");
|
||||||
wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
|
wpa_printf(MSG_INFO, "Delete '%s' manually if it is "
|
||||||
"not used anymore",
|
"not used anymore",
|
||||||
global->params.ctrl_interface);
|
ctrl);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_printf(MSG_DEBUG, "Using UNIX control socket '%s'", ctrl);
|
||||||
|
|
||||||
if (global->params.ctrl_interface_group) {
|
if (global->params.ctrl_interface_group) {
|
||||||
char *gid_str = global->params.ctrl_interface_group;
|
char *gid_str = global->params.ctrl_interface_group;
|
||||||
gid_t gid = 0;
|
gid_t gid = 0;
|
||||||
|
@ -755,21 +795,20 @@ wpa_supplicant_global_ctrl_iface_init(struct wpa_global *global)
|
||||||
wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
|
wpa_printf(MSG_DEBUG, "ctrl_interface_group=%d",
|
||||||
(int) gid);
|
(int) gid);
|
||||||
}
|
}
|
||||||
if (chown(global->params.ctrl_interface, -1, gid) < 0) {
|
if (chown(ctrl, -1, gid) < 0) {
|
||||||
perror("chown[global_ctrl_interface/ifname]");
|
perror("chown[global_ctrl_interface/ifname]");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chmod(global->params.ctrl_interface, S_IRWXU | S_IRWXG) < 0)
|
if (chmod(ctrl, S_IRWXU | S_IRWXG) < 0) {
|
||||||
{
|
|
||||||
perror("chmod[global_ctrl_interface/ifname]");
|
perror("chmod[global_ctrl_interface/ifname]");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
chmod(ctrl, S_IRWXU);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID
|
|
||||||
havesock:
|
havesock:
|
||||||
#endif /* ANDROID */
|
|
||||||
eloop_register_read_sock(priv->sock,
|
eloop_register_read_sock(priv->sock,
|
||||||
wpa_supplicant_global_ctrl_iface_receive,
|
wpa_supplicant_global_ctrl_iface_receive,
|
||||||
global, NULL);
|
global, NULL);
|
||||||
|
|
Loading…
Reference in a new issue