Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge branch 'jb48769' into 'master'
[connman] Prevent IPv4 only VPN data and DNS leak to IPv6. Fixes JB#48769

See merge request mer-core/connman!257
  • Loading branch information
LaakkonenJussi committed Mar 17, 2021
2 parents 60dcd1b + 93f0a73 commit 15e368f
Show file tree
Hide file tree
Showing 10 changed files with 977 additions and 468 deletions.
2 changes: 1 addition & 1 deletion connman/Makefile.am
Expand Up @@ -370,7 +370,7 @@ unit_test_service_SOURCES = $(backtrace_sources) $(gdhcp_sources) \
$(gweb_sources) $(shared_sources) \
unit/test-service.c \
src/connman.h src/log.c src/error.c src/task.c \
src/device.c src/network.c src/connection.c \
src/device.c src/network.c \
src/manager.c src/agent-connman.c src/clock.c \
src/timezone.c src/agent.c src/notifier.c \
src/resolver.c src/ipconfig.c src/detect.c \
Expand Down
22 changes: 15 additions & 7 deletions connman/plugins/vpn.c
Expand Up @@ -155,6 +155,8 @@ static const char *get_string(struct connman_provider *provider,
return data->host_ip[0];
} else if (g_str_equal(key, "VPN.Domain"))
return data->domain;
else if (g_str_equal(key, "Transport"))
return data->service_ident;

return g_hash_table_lookup(data->setting_strings, key);
}
Expand Down Expand Up @@ -270,14 +272,12 @@ static bool provider_is_connected(struct connection_data *data)
static void set_provider_state(struct connection_data *data)
{
enum connman_provider_state state = CONNMAN_PROVIDER_STATE_UNKNOWN;
bool connected;
int err = 0;

DBG("provider %p new state %s", data->provider, data->state);

if (!provider_is_connected(data)) {
g_free(data->service_ident);
data->service_ident = NULL;
}
connected = provider_is_connected(data);

if (g_str_equal(data->state, "ready")) {
state = CONNMAN_PROVIDER_STATE_READY;
Expand All @@ -297,7 +297,7 @@ static void set_provider_state(struct connection_data *data)
}

connman_provider_set_state(data->provider, state);
return;
goto free;

set:
if (data->cb_data)
Expand All @@ -308,6 +308,12 @@ static void set_provider_state(struct connection_data *data)

free_config_cb_data(data->cb_data);
data->cb_data = NULL;

free:
if (!connected) {
g_free(data->service_ident);
data->service_ident = NULL;
}
}

static int create_provider(struct connection_data *data, void *user_data)
Expand Down Expand Up @@ -1045,12 +1051,14 @@ static int disconnect_provider(struct connection_data *data)
dbus_pending_call_set_notify(data->disconnect_call, disconnect_reply,
data, NULL);

g_free(data->service_ident);
data->service_ident = NULL;
data->default_route_set = false;

connman_provider_set_state(data->provider,
CONNMAN_PROVIDER_STATE_DISCONNECT);

g_free(data->service_ident);
data->service_ident = NULL;

return -EINPROGRESS;
}

Expand Down
16 changes: 13 additions & 3 deletions connman/src/connman.h
Expand Up @@ -435,8 +435,11 @@ void __connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
const struct connman_ipconfig_ops *ops);
int __connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
enum connman_ipconfig_method method);
void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig);
void __connman_ipconfig_disable_ipv6(struct connman_ipconfig *ipconfig,
bool forced);
int __connman_ipconfig_enable_ipv6(struct connman_ipconfig *ipconfig,
bool forced);
int __connman_ipconfig_set_ipv6_support(bool enable);

int __connman_ipconfig_init(void);
void __connman_ipconfig_cleanup(void);
Expand Down Expand Up @@ -705,7 +708,8 @@ int __connman_network_disconnect(struct connman_network *network);
int __connman_network_clear_ipconfig(struct connman_network *network,
struct connman_ipconfig *ipconfig);
int __connman_network_enable_ipconfig(struct connman_network *network,
struct connman_ipconfig *ipconfig);
struct connman_ipconfig *ipconfig,
bool force);

