Remove disconnected APs from BSS table if likely out-of-range
[mech_eap.git] / wpa_supplicant / dbus / dbus_old.c
index 674b9ff..88227af 100644 (file)
@@ -2,14 +2,8 @@
  * WPA Supplicant / dbus-based control interface
  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
  *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Alternatively, this software may be distributed under the terms of BSD
- * license.
- *
- * See README and COPYING for more details.
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
  */
 
 #include "includes.h"
 
 #include "common.h"
 #include "eloop.h"
-#include "drivers/driver.h"
 #include "wps/wps.h"
 #include "../config.h"
 #include "../wpa_supplicant_i.h"
+#include "../bss.h"
 #include "dbus_old.h"
 #include "dbus_old_handlers.h"
-#include "dbus_common.h"
 #include "dbus_common_i.h"
 
 
@@ -99,9 +92,9 @@ char * wpas_dbus_decompose_object_path(const char *path, char **network,
  */
 DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
 {
-       return dbus_message_new_error(message, WPAS_ERROR_INVALID_IFACE,
-                                     "wpa_supplicant knows nothing about "
-                                     "this interface.");
+       return dbus_message_new_error(
+               message, WPAS_ERROR_INVALID_IFACE,
+               "wpa_supplicant knows nothing about this interface.");
 }
 
 
@@ -176,45 +169,23 @@ static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
  */
 static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
                                                struct wpa_supplicant *wpa_s,
-                                               const char *bssid)
+                                               const char *bssid_txt)
 {
-       DBusMessage *reply = NULL;
-       const char *method = dbus_message_get_member(message);
-       struct wpa_scan_res *res = NULL;
-       size_t i;
-
-       /* Ensure we actually have scan data */
-       if (wpa_s->scan_res == NULL &&
-           wpa_supplicant_get_scan_results(wpa_s) < 0) {
-               reply = wpas_dbus_new_invalid_bssid_error(message);
-               goto out;
-       }
+       u8 bssid[ETH_ALEN];
+       struct wpa_bss *bss;
 
-       /* Find the bssid's scan data */
-       for (i = 0; i < wpa_s->scan_res->num; i++) {
-               struct wpa_scan_res *search_res = wpa_s->scan_res->res[i];
-               char mac_str[18];
-
-               memset(mac_str, 0, sizeof(mac_str));
-               snprintf(mac_str, sizeof(mac_str) - 1, WPAS_DBUS_BSSID_FORMAT,
-                        MAC2STR(search_res->bssid));
-               if (!strcmp(bssid, mac_str)) {
-                       res = search_res;
-                       break;
-               }
-       }
+       if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
+               return wpas_dbus_new_invalid_bssid_error(message);
 
-       if (!res) {
-               reply = wpas_dbus_new_invalid_bssid_error(message);
-               goto out;
-       }
+       bss = wpa_bss_get_bssid(wpa_s, bssid);
+       if (bss == NULL)
+               return wpas_dbus_new_invalid_bssid_error(message);
 
        /* Dispatch the method call against the scanned bssid */
-       if (!strcmp(method, "properties"))
-               reply = wpas_dbus_bssid_properties(message, wpa_s, res);
+       if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
+               return wpas_dbus_bssid_properties(message, wpa_s, bss);
 
-out:
-       return reply;
+       return NULL;
 }
 
 
@@ -245,8 +216,12 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
        if (!msg_interface)
                goto out;
 
+       wpa_printf(MSG_MSGDUMP, "dbus[old/iface]: %s.%s (%s) [%s]",
+                  msg_interface, method, path,
+                  dbus_message_get_signature(message));
+
        iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
-                                                        &bssid);
+                                                        &bssid);
        if (iface_obj_path == NULL) {
                reply = wpas_dbus_new_invalid_iface_error(message);
                goto out;
@@ -256,7 +231,7 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
         * wpa_supplicant structure it's supposed to (which is wpa_s)
         */
        if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
-                                                 iface_obj_path) != wpa_s) {
+                                                 iface_obj_path) != wpa_s) {
                reply = wpas_dbus_new_invalid_iface_error(message);
                goto out;
        }
@@ -264,6 +239,7 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
        if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
                /* A method for one of this interface's configured networks */
                int nid = strtoul(network, NULL, 10);
+
                if (errno != EINVAL)
                        reply = wpas_dispatch_network_method(message, wpa_s,
                                                             nid);
@@ -297,28 +273,32 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
                        reply = wpas_dbus_iface_get_state(message, wpa_s);
                else if (!strcmp(method, "scanning"))
                        reply = wpas_dbus_iface_get_scanning(message, wpa_s);
