[PATCH 1/2] eap-tls: Dump server certificate when IWD_TLS_DEBUG set
by Andrew Zaborowski
---
src/eap-tls-common.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/src/eap-tls-common.c b/src/eap-tls-common.c
index c3eb5ab3..68e2a10c 100644
--- a/src/eap-tls-common.c
+++ b/src/eap-tls-common.c
@@ -583,9 +583,12 @@ static bool eap_tls_tunnel_init(struct eap_state *eap)
return false;
}
- if (getenv("IWD_TLS_DEBUG"))
+ if (getenv("IWD_TLS_DEBUG")) {
l_tls_set_debug(eap_tls->tunnel, eap_tls_tunnel_debug, eap,
NULL);
+ l_tls_set_cert_dump_path(eap_tls->tunnel,
+ "/tmp/iwd-tls-debug-server-cert.pem");
+ }
if (eap_tls->client_cert || eap_tls->client_key) {
if (!l_tls_set_auth_data(eap_tls->tunnel, eap_tls->client_cert,
--
2.27.0
1 year, 5 months
[PATCH] doc: move EnableIPv6 under Network
by Carlo Abelli
The EnableIPv6 option is incorrectly documented under General but should
be documented under Network instead.
---
src/iwd.config.rst | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/iwd.config.rst b/src/iwd.config.rst
index f74e31cf..365494a4 100644
--- a/src/iwd.config.rst
+++ b/src/iwd.config.rst
@@ -74,14 +74,6 @@ The group ``[General]`` contains general settings.
``[Network]`` settings for additional settings related to network
configuration.
- * - EnableIPv6
- - Values: true, **false**
-
- Sets the global default that tells **iwd** whether it should configure
- IPv6 addresses and routes (either provided via static settings,
- Router Advertisements or DHCPv6 protocol). This setting is disabled
- by default. This setting can also be overriden on a per-network basis.
-
* - APRanges
- Values: <IP in prefix notation>
@@ -186,6 +178,14 @@ The group ``[Network]`` contains network configuration related settings.
:widths: 20 80
:align: left
+ * - EnableIPv6
+ - Values: true, **false**
+
+ Sets the global default that tells **iwd** whether it should configure
+ IPv6 addresses and routes (either provided via static settings,
+ Router Advertisements or DHCPv6 protocol). This setting is disabled
+ by default. This setting can also be overriden on a per-network basis.
+
* - NameResolvingService
- Values: resolvconf, **systemd**
--
2.29.2
1 year, 6 months
[PATCH] configure.ac: fix static build with readline
by Fabrice Fontaine
Retrieve the dependencies of readline through pkg-config (and fallback
to -lreadline) to avoid the following build failure:
/nvme/rc-buildroot-test/scripts/instance-0/output-1/host/opt/ext-toolchain/bin/../lib/gcc/x86_64-buildroot-linux-uclibc/8.3.0/../../../../x86_64-buildroot-linux-uclibc/bin/ld: /nvme/rc-buildroot-test/scripts/instance-0/output-1/host/bin/../x86_64-buildroot-linux-uclibc/sysroot/usr/lib/libreadline.a(display.o): in function `cr':
display.c:(.text+0x1ab): undefined reference to `tputs'
Fixes:
- http://autobuild.buildroot.org/results/8fb1341f2f5094c346456b43b4fc04996c...
Signed-off-by: Fabrice Fontaine <fontaine.fabrice(a)gmail.com>
---
Makefile.am | 4 ++--
configure.ac | 3 +++
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 3cd7eaa6..493d06cc 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -288,7 +288,7 @@ client_iwctl_SOURCES = client/main.c \
client/network.h client/network.c \
client/properties.h client/properties.c \
client/wsc.c client/station.c
-client_iwctl_LDADD = $(ell_ldadd) -lreadline
+client_iwctl_LDADD = $(ell_ldadd) $(READLINE_LIBS)
if MANUAL_PAGES
man_MANS += client/iwctl.1
@@ -504,7 +504,7 @@ unit_test_client_SOURCES = unit/test-client.c \
client/display.h client/display.c \
client/network.h client/network.c \
client/properties.h client/properties.c
-unit_test_client_LDADD = $(ell_ldadd) -lreadline
+unit_test_client_LDADD = $(ell_ldadd) $(READLINE_LIBS)
endif
unit_test_sae_SOURCES = unit/test-sae.c \
diff --git a/configure.ac b/configure.ac
index 7bd917a4..52f27ed9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,6 +154,9 @@ AC_ARG_ENABLE([client], AC_HELP_STRING([--disable-client],
if (test "${enable_client}" != "no"); then
AC_CHECK_HEADERS(readline/readline.h, enable_readline=yes,
AC_MSG_ERROR(readline header files are required))
+ PKG_CHECK_MODULES(READLINE, readline, dummy=yes, READLINE_LIBS=-lreadline)
+ AC_SUBST(READLINE_CFLAGS)
+ AC_SUBST(READLINE_LIBS)
fi
AM_CONDITIONAL(CLIENT, test "${enable_client}" != "no")
--
2.29.2
1 year, 6 months
[PATCH 1/2] station: Split DBus scans into 3 frequency subsets
by Andrew Zaborowski
A scan normally takes about 2 seconds on my dual-band wifi adapter when
connected. The drivers will normally probe on each supported channel in
some unspecified order and will have new partial results after each step
but the kernel sends NL80211_CMD_NEW_SCAN_RESULTS only when the full
scan request finishes, and for segmented scans we will wait for all
segments to finish before calling back from scan_active() or
scan_passive().
To improve user experience define our own channel order favouring the
2.4 channels 1, 6 and 11 and probe those as an individual scan request
so we can update most our DBus org.connman.iwd.Network objects more
quickly, before continuing with 5GHz band channels, updating DBus
objects again and finally the other 2.4GHz band channels.
The overall DBus-triggered scan on my wifi adapter takes about the same
time but my measurements were not very strict, and were not very
consistent with and without this change. With the change most Network
objects are updated after about 200ms though, meaning that I get most
of the network updates in the nm-applet UI 200ms from opening the
network list. The 5GHz band channels take another 1 to 1.5s to scan and
remaining 2.4GHz band channels another ~300ms.
Hopefully this is similar when using other drivers although I can easily
imagine a driver that parallelizes 2.4GHz and 5GHz channel probing using
two radios, or uses 2, 4 or another number of dual-band radios to probe
2, 4, ... channels simultanously. We'd then lose some of the
performance benefit. The faster scan results may be worth the longer
overall scan time anyway.
I'm also assuming that the wiphy's supported frequency list is exactly
what was scanned when we passed no frequency list to
NL80211_CMD_TRIGGER_SCAN and we won't get errors for passing some
frequency that shouldn't have been scanned.
---
src/station.c | 120 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 107 insertions(+), 13 deletions(-)
diff --git a/src/station.c b/src/station.c
index ed3741d3..79b026b9 100644
--- a/src/station.c
+++ b/src/station.c
@@ -98,6 +98,10 @@ struct station {
/* Set of frequencies to scan first when attempting a roam */
struct scan_freq_set *roam_freqs;
+ /* Frequencies split into subsets by priority */
+ struct scan_freq_set *scan_freqs_order[3];
+ unsigned int dbus_scan_subset_idx;
+
bool preparing_roam : 1;
bool roam_scan_full : 1;
bool signal_low : 1;
@@ -2885,6 +2889,13 @@ static struct l_dbus_message *station_dbus_get_hidden_access_points(
return reply;
}
+static void station_dbus_scan_done(struct station *station)
+{
+ station->dbus_scan_id = 0;
+
+ station_property_set_scanning(station, false);
+}
+
static void station_dbus_scan_triggered(int err, void *user_data)
{
struct station *station = user_data;
@@ -2893,25 +2904,68 @@ static void station_dbus_scan_triggered(int err, void *user_data)
l_debug("station_scan_triggered: %i", err);
if (err < 0) {
- reply = dbus_error_from_errno(err, station->scan_pending);
- dbus_pending_reply(&station->scan_pending, reply);
+ if (station->scan_pending) {
+ reply = dbus_error_from_errno(err,
+ station->scan_pending);
+ dbus_pending_reply(&station->scan_pending, reply);
+ }
+
+ station_dbus_scan_done(station);
return;
}
- l_debug("Scan triggered for %s", netdev_get_name(station->netdev));
+ l_debug("Scan triggered for %s subset %i",
+ netdev_get_name(station->netdev),
+ station->dbus_scan_subset_idx);
- reply = l_dbus_message_new_method_return(station->scan_pending);
- l_dbus_message_set_arguments(reply, "");
- dbus_pending_reply(&station->scan_pending, reply);
+ if (station->scan_pending) {
+ reply = l_dbus_message_new_method_return(station->scan_pending);
+ l_dbus_message_set_arguments(reply, "");
+ dbus_pending_reply(&station->scan_pending, reply);
+ }
station_property_set_scanning(station, true);
}
-static void station_dbus_scan_destroy(void *userdata)
+static bool station_dbus_scan_subset(struct station *station);
+
+static bool station_dbus_scan_results(int err, struct l_queue *bss_list, void *userdata)
{
struct station *station = userdata;
+ unsigned int next_idx = station->dbus_scan_subset_idx + 1;
+ bool autoconnect;
+ bool last_subset;
- station->dbus_scan_id = 0;
+ if (err) {
+ station_dbus_scan_done(station);
+ return false;
+ }
+
+ autoconnect = station_is_autoconnecting(station);
+ last_subset = next_idx >= L_ARRAY_SIZE(station->scan_freqs_order) ||
+ station->scan_freqs_order[next_idx] == NULL;
+
+ station_set_scan_results(station, bss_list, autoconnect);
+
+ station->dbus_scan_subset_idx = next_idx;
+
+ if (last_subset || !station_dbus_scan_subset(station))
+ station_dbus_scan_done(station);
+
+ return true;
+}
+
+static bool station_dbus_scan_subset(struct station *station)
+{
+ unsigned int idx = station->dbus_scan_subset_idx;
+
+ station->dbus_scan_id = station_scan_trigger(station,
+ station->scan_freqs_order[idx],
+ station_dbus_scan_triggered,
+ station_dbus_scan_results,
+ NULL);
+
+ return station->dbus_scan_id != 0;
}
static struct l_dbus_message *station_dbus_scan(struct l_dbus *dbus,
@@ -2928,12 +2982,9 @@ static struct l_dbus_message *station_dbus_scan(struct l_dbus *dbus,
if (station->state == STATION_STATE_CONNECTING)
return dbus_error_busy(message);
- station->dbus_scan_id = station_scan_trigger(station, NULL,
- station_dbus_scan_triggered,
- new_scan_results,
- station_dbus_scan_destroy);
+ station->dbus_scan_subset_idx = 0;
- if (!station->dbus_scan_id)
+ if (!station_dbus_scan_subset(station))
return dbus_error_failed(message);
station->scan_pending = l_dbus_message_ref(message);
@@ -3209,6 +3260,41 @@ struct scan_bss *station_get_connected_bss(struct station *station)
return station->connected_bss;
}
+static void station_add_one_freq(uint32_t freq, void *user_data)
+{
+ struct station *station = user_data;
+
+ if (freq > 3000)
+ scan_freq_set_add(station->scan_freqs_order[1], freq);
+ else if (!scan_freq_set_contains(station->scan_freqs_order[0], freq))
+ scan_freq_set_add(station->scan_freqs_order[2], freq);
+}
+
+static void station_fill_scan_freq_subsets(struct station *station)
+{
+ const struct scan_freq_set *supported =
+ wiphy_get_supported_freqs(station->wiphy);
+
+ /*
+ * Scan the 2.4GHz "social channels" first, 5GHz second, if supported,
+ * all other 2.4GHz channels last. To be refined as needed.
+ */
+ station->scan_freqs_order[0] = scan_freq_set_new();
+ scan_freq_set_add(station->scan_freqs_order[0], 2412);
+ scan_freq_set_add(station->scan_freqs_order[0], 2437);
+ scan_freq_set_add(station->scan_freqs_order[0], 2462);
+
+ station->scan_freqs_order[1] = scan_freq_set_new();
+ station->scan_freqs_order[2] = scan_freq_set_new();
+ scan_freq_set_foreach(supported, station_add_one_freq, station);
+
+ if (scan_freq_set_isempty(station->scan_freqs_order[1])) {
+ scan_freq_set_free(station->scan_freqs_order[1]);
+ station->scan_freqs_order[1] = station->scan_freqs_order[2];
+ station->scan_freqs_order[2] = NULL;
+ }
+}
+
static struct station *station_create(struct netdev *netdev)
{
struct station *station;
@@ -3240,6 +3326,8 @@ static struct station *station_create(struct netdev *netdev)
station->anqp_pending = l_queue_new();
+ station_fill_scan_freq_subsets(station);
+
return station;
}
@@ -3306,6 +3394,12 @@ static void station_free(struct station *station)
l_queue_destroy(station->anqp_pending, remove_anqp);
+ scan_freq_set_free(station->scan_freqs_order[0]);
+ scan_freq_set_free(station->scan_freqs_order[1]);
+
+ if (station->scan_freqs_order[2])
+ scan_freq_set_free(station->scan_freqs_order[2]);
+
l_free(station);
}
--
2.27.0
1 year, 6 months
[PATCH 01/11] hwsim: add --no-register option
by James Prestwood
Starts hwsim but does not register to mac80211_hwsim. This is to
allow autotests to disable hwsim, while still having the ability
to create/destroy radios over DBus.
---
tools/hwsim.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/tools/hwsim.c b/tools/hwsim.c
index 02053fa1..641a6c6f 100644
--- a/tools/hwsim.c
+++ b/tools/hwsim.c
@@ -151,6 +151,7 @@ static enum action {
static bool no_vif_attr;
static bool p2p_attr;
+static bool no_register = false;
static const char *radio_name_attr;
static struct l_dbus *dbus;
static struct l_queue *rules;
@@ -2347,6 +2348,9 @@ static void get_interface_done_initial(void *user_data)
{
struct l_genl_msg *msg;
+ if (no_register)
+ return;
+
msg = l_genl_msg_new_sized(HWSIM_CMD_REGISTER, 4);
l_genl_family_send(hwsim, msg, register_callback, NULL, NULL);
}
@@ -2625,6 +2629,7 @@ static const struct option main_options[] = {
{ "version", no_argument, NULL, 'v' },
{ "iftype-disable", required_argument, NULL, 't' },
{ "cipher-disable", required_argument, NULL, 'c' },
+ { "no-register", no_argument, NULL, 'r' },
{ "help", no_argument, NULL, 'h' },
{ }
};
@@ -2636,7 +2641,7 @@ int main(int argc, char *argv[])
for (;;) {
int opt;
- opt = getopt_long(argc, argv, ":L:CD:kndetc:ipvh", main_options,
+ opt = getopt_long(argc, argv, ":L:CD:kndetrc:ipvh", main_options,
NULL);
if (opt < 0)
break;
@@ -2682,6 +2687,9 @@ int main(int argc, char *argv[])
case 'c':
hwsim_disable_ciphers(optarg);
break;
+ case 'r':
+ no_register = true;
+ break;
case 'v':
printf("%s\n", VERSION);
return EXIT_SUCCESS;
--
2.26.2
1 year, 6 months
[PATCH 1/2] eap-tls: Make use of l_pem_load_container_file()
by Andrew Zaborowski
This allows .p12 files and other formats to be used. When a single file
contains both the client certificates and the private key, it can be
given as either EAP-{TLS,PEAP,TTLS}-ClientCert or -ClientKey. Also both
settings can point to the same or different files and only the
certificates will be loaded from one and only the key from the other (if
different).
---
src/eap-tls-common.c | 302 +++++++++++++++++++++++++------------------
1 file changed, 178 insertions(+), 124 deletions(-)
diff --git a/src/eap-tls-common.c b/src/eap-tls-common.c
index c3eb5ab3..aa43e5a3 100644
--- a/src/eap-tls-common.c
+++ b/src/eap-tls-common.c
@@ -864,31 +864,25 @@ static struct l_queue *eap_tls_load_ca_cert(struct l_settings *settings,
return l_pem_load_certificate_list_from_data(pem, strlen(pem));
}
-static struct l_certchain *eap_tls_load_client_cert(struct l_settings *settings,
- const char *value)
+static struct l_certchain *eap_tls_load_embedded_cert(
+ struct l_settings *settings,
+ const char *value)
{
- const char *pem;
-
- if (!is_embedded(value))
- return l_pem_load_certificate_chain(value);
+ const char *pem = load_embedded_pem(settings, value);
- pem = load_embedded_pem(settings, value);
if (!pem)
return NULL;
return l_pem_load_certificate_chain_from_data(pem, strlen(pem));
}
-static struct l_key *eap_tls_load_priv_key(struct l_settings *settings,
- const char *value, const char *passphrase,
- bool *is_encrypted)
+static struct l_key *eap_tls_load_embedded_priv_key(struct l_settings *settings,
+ const char *value,
+ const char *passphrase,
+ bool *is_encrypted)
{
- const char *pem;
+ const char *pem = load_embedded_pem(settings, value);
- if (!is_embedded(value))
- return l_pem_load_private_key(value, passphrase, is_encrypted);
-
- pem = load_embedded_pem(settings, value);
if (!pem)
return NULL;
@@ -903,11 +897,14 @@ int eap_tls_common_settings_check(struct l_settings *settings,
{
char setting_key[72];
char client_cert_setting[72];
+ char client_key_setting[72];
char passphrase_setting[72];
struct l_queue *cacerts = NULL;
struct l_certchain *cert = NULL;
struct l_key *priv_key = NULL;
- bool is_encrypted, is_public;
+ bool is_public;
+ bool cert_is_encrypted;
+ bool key_is_encrypted;
int ret;
const char *error_str;
size_t size;
@@ -916,17 +913,32 @@ int eap_tls_common_settings_check(struct l_settings *settings,
struct l_key *pub_key;
const char *domain_mask_str;
- L_AUTO_FREE_VAR(char *, value);
+ L_AUTO_FREE_VAR(char *, ca_cert);
L_AUTO_FREE_VAR(char *, client_cert) = NULL;
+ L_AUTO_FREE_VAR(char *, client_key) = NULL;
L_AUTO_FREE_VAR(char *, passphrase) = NULL;
+ snprintf(passphrase_setting, sizeof(passphrase_setting),
+ "%sClientKeyPassphrase", prefix);
+ passphrase = l_settings_get_string(settings, "Security",
+ passphrase_setting);
+
+ if (!passphrase) {
+ const struct eap_secret_info *secret;
+
+ secret = l_queue_find(secrets, eap_secret_info_match,
+ passphrase_setting);
+ if (secret)
+ passphrase = l_strdup(secret->value);
+ }
+
snprintf(setting_key, sizeof(setting_key), "%sCACert", prefix);
- value = l_settings_get_string(settings, "Security", setting_key);
- if (value) {
- cacerts = eap_tls_load_ca_cert(settings, value);
+ ca_cert = l_settings_get_string(settings, "Security", setting_key);
+ if (ca_cert) {
+ cacerts = eap_tls_load_ca_cert(settings, ca_cert);
if (!cacerts) {
- l_error("Failed to load %s", value);
+ l_error("Failed to load %s", ca_cert);
return -EIO;
}
}
@@ -935,113 +947,146 @@ int eap_tls_common_settings_check(struct l_settings *settings,
"%sClientCert", prefix);
client_cert = l_settings_get_string(settings, "Security",
client_cert_setting);
- if (client_cert) {
- cert = eap_tls_load_client_cert(settings, client_cert);
-
- if (!cert) {
- l_error("Failed to load %s", client_cert);
- ret = -EIO;
- goto done;
- }
- /*
- * Sanity check that certchain provided is valid. We do not
- * verify the certchain against the provided CA, since the
- * CA that issued user certificates might be different from
- * the one that is used to verify the peer
- */
- if (!l_certchain_verify(cert, NULL, &error_str)) {
- l_error("Certificate chain %s fails verification: %s",
- client_cert, error_str);
- ret = -EINVAL;
- goto done;
- }
- }
+ snprintf(client_key_setting, sizeof(client_key_setting),
+ "%sClientKey", prefix);
+ client_key = l_settings_get_string(settings, "Security",
+ client_key_setting);
- l_free(value);
-
- snprintf(setting_key, sizeof(setting_key), "%sClientKey", prefix);
- value = l_settings_get_string(settings, "Security", setting_key);
+ /*
+ * If ClientCert and ClientKey are both provided, try to load only the
+ * certificate chain from the former and only the private key from the
+ * latter. If only one is present and is a file path, take whatever
+ * the file contains.
+ */
- if (value && !client_cert) {
- l_error("%s present but no client certificate (%s)",
- setting_key, client_cert_setting);
- ret = -ENOENT;
- goto done;
- } else if (!value && client_cert) {
- l_error("%s present but no client private key (%s)",
- client_cert_setting, setting_key);
- ret = -ENOENT;
- goto done;
+ if (client_cert && is_embedded(client_cert)) {
+ cert = eap_tls_load_embedded_cert(settings, client_cert);
+ cert_is_encrypted = false;
+ } else if (client_cert) {
+ l_pem_load_container_file(client_cert, passphrase,
+ &cert,
+ client_key ? NULL : &priv_key,
+ &cert_is_encrypted);
}
- snprintf(passphrase_setting, sizeof(passphrase_setting),
- "%sClientKeyPassphrase", prefix);
- passphrase = l_settings_get_string(settings, "Security",
- passphrase_setting);
+ if (client_key && is_embedded(client_key))
+ priv_key = eap_tls_load_embedded_priv_key(settings, client_key,
+ passphrase,
+ &key_is_encrypted);
+ else if (client_key) {
+ l_pem_load_container_file(client_key, passphrase,
+ client_cert ? NULL : &cert,
+ &priv_key,
+ &key_is_encrypted);
+ }
- if (!passphrase) {
- const struct eap_secret_info *secret;
+ /* Analyze all possible error condition */
- secret = l_queue_find(secrets, eap_secret_info_match,
- passphrase_setting);
- if (secret)
- passphrase = l_strdup(secret->value);
- }
+ if (client_cert && !cert) {
+ if (!cert_is_encrypted) {
+ l_error("Failed to load %s", client_cert);
+ ret = -EIO;
+ goto done;
+ }
- if (!value) {
if (passphrase) {
- l_error("%s present but no client private key"
- " value set (%s)", passphrase_setting,
- setting_key);
- ret = -ENOENT;
+ l_error("Error loading encrypted contents from %s",
+ client_cert);
+ ret = -EACCES;
goto done;
}
+ /*
+ * We've got an encrypted file and passphrase was not saved
+ * in the network settings, need to request the passphrase.
+ */
+ eap_append_secret(out_missing,
+ EAP_SECRET_LOCAL_PKEY_PASSPHRASE,
+ passphrase_setting, NULL, client_cert,
+ EAP_CACHE_TEMPORARY);
ret = 0;
goto done;
}
- priv_key = eap_tls_load_priv_key(settings, value, passphrase,
- &is_encrypted);
-
- if (!priv_key) {
- if (!is_encrypted) {
- l_error("Error loading client private key %s", value);
+ if (client_key && !priv_key) {
+ if (!key_is_encrypted) {
+ l_error("Failed to load %s", client_key);
ret = -EIO;
goto done;
}
if (passphrase) {
- l_error("Error loading encrypted client private key %s",
- value);
+ l_error("Error loading encrypted contents from %s",
+ client_key);
ret = -EACCES;
goto done;
}
/*
- * We've got an encrypted key and passphrase was not saved
+ * We've got an encrypted file and passphrase was not saved
* in the network settings, need to request the passphrase.
*/
eap_append_secret(out_missing,
EAP_SECRET_LOCAL_PKEY_PASSPHRASE,
- passphrase_setting, NULL, value,
+ passphrase_setting, NULL, client_key,
EAP_CACHE_TEMPORARY);
ret = 0;
goto done;
}
- if (passphrase && !is_encrypted) {
- l_error("%s present but client private key %s is not encrypted",
- passphrase_setting, value);
+ /* We now know that the provided certificate and key (if any) load */
+
+ if (cert && !priv_key) {
+ /* priv_key is NULL so ClientKey must have been unset */
+ l_error("A client certificate was loaded (%s) but no client "
+ "private key found, please set %s",
+ client_cert, client_key_setting);
+ ret = -ENOENT;
+ goto done;
+ } else if (!cert && priv_key) {
+ /* cert is NULL so ClientCert must have been unset */
+ l_error("A client private key was loaded (%s) but no client "
+ "certificate found, please set %s",
+ client_key, client_cert_setting);
+ ret = -ENOENT;
+ goto done;
+ } else if (!priv_key && passphrase) {
+ l_error("%s was set but no client private key (%s)",
+ passphrase_setting, client_key_setting);
+ ret = -ENOENT;
+ goto done;
+ } else if (!cert_is_encrypted && !key_is_encrypted && passphrase) {
+ l_error("%s was set but client %sprivate key file (%s) is "
+ "not encrypted", passphrase_setting,
+ (!client_key || !client_cert) ? "certificate and " : "",
+ client_key ?: client_cert);
ret = -ENOENT;
goto done;
}
+ if (!cert) {
+ ret = 0;
+ goto done;
+ }
+
+ /*
+ * Sanity check that provided certchain is valid. We do not verify
+ * the certchain against the provided CA, since the CA that issued
+ * user certificates might be different from the one that is used
+ * to verify the peer.
+ */
+ if (!l_certchain_verify(cert, NULL, &error_str)) {
+ l_error("The certificate chain in %s fails verification: %s",
+ client_cert ?: client_key, error_str);
+ ret = -EINVAL;
+ goto done;
+ }
+
if (!l_key_get_info(priv_key, L_KEY_RSA_PKCS1_V1_5, L_CHECKSUM_NONE,
&size, &is_public) || is_public) {
- l_error("%s is not a private key or l_key_get_info fails",
- value);
+ l_error("The key in %s is not a private key or l_key_get_info "
+ "fails", client_key ?: client_cert);
ret = -EINVAL;
goto done;
}
@@ -1052,7 +1097,8 @@ int eap_tls_common_settings_check(struct l_settings *settings,
pub_key = l_cert_get_pubkey(l_certchain_get_leaf(cert));
if (!pub_key) {
- l_error("l_cert_get_pubkey fails for %s", client_cert);
+ l_error("l_cert_get_pubkey fails for the certificate in %s",
+ client_cert ?: client_key);
ret = -EIO;
goto done;
}
@@ -1062,7 +1108,8 @@ int eap_tls_common_settings_check(struct l_settings *settings,
l_key_free(pub_key);
if (result != (ssize_t) size) {
- l_error("l_key_encrypt fails with %s: %s", client_cert,
+ l_error("l_key_encrypt fails with the public key in the "
+ "certificate in %s: %s", client_cert ?: client_key,
strerror(-result));
ret = result;
goto done;
@@ -1071,15 +1118,16 @@ int eap_tls_common_settings_check(struct l_settings *settings,
result = l_key_decrypt(priv_key, L_KEY_RSA_PKCS1_V1_5, L_CHECKSUM_NONE,
encrypted, decrypted, size, size);
if (result < 0) {
- l_error("l_key_decrypt fails with %s: %s", value,
- strerror(-result));
+ l_error("l_key_decrypt fails with the private key in %s: %s",
+ client_key ?: client_cert, strerror(-result));
ret = result;
goto done;
}
if (result != 1 || decrypted[0] != 0) {
- l_error("Private key %s does not match certificate %s", value,
- client_cert);
+ l_error("The private key in %s does not match certificate in "
+ "%s", client_key ?: client_cert,
+ client_cert ?: client_key);
ret = -EINVAL;
goto done;
}
@@ -1121,7 +1169,9 @@ bool eap_tls_common_settings_load(struct eap_state *eap,
struct eap_tls_state *eap_tls;
char setting_key[72];
char *domain_mask_str;
- L_AUTO_FREE_VAR(char *, value) = NULL;
+ L_AUTO_FREE_VAR(char *, ca_cert) = NULL;
+ L_AUTO_FREE_VAR(char *, client_cert) = NULL;
+ L_AUTO_FREE_VAR(char *, client_key) = NULL;
L_AUTO_FREE_VAR(char *, passphrase) = NULL;
eap_tls = l_new(struct eap_tls_state, 1);
@@ -1130,47 +1180,51 @@ bool eap_tls_common_settings_load(struct eap_state *eap,
eap_tls->variant_ops = variant_ops;
eap_tls->variant_data = variant_data;
+ snprintf(setting_key, sizeof(setting_key), "%sClientKeyPassphrase",
+ prefix);
+ passphrase = l_settings_get_string(settings, "Security", setting_key);
+
snprintf(setting_key, sizeof(setting_key), "%sCACert", prefix);
- value = l_settings_get_string(settings, "Security", setting_key);
- if (value) {
- eap_tls->ca_cert = eap_tls_load_ca_cert(settings, value);
- if (!eap_tls->ca_cert) {
- l_error("Could not load CACert %s", value);
+ ca_cert = l_settings_get_string(settings, "Security", setting_key);
+ if (ca_cert) {
+ eap_tls->ca_cert = eap_tls_load_ca_cert(settings, ca_cert);
+ if (!eap_tls->ca_cert)
goto load_error;
- }
}
- l_free(value);
-
snprintf(setting_key, sizeof(setting_key), "%sClientCert", prefix);
- value = l_settings_get_string(settings, "Security", setting_key);
- if (value) {
- eap_tls->client_cert = eap_tls_load_client_cert(settings,
- value);
- if (!eap_tls->client_cert) {
- l_error("Could not load ClientCert %s", value);
- goto load_error;
- }
- }
-
- l_free(value);
-
- snprintf(setting_key, sizeof(setting_key), "%sClientKeyPassphrase",
- prefix);
- passphrase = l_settings_get_string(settings, "Security", setting_key);
+ client_cert = l_settings_get_string(settings, "Security", setting_key);
snprintf(setting_key, sizeof(setting_key), "%sClientKey", prefix);
- value = l_settings_get_string(settings, "Security", setting_key);
- if (value) {
- eap_tls->client_key = eap_tls_load_priv_key(settings, value,
+ client_key = l_settings_get_string(settings, "Security", setting_key);
+
+ if (client_cert && is_embedded(client_cert))
+ eap_tls->client_cert = eap_tls_load_embedded_cert(settings,
+ client_cert);
+ else if (client_cert) {
+ l_pem_load_container_file(client_cert, passphrase,
+ &eap_tls->client_cert,
+ client_key ? NULL :
+ &eap_tls->client_key, NULL);
+ }
+
+ if (client_key && is_embedded(client_key))
+ eap_tls->client_key = eap_tls_load_embedded_priv_key(settings,
+ client_key,
passphrase,
NULL);
- if (!eap_tls->client_key) {
- l_error("Could not load ClientKey %s", value);
- goto load_error;
- }
+ else if (client_key) {
+ l_pem_load_container_file(client_key, passphrase,
+ client_cert ? NULL :
+ &eap_tls->client_cert,
+ &eap_tls->client_key, NULL);
}
+ if ((client_cert && !eap_tls->client_cert) ||
+ (client_key && !eap_tls->client_key) ||
+ !eap_tls->client_cert != !eap_tls->client_key)
+ goto load_error;
+
snprintf(setting_key, sizeof(setting_key), "%sServerDomainMask",
prefix);
domain_mask_str = l_settings_get_string(settings, "Security",
--
2.27.0
1 year, 6 months
iwd and NetworkManager
by KeithG
Andrew,
Wanted to post here. I recently started having issues with my Arch Linux
install with NetworkManager and iwd 1.9 not connecting at boot or
reconnecting after wake-up. It used to work reasonably well then recently,
after an update, it would only reconnect if I restarted iwd or NW after
boot. I ran across a post to the NW project that you posted and said that
you recently addressed an issue with iwd and NW. I built the 1.10 version
and am posting here to say that it appears to have fixed my issue. I just
tried one reboot and it was already connected by the time the desktop
showed. Tried a suspend resume and likewise it was showing the WiFi icon as
connected when the login screen appeared.
Arch still has not updated their package to 1.10, but it builds fine with
the old PKGBUILD and installs fine as well.
Thanks!
Keith
1 year, 6 months
[PATCH] client: ignore control sequence length in prompt
by Ronan Pigott
From: Ronan Pigott <rpigott(a)berkeley.edu>
Readline uses the characters \001 and \002 to mark the start and end
of zero-length character sequnces in the prompt before prompt
expansion. Without these characters the input point can become offset
from the visual end of the prompt when performing some actions.
---
iwctl gets messed up if you press up and down once to recall and
then dismiss the last history line. This fixes that.
client/display.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/client/display.c b/client/display.c
index b19759ea..88bc913f 100644
--- a/client/display.c
+++ b/client/display.c
@@ -39,7 +39,8 @@
#include "client/command.h"
#include "client/display.h"
-#define IWD_PROMPT COLOR_GREEN "[iwd]" COLOR_OFF "# "
+#define IWD_PROMPT \
+ "\001" COLOR_GREEN "\002" "[iwd]" "\001" COLOR_OFF "\002" "# "
#define LINE_LEN 81
static struct l_signal *window_change_signal;
--
2.29.2
1 year, 6 months
[PATCH v2 1/2] netconfig: add ACD client for static configuration
by James Prestwood
When the IP is configured to be static we can now use ACD in
order to check that the IP is available and not already in
use. If a conflict is found netconfig will be reset and no IP
will be set on the interface. The ACD client is left with
the default 'defend once' policy, and probes are not turned
off. This will increase connection time, but for static IP's
it is the best approach.
---
src/netconfig.c | 94 +++++++++++++++++++++++++++++++++++++++----------
1 file changed, 76 insertions(+), 18 deletions(-)
v2:
* Added netconfig_reset_v4 to allow a failed ACD attempt to
reset only the IPv4 data.
* Distinguish between CONFLICT/LOST events. For conflicts
no IP was ever set in the kernel, so we can just clean up
the rtnl address directly. For LOST events an address was
set, so it would need to be deleted.
diff --git a/src/netconfig.c b/src/netconfig.c
index f48a789a..e7a6a402 100644
--- a/src/netconfig.c
+++ b/src/netconfig.c
@@ -64,6 +64,8 @@ struct netconfig {
void *user_data;
struct resolve *resolve;
+
+ struct l_acd *acd;
};
static struct l_netlink *rtnl;
@@ -804,15 +806,87 @@ static void netconfig_dhcp6_event_handler(struct l_dhcp6_client *client,
}
}
+static void netconfig_reset_v4(struct netconfig *netconfig)
+{
+ if (netconfig->rtm_protocol) {
+ if (netconfig->v4_address) {
+ L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl,
+ netconfig->ifindex,
+ netconfig->v4_address,
+ netconfig_ifaddr_del_cmd_cb,
+ netconfig, NULL));
+ l_rtnl_address_free(netconfig->v4_address);
+ netconfig->v4_address = NULL;
+ }
+
+ l_strfreev(netconfig->dns4_overrides);
+ netconfig->dns4_overrides = NULL;
+
+ l_dhcp_client_stop(netconfig->dhcp_client);
+ netconfig->rtm_protocol = 0;
+ }
+}
+
+static void netconfig_ipv4_acd_event(enum l_acd_event event, void *user_data)
+{
+ struct netconfig *netconfig = user_data;
+
+ switch (event) {
+ case L_ACD_EVENT_AVAILABLE:
+ L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
+ netconfig->v4_address,
+ netconfig_ipv4_ifaddr_add_cmd_cb,
+ netconfig, NULL));
+ return;
+ case L_ACD_EVENT_CONFLICT:
+ /*
+ * Conflict found, no IP was actually set so just free/unset
+ * anything we set prior to starting ACD.
+ */
+ l_error("netconfig: statically configured address conflict!");
+ l_rtnl_address_free(netconfig->v4_address);
+ netconfig->v4_address = NULL;
+ netconfig->rtm_protocol = 0;
+ break;
+ case L_ACD_EVENT_LOST:
+ /*
+ * Set IP but lost it some time after. Full (IPv4) reset in this
+ * case.
+ */
+ l_error("netconfig: statically configured address was lost");
+ netconfig_reset_v4(netconfig);
+ break;
+ }
+}
+
static void netconfig_ipv4_select_and_install(struct netconfig *netconfig)
{
netconfig->v4_address = netconfig_get_static4_address(netconfig);
if (netconfig->v4_address) {
+ char ip[INET6_ADDRSTRLEN];
+
netconfig->rtm_protocol = RTPROT_STATIC;
- L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
+ netconfig->acd = l_acd_new(netconfig->ifindex);
+ l_acd_set_event_handler(netconfig->acd,
+ netconfig_ipv4_acd_event, netconfig,
+ NULL);
+ if (getenv("IWD_ACD_DEBUG"))
+ l_acd_set_debug(netconfig->acd, do_debug,
+ "[ACD] ", NULL);
+
+ l_rtnl_address_get_address(netconfig->v4_address, ip);
+
+ if (!l_acd_start(netconfig->acd, ip)) {
+ l_error("failed to start ACD, continuing anyways");
+ l_acd_destroy(netconfig->acd);
+ netconfig->acd = NULL;
+
+ L_WARN_ON(!l_rtnl_ifaddr_add(rtnl, netconfig->ifindex,
netconfig->v4_address,
netconfig_ipv4_ifaddr_add_cmd_cb,
netconfig, NULL));
+ }
+
return;
}
@@ -955,23 +1029,7 @@ bool netconfig_reset(struct netconfig *netconfig)
if (netconfig->rtm_protocol || netconfig->rtm_v6_protocol)
resolve_revert(netconfig->resolve);
- if (netconfig->rtm_protocol) {
- if (netconfig->v4_address) {
- L_WARN_ON(!l_rtnl_ifaddr_delete(rtnl,
- netconfig->ifindex,
- netconfig->v4_address,
- netconfig_ifaddr_del_cmd_cb,
- netconfig, NULL));
- l_rtnl_address_free(netconfig->v4_address);
- netconfig->v4_address = NULL;
- }
-
- l_strfreev(netconfig->dns4_overrides);
- netconfig->dns4_overrides = NULL;
-
- l_dhcp_client_stop(netconfig->dhcp_client);
- netconfig->rtm_protocol = 0;
- }
+ netconfig_reset_v4(netconfig);
if (netconfig->rtm_v6_protocol) {
l_strfreev(netconfig->dns6_overrides);
--
2.26.2
1 year, 6 months
[PATCH 1/9] build: add ell/acd.{c,h} to makefile
by James Prestwood
---
Makefile.am | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 1f0b0d30..3cd7eaa6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -61,7 +61,8 @@ ell_headers = ell/util.h \
ell/time.h \
ell/path.h \
ell/icmp6.h \
- ell/dhcp6.h
+ ell/dhcp6.h \
+ ell/acd.h
ell_sources = ell/private.h \
ell/missing.h \
@@ -138,7 +139,8 @@ ell_sources = ell/private.h \
ell/icmp6.c \
ell/icmp6-private.h \
ell/dhcp6-lease.c \
- ell/dhcp6-transport.c
+ ell/dhcp6-transport.c \
+ ell/acd.c
ell_libell_internal_la_SOURCES = $(ell_headers) $(ell_sources)
endif
--
2.26.2
1 year, 6 months