From patchwork Fri Sep 24 11:44:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Damien Dejean X-Patchwork-Id: 1532243 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=GV13L8IC; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.a=rsa-sha256 header.s=20210112 header.b=iBdduk6W; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4HG9Gn21Yyz9svs for ; Fri, 24 Sep 2021 21:46:25 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:References: Mime-Version:Message-Id:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=6VAliypFf+RzkUFv5Me2FCxLwSjx/27U2AB61xqlvYI=; b=GV13L8ICoD8EBQMKnFpIZkLP77 MF7/rUSSy5Wn0zc4rpyFUlgAQe21IlqHAZJvg5SqwPwnHON1KWgeaKrXauP5fqy23aYCTiJagu26m 6UJ4JxMnJ5eqVa555sW43+vcOMeNzBhqXzAV8BV4LFFeFQilk7mXyqIxl1yzJU8nR1NT5JfWMR5r/ s0fPDdCYCRJ44b+2Ubit6YLjRIYDPcJydk6oKm18Rrg+TQzAk6i2+hOYSwmzFb4HsnSzIxNrVV+Yk sI4tXIn8dck/wbBTgA48cojB9IigTwWcBRw0+X1vfZ5amaaNEvpG4RhuykU6VOI+cIRkDotQzwzrq WktHsl/Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mTjdm-00ED3Q-16; Fri, 24 Sep 2021 11:45:18 +0000 Received: from mail-qk1-x74a.google.com ([2607:f8b0:4864:20::74a]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mTjdb-00ED1S-UO for hostap@lists.infradead.org; Fri, 24 Sep 2021 11:45:09 +0000 Received: by mail-qk1-x74a.google.com with SMTP id u22-20020a05620a431600b0045dcc8487daso983105qko.6 for ; Fri, 24 Sep 2021 04:45:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=J7kd0lLT49Ko2JfUH3G3hL9MGCziASZz87uXE95VxaY=; b=iBdduk6W523ny5oRPN4O8ZgVpG+o4Ovm+mdPn9Us4M5tvrK+SBzUsptekbqufqYxBO dRnzulBhxJfTYNJ9Z8op9N5msoV2tIkfcGlm8mOqGdoxKuaSW6tRTYmXAwuuSA4sm/hk 6OYCjHVCF39mtPVbvvJR1mc08yWrExXCZPlVwPxtj4pxd4pJg1C4dO0LDCBbTh+1Jym0 fP6wwq69P1fpm5XOdBGuVGkwcvfS7mnLAwqzghkHF14N7Ma7bMdC89KL7ctAFLi/qKQa cmbE8QrjR6ImA6dGLVs4N+Lx21AYb12fy7fMfQ4i78E/0k6MyDGjN4w8hsqgSbYt2Ao/ n0NQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=J7kd0lLT49Ko2JfUH3G3hL9MGCziASZz87uXE95VxaY=; b=Xuiheyqd84ls39zXn7rT8FN+Zxqongs7UsNNOXe3blT+uxl+LIcYz1U5izcUzJQOlh smVHPYytekeXKcIw0QOLgBAQrVtxnksFFiafg4R5kBfKycZ5j+NPy94l2/Ldj+yGAb6D Zr03kR0y4wRMQltGq9X9XsmUVqBQ6ORjI3JFuCTR7h2ufgZPgVt+ngB0SggaIqRaplRa afli8Kep2EN7Vqnrp92krsgQaALSqx0hItyLhgjPWQ6mpj2MMcXJsYwjfua/e4WQKiZQ X+VpRa9zbTB9Mj4o1NWYyb1NNynwVQlo3nhwq5QziWkMBbf4hlJQfaWB6V7QCyKMicxz NdeA== X-Gm-Message-State: AOAM531NWCzzJStGct6Sua4WoO4GZC0DsxDuyrema7G7H/4EzoMQf6rU 9bGw3XJIIAYCUIJG5j3mIFZ2E+au5W0AS5DkEvwiZVJyl5PNwvdowWL+AYLkd1zPusKmhpiivaK nP4qZsIlNPzj6hXQ1YAzodEnjiAv9EsHkv/rQaEf1DXRTyQz2JineGfR3RQRxhJ8iw9jioso9mz QFgTJzkx4= X-Google-Smtp-Source: ABdhPJypxmyt1WuH3PaAeJ/b+/mA5a5+fOxpjdP5ZPVI14RImYHFsEJ0DiPqalXKzDqg5nm9Vuz3h/WJZYFz9y/cn/E= X-Received: from ddejean-cros.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:5f]) (user=damiendejean job=sendgmr) by 2002:ad4:46ab:: with SMTP id br11mr9326535qvb.15.1632483905582; Fri, 24 Sep 2021 04:45:05 -0700 (PDT) Date: Fri, 24 Sep 2021 11:44:48 +0000 In-Reply-To: <20210924114449.3539070-1-damiendejean@google.com> Message-Id: <20210924114449.3539070-2-damiendejean@google.com> Mime-Version: 1.0 References: <20210924114449.3539070-1-damiendejean@google.com> X-Mailer: git-send-email 2.33.0.685.g46640cef36-goog Subject: [PATCH v2 2/3] DBus: add interworking credentials. From: damiendejean@google.com To: hostap@lists.infradead.org Cc: Damien Dejean X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210924_044508_022699_757E780E X-CRM114-Status: GOOD ( 23.56 ) X-Spam-Score: -7.7 (-------) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: From: Damien Dejean Add "AddCred" and "RemoveCred" methods to the D-Bus API of the network interface to allow the caller to manipulate a set of interworking credentials. Signed-off-by: Damien Dejean --- tests/hwsim/test_dbus.py | 26 +++ wpa_supplicant/dbus/dbus_new.c | 17 ++ wpa_supplicant/dbus/dbus_new.h | 4 + wpa_supplicant/dbus/dbus_new_ha [...] Content analysis details: (-7.7 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:74a listed in] [list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -7.5 USER_IN_DEF_DKIM_WL From: address is in the default DKIM white-list -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.0 DKIMWL_WL_MED DKIMwl.org - Medium trust sender X-BeenThere: hostap@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Hostap" Errors-To: hostap-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Damien Dejean Add "AddCred" and "RemoveCred" methods to the D-Bus API of the network interface to allow the caller to manipulate a set of interworking credentials. Signed-off-by: Damien Dejean --- tests/hwsim/test_dbus.py | 26 +++ wpa_supplicant/dbus/dbus_new.c | 17 ++ wpa_supplicant/dbus/dbus_new.h | 4 + wpa_supplicant/dbus/dbus_new_handlers.c | 228 ++++++++++++++++++++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 11 ++ 5 files changed, 286 insertions(+) diff --git a/tests/hwsim/test_dbus.py b/tests/hwsim/test_dbus.py index 1143802c6..1822e0a2c 100644 --- a/tests/hwsim/test_dbus.py +++ b/tests/hwsim/test_dbus.py @@ -6091,3 +6091,29 @@ def test_dbus_roam(dev, apdev): with TestDbusConnect(bus) as t: if not t.success(): raise Exception("Expected signals not seen") + +def test_dbus_creds(dev, apdev): + "D-Bus interworking credentials" + (bus, wpas_obj, path, if_obj) = prepare_dbus(dev[0]) + iface = dbus.Interface(if_obj, WPAS_DBUS_IFACE) + + args = {'domain': 'server.w1.fi', + 'realm': 'server.w1.fi', + 'eap': 'TTLS', + 'phase2': 'auth=MSCHAPV2', + 'username': 'user', + 'password': 'password', + 'domain_suffix_match': 'server.w1.fi', + 'ca_cert': 'auth_serv/ca.pem'} + + path = iface.AddCred(dbus.Dictionary(args, signature='sv')) + for k, v in args.items(): + if k == 'password': + continue + prop = dev[0].get_cred(0, k) + if prop != v: + raise Exception('Credential add failed: %s does not match %s' % (prop, v)) + + iface.RemoveCred(path) + if not "FAIL" in dev[0].get_cred(0, 'domain'): + raise Exception("Credential remove failed") diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 2c01943f7..413396a9f 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -3570,6 +3570,23 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { END_ARGS } }, +#ifdef CONFIG_INTERWORKING + { "AddCred", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_add_cred, + { + { "args", "a{sv}", ARG_IN }, + { "path", "o", ARG_OUT }, + END_ARGS + } + }, + { "RemoveCred", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_remove_cred, + { + { "path", "o", ARG_IN }, + END_ARGS + } + }, +#endif /* CONFIG_INTERWORKING */ { NULL, NULL, NULL, { END_ARGS } } }; diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 42db3892e..8ae0afeaa 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -16,6 +16,7 @@ struct wpa_global; struct wpa_supplicant; struct wpa_ssid; +struct wpa_cred; struct wps_event_m2d; struct wps_event_fail; struct wps_credential; @@ -96,6 +97,9 @@ enum wpas_dbus_sta_prop { #define WPAS_DBUS_NEW_P2P_PEERS_PART "Peers" #define WPAS_DBUS_NEW_IFACE_P2P_PEER WPAS_DBUS_NEW_INTERFACE ".Peer" +#define WPAS_DBUS_NEW_CREDENTIALS_PART "Credentials" +#define WPAS_DBUS_NEW_IFACE_CREDENTIAL WPAS_DBUS_NEW_INTERFACE ".Credential" + /* Top-level Errors */ #define WPAS_DBUS_ERROR_UNKNOWN_ERROR \ WPAS_DBUS_NEW_INTERFACE ".UnknownError" diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index db9f30c9a..2b2cefb76 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -148,6 +148,9 @@ static const char * const dont_quote[] = { #ifdef CONFIG_P2P "go_p2p_dev_addr", "p2p_client_list", "psk_list", #endif /* CONFIG_P2P */ +#ifdef CONFIG_INTERWORKING + "roaming_consortium", +#endif /* CONFIG_INTERWORKING */ NULL }; @@ -328,6 +331,110 @@ error: } +/** + * set_cred_properties - Set the properties of a configured set of + * crendentials. + * @wpa_s: wpa_supplicant structure for a network interface + * @cred: wpa_cred structure for a configured credential + * @iter: DBus message iterator containing dictionary of network + * properties to set. + * @error: On failure, an error describing the failure + * Returns: TRUE if the request succeeds, FALSE if it failed + */ +dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s, + struct wpa_cred *cred, + DBusMessageIter *iter, + DBusError *error) +{ + struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING }; + DBusMessageIter iter_dict; + char *value = NULL; + + if (!wpa_dbus_dict_open_read(iter, &iter_dict, error)) + return FALSE; + + while (wpa_dbus_dict_has_dict_entry(&iter_dict)) { + size_t size = 50; + int ret; + + if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) + goto error; + + value = NULL; + if (entry.type == DBUS_TYPE_ARRAY && + entry.array_type == DBUS_TYPE_BYTE) { + if (entry.array_len <= 0) + goto error; + + size = entry.array_len * 2 + 1; + value = os_zalloc(size); + if (value == NULL) + goto error; + + ret = wpa_snprintf_hex(value, size, + (u8 *) entry.bytearray_value, + entry.array_len); + if (ret <= 0) + goto error; + } else if (entry.type == DBUS_TYPE_STRING) { + if (should_quote_opt(entry.key)) { + size = os_strlen(entry.str_value); + + size += 3; + value = os_zalloc(size); + if (value == NULL) + goto error; + + ret = os_snprintf(value, size, "\"%s\"", + entry.str_value); + if (os_snprintf_error(size, ret)) + goto error; + } else { + value = os_strdup(entry.str_value); + if (value == NULL) + goto error; + } + } else if (entry.type == DBUS_TYPE_UINT32) { + value = os_zalloc(size); + if (value == NULL) + goto error; + + ret = os_snprintf(value, size, "%u", + entry.uint32_value); + if (os_snprintf_error(size, ret)) + goto error; + } else if (entry.type == DBUS_TYPE_INT32) { + value = os_zalloc(size); + if (value == NULL) + goto error; + + ret = os_snprintf(value, size, "%d", + entry.int32_value); + if (os_snprintf_error(size, ret)) + goto error; + } else + goto error; + + ret = wpa_config_set_cred(cred, entry.key, value, 0); + if (ret < 0) + goto error; + + os_free(value); + value = NULL; + wpa_dbus_dict_entry_clear(&entry); + } + + return TRUE; + +error: + os_free(value); + wpa_dbus_dict_entry_clear(&entry); + dbus_set_error_const(error, DBUS_ERROR_INVALID_ARGS, + "invalid message format"); + return FALSE; +} + + /** * wpas_dbus_simple_property_getter - Get basic type property * @iter: Message iter to use when appending arguments @@ -1514,6 +1621,127 @@ DBusMessage * wpas_dbus_handler_abort_scan(DBusMessage *message, return NULL; } +/** + * wpas_dbus_new_iface_add_cred - Add a new set of credentials + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: A dbus message containing the object path of the new credential + * + * Handler function for "AddCred" method call of a network interface. + */ +DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + DBusMessageIter iter; + struct wpa_cred *cred = NULL; + char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf; + DBusError error; + + dbus_message_iter_init(message, &iter); + + if (wpa_s->dbus_new_path) + cred = wpa_config_add_cred(wpa_s->conf); + if (cred == NULL) { + wpa_printf(MSG_ERROR, "%s[dbus]: can't add new interface.", + __func__); + reply = wpas_dbus_error_unknown_error( + message, + "wpa_supplicant could not add a credential on this interface."); + goto err; + } + + dbus_error_init(&error); + if (!set_cred_properties(wpa_s, cred, &iter, &error)) { + wpa_printf(MSG_DEBUG, + "%s[dbus]: control interface couldn't set credential properties", + __func__); + reply = wpas_dbus_reply_new_from_error(message, &error, + DBUS_ERROR_INVALID_ARGS, + "Failed to add credential"); + dbus_error_free(&error); + goto err; + } + + /* Construct the object path for this network. */ + os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, + "%s/" WPAS_DBUS_NEW_CREDENTIALS_PART "/%d", + wpa_s->dbus_new_path, cred->id); + + reply = dbus_message_new_method_return(message); + if (reply == NULL) { + reply = wpas_dbus_error_no_memory(message); + goto err; + } + if (!dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID)) { + dbus_message_unref(reply); + reply = wpas_dbus_error_no_memory(message); + goto err; + } + + return reply; + +err: + if (cred) { + wpa_config_remove_cred(wpa_s->conf, cred->id); + } + return reply; +} + +/** + * wpas_dbus_handler_remove_cred - Remove a configured set of credentials + * @message: Pointer to incoming dbus message + * @wpa_s: wpa_supplicant structure for a network interface + * Returns: NULL on success or dbus error on failure + * + * Handler function for "RemoveCred" method call of a network interface. + */ +DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message, + struct wpa_supplicant *wpa_s) +{ + DBusMessage *reply = NULL; + const char *op; + char *iface, *cred_id; + int id; + int result; + + dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &op, + DBUS_TYPE_INVALID); + + /* Extract the network ID and ensure the network */ + /* is actually a child of this interface */ + iface = wpas_dbus_new_decompose_object_path(op, + WPAS_DBUS_NEW_CREDENTIALS_PART, + &cred_id); + if (iface == NULL || cred_id == NULL || !wpa_s->dbus_new_path || + os_strcmp(iface, wpa_s->dbus_new_path) != 0) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + errno = 0; + id = strtoul(cred_id, NULL, 10); + if (errno != 0) { + reply = wpas_dbus_error_invalid_args(message, op); + goto out; + } + + result = wpa_config_remove_cred(wpa_s->conf, id); + if (result == -1) { + wpa_printf(MSG_ERROR, + "%s[dbus]: error occurred when removing cred %d", + __func__, id); + reply = wpas_dbus_error_unknown_error( + message, + "error removing the specified credential on its interface."); + goto out; + } + +out: + os_free(iface); + return reply; +} /** * wpas_dbus_handler_signal_poll - Request immediate signal properties diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index c36383f05..5b01ab527 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -144,6 +144,17 @@ DBusMessage * wpas_dbus_handler_eap_logoff(DBusMessage *message, DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message, struct wpa_supplicant *wpa_s); +dbus_bool_t set_cred_properties(struct wpa_supplicant *wpa_s, + struct wpa_cred *cred, + DBusMessageIter *iter, + DBusError *error); + +DBusMessage * wpas_dbus_handler_add_cred(DBusMessage *message, + struct wpa_supplicant *wpa_s); + +DBusMessage * wpas_dbus_handler_remove_cred(DBusMessage *message, + struct wpa_supplicant *wpa_s); + DECLARE_ACCESSOR(wpas_dbus_getter_capabilities); DECLARE_ACCESSOR(wpas_dbus_getter_state); DECLARE_ACCESSOR(wpas_dbus_getter_scanning);