+#ifndef CONFIG_NO_CONFIG_BLOBS
                else if (!strcmp(method, "setBlobs"))
                        reply = wpas_dbus_iface_set_blobs(message, wpa_s);
                else if (!strcmp(method, "removeBlobs"))
                        reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
+#endif /* CONFIG_NO_CONFIG_BLOBS */
 #ifdef CONFIG_WPS
-               else if (!os_strcmp(method, "wpsPbc"))
+               else if (os_strcmp(method, "wpsPbc") == 0)
                        reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
-               else if (!os_strcmp(method, "wpsPin"))
+               else if (os_strcmp(method, "wpsPin") == 0)
                        reply = wpas_dbus_iface_wps_pin(message, wpa_s);
-               else if (!os_strcmp(method, "wpsReg"))
+               else if (os_strcmp(method, "wpsReg") == 0)
                        reply = wpas_dbus_iface_wps_reg(message, wpa_s);
 #endif /* CONFIG_WPS */
+               else if (os_strcmp(method, "flush") == 0)
+                       reply = wpas_dbus_iface_flush(message, wpa_s);
        }
 
        /* If the message was handled, send back the reply */
+out:
        if (reply) {
                if (!dbus_message_get_no_reply(message))
                        dbus_connection_send(connection, reply, NULL);
                dbus_message_unref(reply);
        }
 
-out:
        os_free(iface_obj_path);
        os_free(network);
        os_free(bssid);
@@ -353,6 +333,10 @@ static DBusHandlerResult wpas_message_handler(DBusConnection *connection,
        if (!method || !path || !ctrl_iface || !msg_interface)
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
 
+       wpa_printf(MSG_MSGDUMP, "dbus[old]: %s.%s (%s) [%s]",
+                  msg_interface, method, path,
+                  dbus_message_get_signature(message));
+
        /* Validate the method interface */
        if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
                return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -397,29 +381,17 @@ void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
 {
        struct wpas_dbus_priv *iface = wpa_s->global->dbus;
        DBusMessage *_signal;
-       const char *path;
 
        /* Do nothing if the control interface is not turned on */
-       if (iface == NULL)
+       if (iface == NULL || !wpa_s->dbus_path)
                return;
 
-       path = wpa_supplicant_get_dbus_path(wpa_s);
-       if (path == NULL) {
-               perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
-                      "interface didn't have a dbus path");
-               wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_scan_results[dbus]: "
-                          "interface didn't have a dbus path; can't send "
-                          "scan result signal.");
-               return;
-       }
-       _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
                                          "ScanResultsAvailable");
        if (_signal == NULL) {
-               perror("wpa_supplicant_dbus_notify_scan_results[dbus]: "
-                      "couldn't create dbus signal; likely out of memory");
-               wpa_printf(MSG_ERROR, "dbus control interface: not enough "
-                          "memory to send scan results signal.");
+               wpa_printf(MSG_ERROR,
+                          "dbus: Not enough memory to send scan results signal");
                return;
        }
        dbus_connection_send(iface->con, _signal, NULL);
@@ -442,9 +414,11 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
 {
        struct wpas_dbus_priv *iface;
        DBusMessage *_signal = NULL;
-       const char *path;
        const char *new_state_str, *old_state_str;
 
+       if (wpa_s->dbus_path == NULL)
+               return; /* Skip signal since D-Bus setup is not yet ready */
+
        /* Do nothing if the control interface is not turned on */
        if (wpa_s->global == NULL)
                return;
@@ -456,49 +430,26 @@ void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
        if (new_state == old_state)
                return;
 
-       path = wpa_supplicant_get_dbus_path(wpa_s);
-       if (path == NULL) {
-               perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
-                      "interface didn't have a dbus path");
-               wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_state_change[dbus]: "
-                          "interface didn't have a dbus path; can't send "
-                          "signal.");
-               return;
-       }
-       _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
                                          "StateChange");
        if (_signal == NULL) {
-               perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
-                      "couldn't create dbus signal; likely out of memory");
                wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_state_change[dbus]: "
-                          "couldn't create dbus signal; likely out of "
-                          "memory.");
+                          "dbus: %s: could not create dbus signal; likely out of memory",
+                          __func__);
                return;
        }
 
        new_state_str = wpa_supplicant_state_txt(new_state);
        old_state_str = wpa_supplicant_state_txt(old_state);