const char *__connman_network_get_type(struct connman_network *network);
const char *__connman_network_get_group(struct connman_network *network);
Expand Down Expand Up @@ -761,13 +765,17 @@ void __connman_provider_list(DBusMessageIter *iter, void *user_data);
bool __connman_provider_is_immutable(struct connman_provider *provider);
int __connman_provider_create_and_connect(DBusMessage *msg);
const char * __connman_provider_get_ident(struct connman_provider *provider);
const char * __connman_provider_get_transport_ident(
struct connman_provider *provider);
int __connman_provider_indicate_state(struct connman_provider *provider,
enum connman_provider_state state);
int __connman_provider_indicate_error(struct connman_provider *provider,
enum connman_provider_error error);
int __connman_provider_connect(struct connman_provider *provider,
const char *dbus_sender);
int __connman_provider_remove_by_path(const char *path);
int __connman_provider_toggle_transport_ipv6(struct connman_provider *provider,
bool disable);
void __connman_provider_cleanup(void);
int __connman_provider_init(void);

Expand Down Expand Up @@ -805,6 +813,8 @@ struct connman_ipconfig *__connman_service_get_ipconfig(
struct connman_service *service, int family);
void __connman_service_notify_ipv4_configuration(
struct connman_service *service);
void __connman_service_notify_ipv6_configuration(
struct connman_service *service);
bool __connman_service_is_connected_state(struct connman_service *service,
enum connman_ipconfig_type type);
const char *__connman_service_get_path(struct connman_service *service);
Expand Down
36 changes: 14 additions & 22 deletions connman/src/dnsproxy.c
Expand Up @@ -2569,8 +2569,6 @@ static struct server_data *create_server(int index,
{
struct server_data *data;
struct addrinfo hints, *rp;
struct connman_service *service;
GSList *vpn_index_list;
int ret;

DBG("index %d server %s", index, server);
Expand Down Expand Up @@ -2645,9 +2643,6 @@ static struct server_data *create_server(int index,
return NULL;
}

service = connman_service_get_default();
vpn_index_list = __connman_service_get_depending_vpn_index(service);

if (protocol == IPPROTO_UDP) {
if (__connman_service_index_is_default(data->index) ||
__connman_service_index_is_split_routing(
Expand All @@ -2656,19 +2651,11 @@ static struct server_data *create_server(int index,
DBG("Adding DNS server %s", data->server);

enable_fallback(false);
} else if (vpn_index_list && g_slist_index(vpn_index_list,
GINT_TO_POINTER(data->index)) != -1) {
data->enabled = true;
DBG("Adding DNS server of depending VPN %s",
data->server);
}

server_list = g_slist_append(server_list, data);
}

if (vpn_index_list)
g_slist_free(vpn_index_list);

return data;
}

Expand Down Expand Up @@ -2896,7 +2883,7 @@ static void dnsproxy_default_changed(struct connman_service *service)
bool server_enabled = false;
GSList *list;
int index;
GSList *vpn_index_list;
int vpn_index;

DBG("service %p", service);

Expand All @@ -2913,7 +2900,12 @@ static void dnsproxy_default_changed(struct connman_service *service)
if (index < 0)
return;

vpn_index_list = __connman_service_get_depending_vpn_index(service);
/*
* In case non-split-routed VPN is set as split routed the DNS servers
* the VPN must be enabled as well, when the transport becomes the
* default service.
*/
vpn_index = __connman_connection_get_vpn_index(index);

for (list = server_list; list; list = list->next) {
struct server_data *data = list->data;
Expand All @@ -2922,20 +2914,15 @@ static void dnsproxy_default_changed(struct connman_service *service)
DBG("Enabling DNS server %s", data->server);
data->enabled = true;
server_enabled = true;
} else if (vpn_index_list && g_slist_index(vpn_index_list,
GINT_TO_POINTER(data->index)) != -1) {
DBG("Enabling DNS server of depending VPN %s",
data->server);
} else if (data->index == vpn_index) {
DBG("Enabling DNS server of VPN %s", data->server);
data->enabled = true;
} else {
DBG("Disabling DNS server %s", data->server);
data->enabled = false;
}
}

if (vpn_index_list)
g_slist_free(vpn_index_list);

if (!server_enabled)
enable_fallback(true);

Expand Down Expand Up @@ -4031,4 +4018,9 @@ void __connman_dnsproxy_cleanup(void)
g_hash_table_destroy(listener_table);

g_hash_table_destroy(partial_tcp_req_table);

if (ipv4_resolve)
g_resolv_unref(ipv4_resolve);
if (ipv6_resolve)
g_resolv_unref(ipv6_resolve);
}

0 comments on commit 15e368f

Please sign in to comment.