[PATCH 1/4] ap: make APRanges optional
by James Prestwood
If EnableNetworkConfiguration was enabled ap.c required that
APRanges also be set. This prevents IWD from starting which
effects a perfectly valid station configuration. Instead if
APRanges is not provided IWD still allows ap_init to pass but
DHCP just will not be enabled.
---
src/ap.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/ap.c b/src/ap.c
index bebd7295..4d0d5686 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -3028,9 +3028,14 @@ static int ap_init(void)
ip_prefix = l_settings_get_string(settings, "General",
"APRanges");
+ /*
+ * In this case its assumed the user only cares about station
+ * netconfig so we let ap_init pass but DHCP will not be
+ * enabled.
+ */
if (!ip_prefix) {
- l_error("[General].APRanges must be set for DHCP");
- return -EINVAL;
+ l_warn("[General].APRanges must be set for DHCP");
+ return 0;
}
if (!ip_pool_create(ip_prefix))
--
2.26.2
1 year, 8 months
[PATCH] test-runner: fix Radio/Interface circular reference
by James Prestwood
Code was added with commit 04487f575b6 which passes a radio object
to the Interface class constructor and stores it in the Interface
object. The radio class also stores each Interface object which
creates a circular reference and causes the Radio to stick around
long after the tests finishes.
I cannot see why the Interface needs to keep track of the Radio
object. None of the wpa_supplicant utilities use this so it has
been removed.
---
tools/test-runner | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/tools/test-runner b/tools/test-runner
index 3ae4558c..b4840fa4 100755
--- a/tools/test-runner
+++ b/tools/test-runner
@@ -246,11 +246,10 @@ class Process:
raise Exception("Timed out waiting for socket")
class Interface:
- def __init__(self, name, config, radio):
+ def __init__(self, name, config):
self.name = name
self.ctrl_interface = '/var/run/hostapd/' + name
self.config = config
- self.radio = radio
def __del__(self):
Process(['iw', 'dev', self.name, 'del'], True)
@@ -276,7 +275,7 @@ class Radio:
intf_id += 1
- self.interface = Interface(ifname, config, self)
+ self.interface = Interface(ifname, config)
self.use = use
Process(['iw', 'phy', self.name, 'interface', 'add', ifname,
--
2.26.2
1 year, 8 months
[PATCH] ap: fixup incorrect return
by James Prestwood
If an RTNL address change fails -EIO should be returned, not
false (aka "success").
---
src/ap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/ap.c b/src/ap.c
index bfa9d47e..bebd7295 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -2412,7 +2412,7 @@ static int ap_load_profile_and_dhcp(struct ap_state *ap, bool *wait_dhcp)
if (!ap->rtnl_add_cmd) {
l_error("Failed to add IPv4 address");
- return false;
+ return -EIO;
}
ap->cleanup_ip = true;
--
2.26.2
1 year, 8 months
[PATCH v2 1/3] ap: add StartProfile DBus method
by James Prestwood
Users can now start an AP from settings based on a profile
on disk. The only argument is the SSID which will be used to
lookup the profile. If no profile is found a NotFound error
will be returned. Any invalid profiles will result in an
Invalid return.
---
src/ap.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/ap.h | 3 +++
2 files changed, 71 insertions(+), 2 deletions(-)
v2:
* Removed the profile loading from ap_init and squashed that into
this commit.
* This now loads the profiles on the fly when the dbus method is
called. This avoids the need for any special ap_config handling
of transient vs disk profiles.
diff --git a/src/ap.c b/src/ap.c
index f08835f7..4aabcd89 100644
--- a/src/ap.c
+++ b/src/ap.c
@@ -51,6 +51,7 @@
#include "src/wscutil.h"
#include "src/eap-wsc.h"
#include "src/ap.h"
+#include "src/storage.h"
struct ap_state {
struct netdev *netdev;
@@ -231,6 +232,10 @@ void ap_config_free(struct ap_config *config)
explicit_bzero(config->psk, sizeof(config->psk));
l_free(config->authorized_macs);
l_free(config->wsc_name);
+
+ if (config->profile)
+ l_free(config->profile);
+
l_free(config);
}
@@ -2207,6 +2212,30 @@ static void ap_mlme_notify(struct l_genl_msg *msg, void *user_data)
}
}
+static bool ap_load_profile(struct ap_state *ap)
+{
+ char *passphrase;
+ L_AUTO_FREE_VAR(struct l_settings *, settings) = l_settings_new();
+
+ if (!l_settings_load_from_file(settings, ap->config->profile))
+ return false;
+
+ passphrase = l_settings_get_string(settings, "Security", "Passphrase");
+ if (passphrase) {
+ if (strlen(passphrase) > 63) {
+ l_error("[Security].Passphrase must not exceed "
+ "63 characters");
+ return false;
+ }
+
+ strcpy(ap->config->passphrase, passphrase);
+ l_free(passphrase);
+ }
+
+ l_info("Loaded AP configuration %s", ap->config->ssid);
+ return true;
+}
+
/*
* Start a simple independent WPA2 AP on given netdev.
*
@@ -2237,8 +2266,8 @@ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config,
if (L_WARN_ON(!config->ssid))
return NULL;
- if (L_WARN_ON(!config->passphrase[0] && util_mem_is_zero(config->psk,
- sizeof(config->psk))))
+ if (L_WARN_ON(!config->profile && !config->passphrase[0] &&
+ util_mem_is_zero(config->psk, sizeof(config->psk))))
return NULL;
ap = l_new(struct ap_state, 1);
@@ -2248,6 +2277,9 @@ struct ap_state *ap_start(struct netdev *netdev, struct ap_config *config,
ap->ops = ops;
ap->user_data = user_data;
+ if (config->profile && !ap_load_profile(ap))
+ goto error;
+
if (!config->channel)
/* TODO: Start a Get Survey to decide the channel */
config->channel = 6;
@@ -2698,6 +2730,37 @@ static struct l_dbus_message *ap_dbus_stop(struct l_dbus *dbus,
return NULL;
}
+static struct l_dbus_message *ap_dbus_start_profile(struct l_dbus *dbus,
+ struct l_dbus_message *message,
+ void *user_data)
+{
+ struct ap_if_data *ap_if = user_data;
+ const char *ssid;
+ struct ap_config *config;
+ int err;
+
+ if (ap_if->ap && ap_if->ap->started)
+ return dbus_error_already_exists(message);
+
+ if (ap_if->ap || ap_if->pending)
+ return dbus_error_busy(message);
+
+ if (!l_dbus_message_get_arguments(message, "s", &ssid))
+ return dbus_error_invalid_args(message);
+
+ config = l_new(struct ap_config, 1);
+ config->ssid = l_strdup(ssid);
+ /* This tells ap_start to pull settings from a profile on disk */
+ config->profile = storage_get_path("ap/%s.ap", ssid);
+
+ ap_if->ap = ap_start(ap_if->netdev, config, &ap_dbus_ops, &err, ap_if);
+ if (!ap_if->ap)
+ return dbus_error_from_errno(err, message);
+
+ ap_if->pending = l_dbus_message_ref(message);
+ return NULL;
+}
+
static bool ap_dbus_property_get_started(struct l_dbus *dbus,
struct l_dbus_message *message,
struct l_dbus_message_builder *builder,
@@ -2716,6 +2779,9 @@ static void ap_setup_interface(struct l_dbus_interface *interface)
l_dbus_interface_method(interface, "Start", 0, ap_dbus_start, "",
"ss", "ssid", "wpa2_passphrase");
l_dbus_interface_method(interface, "Stop", 0, ap_dbus_stop, "", "");
+ l_dbus_interface_method(interface, "StartProfile", 0,
+ ap_dbus_start_profile, "", "s",
+ "ssid");
l_dbus_interface_property(interface, "Started", 0, "b",
ap_dbus_property_get_started, NULL);
diff --git a/src/ap.h b/src/ap.h
index 1f2d438a..dc57a0bb 100644
--- a/src/ap.h
+++ b/src/ap.h
@@ -63,6 +63,9 @@ struct ap_config {
unsigned int authorized_macs_num;
char *wsc_name;
struct wsc_primary_device_type wsc_primary_device_type;
+
+ char *profile;
+
bool no_cck_rates : 1;
};
--
2.26.2
1 year, 8 months
[PATCH v2] frame-xchg: fix invalid read
by James Prestwood
This seems to happen occationally with testAP (potentially others).
The invalid read appears to happen when the frame_xchg_tx_cb detects
an early status and no ACK. In this particular case there is no
retry interval so we reach the retry limit and 'done' the frame.
This frees the 'fx' data all before the destroy callback can get
called. Once we finally return and the destroy callback is called
'fx' is freed and we see the invalid write.
==206== Memcheck, a memory error detector
==206== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==206== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==206== Command: iwd -p rad1,rad2,rad3,rad4 -d
==206== Parent PID: 140
==206==
==206== Invalid write of size 4
==206== at 0x4493A0: frame_xchg_tx_destroy (frame-xchg.c:941)
==206== by 0x46DAF6: destroy_request (genl.c:673)
==206== by 0x46DAF6: process_unicast (genl.c:1002)
==206== by 0x46DAF6: received_data (genl.c:1101)
==206== by 0x46AA4B: io_callback (io.c:118)
==206== by 0x469D6C: l_main_iterate (main.c:477)
==206== by 0x469E1B: l_main_run (main.c:524)
==206== by 0x469E1B: l_main_run (main.c:506)
==206== by 0x46A02B: l_main_run_with_signal (main.c:646)
==206== by 0x403E78: main (main.c:490)
==206== Address 0x4c59c6c is 172 bytes inside a block of size 176 free'd
==206== at 0x483B9F5: free (vg_replace_malloc.c:538)
==206== by 0x40F14C: destroy_work (wiphy.c:248)
==206== by 0x40F14C: wiphy_radio_work_done (wiphy.c:1578)
==206== by 0x44A916: frame_xchg_tx_cb (frame-xchg.c:930)
==206== by 0x46DAD9: process_unicast (genl.c:993)
==206== by 0x46DAD9: received_data (genl.c:1101)
==206== by 0x46AA4B: io_callback (io.c:118)
==206== by 0x469D6C: l_main_iterate (main.c:477)
==206== by 0x469E1B: l_main_run (main.c:524)
==206== by 0x469E1B: l_main_run (main.c:506)
==206== by 0x46A02B: l_main_run_with_signal (main.c:646)
==206== by 0x403E78: main (main.c:490)
==206== Block was alloc'd at
==206== at 0x483A809: malloc (vg_replace_malloc.c:307)
==206== by 0x4643CD: l_malloc (util.c:61)
==206== by 0x44AF8C: frame_xchg_startv (frame-xchg.c:1155)
==206== by 0x44B2A4: frame_xchg_start (frame-xchg.c:1108)
==206== by 0x42BC55: ap_send_mgmt_frame (ap.c:709)
==206== by 0x42F513: ap_probe_req_cb (ap.c:1869)
==206== by 0x449752: frame_watch_unicast_notify (frame-xchg.c:233)
==206== by 0x46DA2F: dispatch_unicast_watches (genl.c:961)
==206== by 0x46DA2F: process_unicast (genl.c:980)
==206== by 0x46DA2F: received_data (genl.c:1101)
==206== by 0x46AA4B: io_callback (io.c:118)
==206== by 0x469D6C: l_main_iterate (main.c:477)
==206== by 0x469E1B: l_main_run (main.c:524)
==206== by 0x469E1B: l_main_run (main.c:506)
==206== by 0x46A02B: l_main_run_with_signal (main.c:646)
==206==
---
src/frame-xchg.c | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
v2:
* Set fx->tx_cmd_id to zero after canceling
diff --git a/src/frame-xchg.c b/src/frame-xchg.c
index 0e3e330d..b4e092b8 100644
--- a/src/frame-xchg.c
+++ b/src/frame-xchg.c
@@ -773,8 +773,10 @@ static void frame_xchg_reset(struct frame_xchg_data *fx)
if (fx->timeout)
l_timeout_remove(fx->timeout);
- if (fx->tx_cmd_id)
+ if (fx->tx_cmd_id) {
l_genl_family_cancel(nl80211, fx->tx_cmd_id);
+ fx->tx_cmd_id = 0;
+ }
l_free(fx->early_frame.mpdu);
fx->early_frame.mpdu = NULL;
@@ -901,6 +903,8 @@ static void frame_xchg_tx_cb(struct l_genl_msg *msg, void *user_data)
uint64_t cookie;
bool early_status;
+ fx->tx_cmd_id = 0;
+
l_debug("err %i", -error);
if (error < 0) {
@@ -934,13 +938,6 @@ error:
frame_xchg_done(fx, error);
}
-static void frame_xchg_tx_destroy(void *user_data)
-{
- struct frame_xchg_data *fx = user_data;
-
- fx->tx_cmd_id = 0;
-}
-
static bool frame_xchg_tx_retry(struct wiphy_radio_work_item *item)
{
struct frame_xchg_data *fx = l_container_of(item,
@@ -974,7 +971,7 @@ static bool frame_xchg_tx_retry(struct wiphy_radio_work_item *item)
&duration);
fx->tx_cmd_id = l_genl_family_send(nl80211, msg, frame_xchg_tx_cb, fx,
- frame_xchg_tx_destroy);
+ NULL);
if (!fx->tx_cmd_id) {
l_error("Error sending frame");
l_genl_msg_unref(msg);
--
2.26.2
1 year, 8 months
[PATCH] resolve: allow setting default DNS resolver at compile time
by John Zimmermann
---
configure.ac | 15 +++++++++++++++
src/resolve.c | 4 ++--
2 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index 78db15e9..0adddd10 100644
--- a/configure.ac
+++ b/configure.ac
@@ -250,6 +250,21 @@ if (test "${enable_systemd_service}" != "no" && test -z "${path_systemd_modloadd
fi
AC_SUBST(SYSTEMD_MODLOADDIR, [${path_systemd_modloaddir}])
+AC_ARG_WITH(resolver, AC_HELP_STRING([--with-resolver=(systemd|resolvconf)],
+ [Set default DNS resolver [default=systemd]]),,
+ [with_resolver=systemd])
+
+case "x$with_resolver" in
+ "xsystemd")
+ AC_DEFINE(DEFAULT_RESOLVER, "systemd", ["Default DNS resolver"])
+ ;;
+ "xresolvconf")
+ AC_DEFINE(DEFAULT_RESOLVER, "resolvconf", ["Default DNS resolver"])
+ ;;
+ *) AC_MSG_ERROR([Wrong value for --with-resolver: $with_resolver])
+ ;;
+esac
+
AC_ARG_ENABLE([external_ell], AC_HELP_STRING([--enable-external-ell],
[enable external Embedded Linux library]),
[enable_external_ell=${enableval}])
diff --git a/src/resolve.c b/src/resolve.c
index 066e4c87..8949edad 100644
--- a/src/resolve.c
+++ b/src/resolve.c
@@ -553,8 +553,8 @@ static int resolve_init(void)
if (method_name)
l_warn("[General].dns_resolve_method is deprecated, "
"use [Network].NameResolvingService");
- else /* Default to systemd-resolved service. */
- method_name = "systemd";
+ else /* Default to compile time option (default: systemd-resolved) */
+ method_name = DEFAULT_RESOLVER;
}
for (i = 0; resolve_method_ops_list[i].name; i++) {
--
2.29.0
1 year, 8 months