-       if (new_state_str == NULL || old_state_str == NULL) {
-               perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
-                      "couldn't convert state strings");
-               wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_state_change[dbus]: "
-                          "couldn't convert state strings.");
-               goto out;
-       }
 
        if (!dbus_message_append_args(_signal,
-                                     DBUS_TYPE_STRING, &new_state_str,
-                                     DBUS_TYPE_STRING, &old_state_str,
-                                     DBUS_TYPE_INVALID)) {
-               perror("wpa_supplicant_dbus_notify_state_change[dbus]: "
-                      "not enough memory to construct state change signal.");
+                                     DBUS_TYPE_STRING, &new_state_str,
+                                     DBUS_TYPE_STRING, &old_state_str,
+                                     DBUS_TYPE_INVALID)) {
                wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_state_change[dbus]: "
-                          "not enough memory to construct state change "
-                          "signal.");
+                          "dbus: %s: Not enough memory to construct state change signal",
+                          __func__);
                goto out;
        }
 
@@ -520,42 +471,28 @@ void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
 {
        struct wpas_dbus_priv *iface = wpa_s->global->dbus;
        DBusMessage *_signal;
-       const char *path;
        dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
 
        /* Do nothing if the control interface is not turned on */
-       if (iface == NULL)
+       if (iface == NULL || !wpa_s->dbus_path)
                return;
 
-       path = wpa_supplicant_get_dbus_path(wpa_s);
-       if (path == NULL) {
-               perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface "
-                      "didn't have a dbus path");
-               wpa_printf(MSG_ERROR,
-                          "%s[dbus]: interface didn't have a dbus path; "
-                          "can't send scanning signal.", __FUNCTION__);
-               return;
-       }
-       _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
                                          "Scanning");
        if (_signal == NULL) {
-               perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't "
-                      "create dbus signal; likely out of memory");
-               wpa_printf(MSG_ERROR, "%s[dbus]: dbus control interface: not "
-                          "enough memory to send scan results signal.",
-                          __FUNCTION__);
+               wpa_printf(MSG_ERROR,
+                          "dbus: Not enough memory to send scan results signal");
                return;
        }
 
        if (dbus_message_append_args(_signal,
-                                    DBUS_TYPE_BOOLEAN, &scanning,
-                                    DBUS_TYPE_INVALID)) {
+                                    DBUS_TYPE_BOOLEAN, &scanning,
+                                    DBUS_TYPE_INVALID)) {
                dbus_connection_send(iface->con, _signal, NULL);
        } else {
-               perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough "
-                      "memory to construct signal.");
-               wpa_printf(MSG_ERROR, "%s[dbus]: not enough memory to "
-                          "construct signal.", __FUNCTION__);
+               wpa_printf(MSG_ERROR,
+                          "dbus: Not enough memory to construct signal");
        }
        dbus_message_unref(_signal);
 }
@@ -567,46 +504,31 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
 {
        struct wpas_dbus_priv *iface;
        DBusMessage *_signal = NULL;
-       const char *path;
 
        /* Do nothing if the control interface is not turned on */
        if (wpa_s->global == NULL)
                return;
        iface = wpa_s->global->dbus;
-       if (iface == NULL)
+       if (iface == NULL || !wpa_s->dbus_path)
                return;
 
-       path = wpa_supplicant_get_dbus_path(wpa_s);
-       if (path == NULL) {
-               perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                      "interface didn't have a dbus path");
-               wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                          "interface didn't have a dbus path; can't send "
-                          "signal.");
-               return;
-       }
-       _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
                                          "WpsCred");
        if (_signal == NULL) {
-               perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                      "couldn't create dbus signal; likely out of memory");
                wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                          "couldn't create dbus signal; likely out of "
-                          "memory.");
+                          "dbus: %s: Could not create dbus signal; likely out of memory",
+                          __func__);
                return;
        }
 
        if (!dbus_message_append_args(_signal,
-                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
                                      &cred->cred_attr, cred->cred_attr_len,
-                                     DBUS_TYPE_INVALID)) {
-               perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                      "not enough memory to construct signal.");
+                                     DBUS_TYPE_INVALID)) {
                wpa_printf(MSG_ERROR,
-                          "wpa_supplicant_dbus_notify_wps_cred[dbus]: "
-                          "not enough memory to construct signal.");
+                          "dbus: %s: Not enough memory to construct signal",
+                          __func__);
                goto out;
        }
 
@@ -622,6 +544,58 @@ void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
 }
 #endif /* CONFIG_WPS */
 
+void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
+                                             int depth, const char *subject,
+                                             const char *cert_hash,
+                                             const struct wpabuf *cert)
+{
+       struct wpas_dbus_priv *iface;
+       DBusMessage *_signal = NULL;
+       const char *hash;
+       const char *cert_hex;
+       int cert_hex_len;
+
+       /* Do nothing if the control interface is not turned on */
+       if (wpa_s->global == NULL)
+               return;
+       iface = wpa_s->global->dbus;
+       if (iface == NULL || !wpa_s->dbus_path)
+               return;
+
+       _signal = dbus_message_new_signal(wpa_s->dbus_path,
+                                         WPAS_DBUS_IFACE_INTERFACE,
+                                         "Certification");
+       if (_signal == NULL) {
+               wpa_printf(MSG_ERROR,
+                          "dbus: %s: Could not create dbus signal; likely out of memory",
+                          __func__);
+               return;
+       }
+
+       hash = cert_hash ? cert_hash : "";
+       cert_hex = cert ? wpabuf_head(cert) : "";
+       cert_hex_len = cert ? wpabuf_len(cert) : 0;
+
+       if (!dbus_message_append_args(_signal,
+                                     DBUS_TYPE_INT32, &depth,
+                                     DBUS_TYPE_STRING, &subject,
+                                     DBUS_TYPE_STRING, &hash,
+                                     DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+                                     &cert_hex, cert_hex_len,
+                                     DBUS_TYPE_INVALID)) {
+               wpa_printf(MSG_ERROR,
+                          "dbus: %s: Not enough memory to construct signal",
+                          __func__);
+               goto out;
+       }
+
+       dbus_connection_send(iface->con, _signal, NULL);
+
+out:
+       dbus_message_unref(_signal);
+
+}
+
 
 /**
  * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
@@ -643,9 +617,7 @@ int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
        if (!dbus_connection_register_object_path(iface->con,
                                                  WPAS_DBUS_PATH, &wpas_vtable,
                                                  iface)) {
-               perror("dbus_connection_register_object_path[dbus]");
-               wpa_printf(MSG_ERROR, "Could not set up DBus message "
-                          "handler.");
+               wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
                return -1;
        }
 
@@ -659,14 +631,13 @@ int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
        case DBUS_REQUEST_NAME_REPLY_EXISTS:
        case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
        case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
-               perror("dbus_bus_request_name[dbus]");
-               wpa_printf(MSG_ERROR, "Could not request DBus service name: "
-                          "already registered.");
+               wpa_printf(MSG_ERROR,
+                          "dbus: Could not request service name: already registered");
                break;
        default:
-               perror("dbus_bus_request_name[dbus]");
-               wpa_printf(MSG_ERROR, "Could not request DBus service name: "
-                          "%s %s.", error.name, error.message);
+               wpa_printf(MSG_ERROR,
+                          "dbus: Could not request service name: %s %s",
+                          error.name, error.message);
                break;
        }
        dbus_error_free(&error);
@@ -696,7 +667,6 @@ int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
        DBusObjectPathVTable vtable = {
                NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
        };
-       int ret = -1;
 
        /* Do nothing if the control interface is not turned on */
        if (ctrl_iface == NULL)
@@ -716,15 +686,13 @@ int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
        /* Register the message handler for the interface functions */
        if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
                                               wpa_s)) {
-               perror("wpas_dbus_register_iface [dbus]");
-               wpa_printf(MSG_ERROR, "Could not set up DBus message "
-                          "handler for interface %s.", wpa_s->ifname);
-               goto out;
+               wpa_printf(MSG_ERROR,
+                          "dbus: Could not set up message handler for interface %s",
+                          wpa_s->ifname);
+               return -1;
        }
-       ret = 0;
 
-out:
-       return ret;
+       return 0;
 }
 
 
@@ -739,19 +707,16 @@ int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
 {
        struct wpas_dbus_priv *ctrl_iface;
        DBusConnection *con;
-       const char *path;
 
        /* Do nothing if the control interface is not turned on */
        if (wpa_s == NULL || wpa_s->global == NULL)
                return 0;
        ctrl_iface = wpa_s->global->dbus;
-       if (ctrl_iface == NULL)
+       if (ctrl_iface == NULL || wpa_s->dbus_path == NULL)
                return 0;
 
        con = ctrl_iface->con;
-       path = wpa_supplicant_get_dbus_path(wpa_s);
-
-       if (!dbus_connection_unregister_object_path(con, path))
+       if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
                return -1;
 
        os_free(wpa_s->dbus_path);
@@ -773,19 +738,8 @@ struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
        struct wpa_supplicant *wpa_s;
 
        for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
-               if (strcmp(wpa_s->dbus_path, path) == 0)
+               if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0)
                        return wpa_s;
        }
        return NULL;
 }
-
-
-/**
- * wpa_supplicant_get_dbus_path - Get an interface's dbus path
- * @wpa_s: %wpa_supplicant interface structure
- * Returns: Interface's dbus object path, or %NULL on error
- */
-const char * wpa_supplicant_get_dbus_path(struct wpa_supplicant *wpa_s)
-{
-       return wpa_s->dbus_path;
-}