LCOV - code coverage report
Current view: top level - wpa_supplicant/dbus - dbus_old.c (source / functions) Hit Total Coverage
Test: wpa_supplicant/hostapd combined for hwsim test run 1443382998 Lines: 238 279 85.3 %
Date: 2015-09-27 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /*
       2             :  * WPA Supplicant / dbus-based control interface
       3             :  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
       4             :  *
       5             :  * This software may be distributed under the terms of the BSD license.
       6             :  * See README for more details.
       7             :  */
       8             : 
       9             : #include "includes.h"
      10             : #include <dbus/dbus.h>
      11             : 
      12             : #include "common.h"
      13             : #include "eloop.h"
      14             : #include "wps/wps.h"
      15             : #include "../config.h"
      16             : #include "../wpa_supplicant_i.h"
      17             : #include "../bss.h"
      18             : #include "dbus_old.h"
      19             : #include "dbus_old_handlers.h"
      20             : #include "dbus_common_i.h"
      21             : 
      22             : 
      23             : /**
      24             :  * wpas_dbus_decompose_object_path - Decompose an interface object path into parts
      25             :  * @path: The dbus object path
      26             :  * @network: (out) the configured network this object path refers to, if any
      27             :  * @bssid: (out) the scanned bssid this object path refers to, if any
      28             :  * Returns: The object path of the network interface this path refers to
      29             :  *
      30             :  * For a given object path, decomposes the object path into object id, network,
      31             :  * and BSSID parts, if those parts exist.
      32             :  */
      33         154 : char * wpas_dbus_decompose_object_path(const char *path, char **network,
      34             :                                        char **bssid)
      35             : {
      36         154 :         const unsigned int dev_path_prefix_len =
      37             :                 strlen(WPAS_DBUS_PATH_INTERFACES "/");
      38             :         char *obj_path_only;
      39             :         char *next_sep;
      40             : 
      41             :         /* Be a bit paranoid about path */
      42         154 :         if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/",
      43             :                              dev_path_prefix_len))
      44           3 :                 return NULL;
      45             : 
      46             :         /* Ensure there's something at the end of the path */
      47         151 :         if ((path + dev_path_prefix_len)[0] == '\0')
      48           0 :                 return NULL;
      49             : 
      50         151 :         obj_path_only = os_strdup(path);
      51         151 :         if (obj_path_only == NULL)
      52           1 :                 return NULL;
      53             : 
      54         150 :         next_sep = strchr(obj_path_only + dev_path_prefix_len, '/');
      55         150 :         if (next_sep != NULL) {
      56          55 :                 const char *net_part = strstr(next_sep,
      57             :                                               WPAS_DBUS_NETWORKS_PART "/");
      58          55 :                 const char *bssid_part = strstr(next_sep,
      59             :                                                 WPAS_DBUS_BSSIDS_PART "/");
      60             : 
      61          97 :                 if (network && net_part) {
      62             :                         /* Deal with a request for a configured network */
      63          42 :                         const char *net_name = net_part +
      64             :                                 strlen(WPAS_DBUS_NETWORKS_PART "/");
      65          42 :                         *network = NULL;
      66          42 :                         if (strlen(net_name))
      67          42 :                                 *network = os_strdup(net_name);
      68          13 :                 } else if (bssid && bssid_part) {
      69             :                         /* Deal with a request for a scanned BSSID */
      70          13 :                         const char *bssid_name = bssid_part +
      71             :                                 strlen(WPAS_DBUS_BSSIDS_PART "/");
      72          13 :                         if (strlen(bssid_name))
      73          13 :                                 *bssid = os_strdup(bssid_name);
      74             :                         else
      75           0 :                                 *bssid = NULL;
      76             :                 }
      77             : 
      78             :                 /* Cut off interface object path before "/" */
      79          55 :                 *next_sep = '\0';
      80             :         }
      81             : 
      82         150 :         return obj_path_only;
      83             : }
      84             : 
      85             : 
      86             : /**
      87             :  * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message
      88             :  * @message: Pointer to incoming dbus message this error refers to
      89             :  * Returns: A dbus error message
      90             :  *
      91             :  * Convenience function to create and return an invalid interface error
      92             :  */
      93           4 : DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message)
      94             : {
      95           4 :         return dbus_message_new_error(
      96             :                 message, WPAS_ERROR_INVALID_IFACE,
      97             :                 "wpa_supplicant knows nothing about this interface.");
      98             : }
      99             : 
     100             : 
     101             : /**
     102             :  * wpas_dbus_new_invalid_network_error - Return a new invalid network error message
     103             :  * @message: Pointer to incoming dbus message this error refers to
     104             :  * Returns: a dbus error message
     105             :  *
     106             :  * Convenience function to create and return an invalid network error
     107             :  */
     108          12 : DBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message)
     109             : {
     110          12 :         return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK,
     111             :                                       "The requested network does not exist.");
     112             : }
     113             : 
     114             : 
     115             : /**
     116             :  * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message
     117             :  * @message: Pointer to incoming dbus message this error refers to
     118             :  * Returns: a dbus error message
     119             :  *
     120             :  * Convenience function to create and return an invalid bssid error
     121             :  */
     122           3 : static DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message)
     123             : {
     124           3 :         return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID,
     125             :                                       "The BSSID requested was invalid.");
     126             : }
     127             : 
     128             : 
     129             : /**
     130             :  * wpas_dispatch_network_method - dispatch messages for configured networks
     131             :  * @message: the incoming dbus message
     132             :  * @wpa_s: a network interface's data
     133             :  * @network_id: id of the configured network we're interested in
     134             :  * Returns: a reply dbus message, or a dbus error message
     135             :  *
     136             :  * This function dispatches all incoming dbus messages for configured networks.
     137             :  */
     138          22 : static DBusMessage * wpas_dispatch_network_method(DBusMessage *message,
     139             :                                                   struct wpa_supplicant *wpa_s,
     140             :                                                   int network_id)
     141             : {
     142          22 :         DBusMessage *reply = NULL;
     143          22 :         const char *method = dbus_message_get_member(message);
     144             :         struct wpa_ssid *ssid;
     145             : 
     146          22 :         ssid = wpa_config_get_network(wpa_s->conf, network_id);
     147          22 :         if (ssid == NULL)
     148           2 :                 return wpas_dbus_new_invalid_network_error(message);
     149             : 
     150          20 :         if (!strcmp(method, "set"))
     151          13 :                 reply = wpas_dbus_iface_set_network(message, wpa_s, ssid);
     152           7 :         else if (!strcmp(method, "enable"))
     153           3 :                 reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid);
     154           4 :         else if (!strcmp(method, "disable"))
     155           4 :                 reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid);
     156             : 
     157          20 :         return reply;
     158             : }
     159             : 
     160             : 
     161             : /**
     162             :  * wpas_dispatch_bssid_method - dispatch messages for scanned networks
     163             :  * @message: the incoming dbus message
     164             :  * @wpa_s: a network interface's data
     165             :  * @bssid: bssid of the scanned network we're interested in
     166             :  * Returns: a reply dbus message, or a dbus error message
     167             :  *
     168             :  * This function dispatches all incoming dbus messages for scanned networks.
     169             :  */
     170           7 : static DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message,
     171             :                                                 struct wpa_supplicant *wpa_s,
     172             :                                                 const char *bssid_txt)
     173             : {
     174             :         u8 bssid[ETH_ALEN];
     175             :         struct wpa_bss *bss;
     176             : 
     177           7 :         if (hexstr2bin(bssid_txt, bssid, ETH_ALEN) < 0)
     178           1 :                 return wpas_dbus_new_invalid_bssid_error(message);
     179             : 
     180           6 :         bss = wpa_bss_get_bssid(wpa_s, bssid);
     181           6 :         if (bss == NULL)
     182           2 :                 return wpas_dbus_new_invalid_bssid_error(message);
     183             : 
     184             :         /* Dispatch the method call against the scanned bssid */
     185           4 :         if (os_strcmp(dbus_message_get_member(message), "properties") == 0)
     186           3 :                 return wpas_dbus_bssid_properties(message, wpa_s, bss);
     187             : 
     188           1 :         return NULL;
     189             : }
     190             : 
     191             : 
     192             : /**
     193             :  * wpas_iface_message_handler - Dispatch messages for interfaces or networks
     194             :  * @connection: Connection to the system message bus
     195             :  * @message: An incoming dbus message
     196             :  * @user_data: A pointer to a dbus control interface data structure
     197             :  * Returns: Whether or not the message was handled
     198             :  *
     199             :  * This function dispatches all incoming dbus messages for network interfaces,
     200             :  * or objects owned by them, such as scanned BSSIDs and configured networks.
     201             :  */
     202         140 : static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
     203             :                                                     DBusMessage *message,
     204             :                                                     void *user_data)
     205             : {
     206         140 :         struct wpa_supplicant *wpa_s = user_data;
     207         140 :         const char *method = dbus_message_get_member(message);
     208         140 :         const char *path = dbus_message_get_path(message);
     209         140 :         const char *msg_interface = dbus_message_get_interface(message);
     210         140 :         char *iface_obj_path = NULL;
     211         140 :         char *network = NULL;
     212         140 :         char *bssid = NULL;
     213         140 :         DBusMessage *reply = NULL;
     214             : 
     215             :         /* Caller must specify a message interface */
     216         140 :         if (!msg_interface)
     217           0 :                 goto out;
     218             : 
     219         140 :         wpa_printf(MSG_MSGDUMP, "dbus[old/iface]: %s.%s (%s) [%s]",
     220             :                    msg_interface, method, path,
     221             :                    dbus_message_get_signature(message));
     222             : 
     223         140 :         iface_obj_path = wpas_dbus_decompose_object_path(path, &network,
     224             :                                                          &bssid);
     225         140 :         if (iface_obj_path == NULL) {
     226           1 :                 reply = wpas_dbus_new_invalid_iface_error(message);
     227           1 :                 goto out;
     228             :         }
     229             : 
     230             :         /* Make sure the message's object path actually refers to the
     231             :          * wpa_supplicant structure it's supposed to (which is wpa_s)
     232             :          */
     233         139 :         if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global,
     234             :                                                   iface_obj_path) != wpa_s) {
     235           0 :                 reply = wpas_dbus_new_invalid_iface_error(message);
     236           0 :                 goto out;
     237             :         }
     238             : 
     239         161 :         if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) {
     240             :                 /* A method for one of this interface's configured networks */
     241          22 :                 int nid = strtoul(network, NULL, 10);
     242             : 
     243          22 :                 if (errno != EINVAL)
     244          22 :                         reply = wpas_dispatch_network_method(message, wpa_s,
     245             :                                                              nid);
     246             :                 else
     247           0 :                         reply = wpas_dbus_new_invalid_network_error(message);
     248         117 :         } else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) {
     249             :                 /* A method for one of this interface's scanned BSSIDs */
     250           7 :                 reply = wpas_dispatch_bssid_method(message, wpa_s, bssid);
     251         110 :         } else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) {
     252             :                 /* A method for an interface only. */
     253          76 :                 if (!strcmp(method, "scan"))
     254           1 :                         reply = wpas_dbus_iface_scan(message, wpa_s);
     255          75 :                 else if (!strcmp(method, "scanResults"))
     256           3 :                         reply = wpas_dbus_iface_scan_results(message, wpa_s);
     257          72 :                 else if (!strcmp(method, "addNetwork"))
     258           6 :                         reply = wpas_dbus_iface_add_network(message, wpa_s);
     259          66 :                 else if (!strcmp(method, "removeNetwork"))
     260          10 :                         reply = wpas_dbus_iface_remove_network(message, wpa_s);
     261          56 :                 else if (!strcmp(method, "selectNetwork"))
     262           7 :                         reply = wpas_dbus_iface_select_network(message, wpa_s);
     263          49 :                 else if (!strcmp(method, "capabilities"))
     264           2 :                         reply = wpas_dbus_iface_capabilities(message, wpa_s);
     265          47 :                 else if (!strcmp(method, "disconnect"))
     266           2 :                         reply = wpas_dbus_iface_disconnect(message, wpa_s);
     267          45 :                 else if (!strcmp(method, "setAPScan"))
     268           3 :                         reply = wpas_dbus_iface_set_ap_scan(message, wpa_s);
     269          42 :                 else if (!strcmp(method, "setSmartcardModules"))
     270          10 :                         reply = wpas_dbus_iface_set_smartcard_modules(message,
     271             :                                                                       wpa_s);
     272          32 :                 else if (!strcmp(method, "state"))
     273           1 :                         reply = wpas_dbus_iface_get_state(message, wpa_s);
     274          31 :                 else if (!strcmp(method, "scanning"))
     275           1 :                         reply = wpas_dbus_iface_get_scanning(message, wpa_s);
     276             : #ifndef CONFIG_NO_CONFIG_BLOBS
     277          30 :                 else if (!strcmp(method, "setBlobs"))
     278           8 :                         reply = wpas_dbus_iface_set_blobs(message, wpa_s);
     279          22 :                 else if (!strcmp(method, "removeBlobs"))
     280           5 :                         reply = wpas_dbus_iface_remove_blobs(message, wpa_s);
     281             : #endif /* CONFIG_NO_CONFIG_BLOBS */
     282             : #ifdef CONFIG_WPS
     283          17 :                 else if (os_strcmp(method, "wpsPbc") == 0)
     284           5 :                         reply = wpas_dbus_iface_wps_pbc(message, wpa_s);
     285          12 :                 else if (os_strcmp(method, "wpsPin") == 0)
     286           5 :                         reply = wpas_dbus_iface_wps_pin(message, wpa_s);
     287           7 :                 else if (os_strcmp(method, "wpsReg") == 0)
     288           4 :                         reply = wpas_dbus_iface_wps_reg(message, wpa_s);
     289             : #endif /* CONFIG_WPS */
     290           3 :                 else if (os_strcmp(method, "flush") == 0)
     291           3 :                         reply = wpas_dbus_iface_flush(message, wpa_s);
     292             :         }
     293             : 
     294             :         /* If the message was handled, send back the reply */
     295             : out:
     296         140 :         if (reply) {
     297         105 :                 if (!dbus_message_get_no_reply(message))
     298         105 :                         dbus_connection_send(connection, reply, NULL);
     299         105 :                 dbus_message_unref(reply);
     300             :         }
     301             : 
     302         140 :         os_free(iface_obj_path);
     303         140 :         os_free(network);
     304         140 :         os_free(bssid);
     305         140 :         return reply ? DBUS_HANDLER_RESULT_HANDLED :
     306             :                 DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     307             : }
     308             : 
     309             : 
     310             : /**
     311             :  * wpas_message_handler - dispatch incoming dbus messages
     312             :  * @connection: connection to the system message bus
     313             :  * @message: an incoming dbus message
     314             :  * @user_data: a pointer to a dbus control interface data structure
     315             :  * Returns: whether or not the message was handled
     316             :  *
     317             :  * This function dispatches all incoming dbus messages to the correct
     318             :  * handlers, depending on what the message's target object path is,
     319             :  * and what the method call is.
     320             :  */
     321          56 : static DBusHandlerResult wpas_message_handler(DBusConnection *connection,
     322             :         DBusMessage *message, void *user_data)
     323             : {
     324          56 :         struct wpas_dbus_priv *ctrl_iface = user_data;
     325             :         const char *method;
     326             :         const char *path;
     327             :         const char *msg_interface;
     328          56 :         DBusMessage *reply = NULL;
     329             : 
     330          56 :         method = dbus_message_get_member(message);
     331          56 :         path = dbus_message_get_path(message);
     332          56 :         msg_interface = dbus_message_get_interface(message);
     333          56 :         if (!method || !path || !ctrl_iface || !msg_interface)
     334           0 :                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     335             : 
     336          56 :         wpa_printf(MSG_MSGDUMP, "dbus[old]: %s.%s (%s) [%s]",
     337             :                    msg_interface, method, path,
     338             :                    dbus_message_get_signature(message));
     339             : 
     340             :         /* Validate the method interface */
     341          56 :         if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0)
     342          17 :                 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     343             : 
     344          39 :         if (!strcmp(path, WPAS_DBUS_PATH)) {
     345             :                 /* dispatch methods against our global dbus interface here */
     346          39 :                 if (!strcmp(method, "addInterface")) {
     347          13 :                         reply = wpas_dbus_global_add_interface(
     348             :                                 message, ctrl_iface->global);
     349          26 :                 } else if (!strcmp(method, "removeInterface")) {
     350           3 :                         reply = wpas_dbus_global_remove_interface(
     351             :                                 message, ctrl_iface->global);
     352          23 :                 } else if (!strcmp(method, "getInterface")) {
     353          20 :                         reply = wpas_dbus_global_get_interface(
     354             :                                 message, ctrl_iface->global);
     355           3 :                 } else if (!strcmp(method, "setDebugParams")) {
     356           3 :                         reply = wpas_dbus_global_set_debugparams(
     357             :                                 message, ctrl_iface->global);
     358             :                 }
     359             :         }
     360             : 
     361             :         /* If the message was handled, send back the reply */
     362          39 :         if (reply) {
     363          39 :                 if (!dbus_message_get_no_reply(message))
     364          39 :                         dbus_connection_send(connection, reply, NULL);
     365          39 :                 dbus_message_unref(reply);
     366             :         }
     367             : 
     368          39 :         return reply ? DBUS_HANDLER_RESULT_HANDLED :
     369             :                 DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
     370             : }
     371             : 
     372             : 
     373             : /**
     374             :  * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal
     375             :  * @wpa_s: %wpa_supplicant network interface data
     376             :  * Returns: 0 on success, -1 on failure
     377             :  *
     378             :  * Notify listeners that this interface has updated scan results.
     379             :  */
     380        3600 : void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
     381             : {
     382        3600 :         struct wpas_dbus_priv *iface = wpa_s->global->dbus;
     383             :         DBusMessage *_signal;
     384             : 
     385             :         /* Do nothing if the control interface is not turned on */
     386        3600 :         if (iface == NULL || !wpa_s->dbus_path)
     387        1729 :                 return;
     388             : 
     389        1871 :         _signal = dbus_message_new_signal(wpa_s->dbus_path,
     390             :                                           WPAS_DBUS_IFACE_INTERFACE,
     391             :                                           "ScanResultsAvailable");
     392        1871 :         if (_signal == NULL) {
     393           0 :                 wpa_printf(MSG_ERROR,
     394             :                            "dbus: Not enough memory to send scan results signal");
     395           0 :                 return;
     396             :         }
     397        1871 :         dbus_connection_send(iface->con, _signal, NULL);
     398        1871 :         dbus_message_unref(_signal);
     399             : }
     400             : 
     401             : 
     402             : /**
     403             :  * wpa_supplicant_dbus_notify_state_change - Send a state change signal
     404             :  * @wpa_s: %wpa_supplicant network interface data
     405             :  * @new_state: new state wpa_supplicant is entering
     406             :  * @old_state: old state wpa_supplicant is leaving
     407             :  * Returns: 0 on success, -1 on failure
     408             :  *
     409             :  * Notify listeners that wpa_supplicant has changed state
     410             :  */
     411       24339 : void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
     412             :                                              enum wpa_states new_state,
     413             :                                              enum wpa_states old_state)
     414             : {
     415             :         struct wpas_dbus_priv *iface;
     416       24339 :         DBusMessage *_signal = NULL;
     417             :         const char *new_state_str, *old_state_str;
     418             : 
     419       24339 :         if (wpa_s->dbus_path == NULL)
     420       15198 :                 return; /* Skip signal since D-Bus setup is not yet ready */
     421             : 
     422             :         /* Do nothing if the control interface is not turned on */
     423       16740 :         if (wpa_s->global == NULL)
     424           0 :                 return;
     425       16740 :         iface = wpa_s->global->dbus;
     426       16740 :         if (iface == NULL)
     427           0 :                 return;
     428             : 
     429             :         /* Only send signal if state really changed */
     430       16740 :         if (new_state == old_state)
     431           0 :                 return;
     432             : 
     433       16740 :         _signal = dbus_message_new_signal(wpa_s->dbus_path,
     434             :                                           WPAS_DBUS_IFACE_INTERFACE,
     435             :                                           "StateChange");
     436       16740 :         if (_signal == NULL) {
     437           0 :                 wpa_printf(MSG_ERROR,
     438             :                            "dbus: %s: could not create dbus signal; likely out of memory",
     439             :                            __func__);
     440           0 :                 return;
     441             :         }
     442             : 
     443       16740 :         new_state_str = wpa_supplicant_state_txt(new_state);
     444       16740 :         old_state_str = wpa_supplicant_state_txt(old_state);
     445             : 
     446       16740 :         if (!dbus_message_append_args(_signal,
     447             :                                       DBUS_TYPE_STRING, &new_state_str,
     448             :                                       DBUS_TYPE_STRING, &old_state_str,
     449             :                                       DBUS_TYPE_INVALID)) {
     450           0 :                 wpa_printf(MSG_ERROR,
     451             :                            "dbus: %s: Not enough memory to construct state change signal",
     452             :                            __func__);
     453           0 :                 goto out;
     454             :         }
     455             : 
     456       16740 :         dbus_connection_send(iface->con, _signal, NULL);
     457             : 
     458             : out:
     459       16740 :         dbus_message_unref(_signal);
     460             : }
     461             : 
     462             : 
     463             : /**
     464             :  * wpa_supplicant_dbus_notify_scanning - send scanning status
     465             :  * @wpa_s: %wpa_supplicant network interface data
     466             :  * Returns: 0 on success, -1 on failure
     467             :  *
     468             :  * Notify listeners of interface scanning state changes
     469             :  */
     470        7434 : void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
     471             : {
     472        7434 :         struct wpas_dbus_priv *iface = wpa_s->global->dbus;
     473             :         DBusMessage *_signal;
     474        7434 :         dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
     475             : 
     476             :         /* Do nothing if the control interface is not turned on */
     477        7434 :         if (iface == NULL || !wpa_s->dbus_path)
     478        6860 :                 return;
     479             : 
     480        4004 :         _signal = dbus_message_new_signal(wpa_s->dbus_path,
     481             :                                           WPAS_DBUS_IFACE_INTERFACE,
     482             :                                           "Scanning");
     483        4004 :         if (_signal == NULL) {
     484           0 :                 wpa_printf(MSG_ERROR,
     485             :                            "dbus: Not enough memory to send scan results signal");
     486           0 :                 return;
     487             :         }
     488             : 
     489        4004 :         if (dbus_message_append_args(_signal,
     490             :                                      DBUS_TYPE_BOOLEAN, &scanning,
     491             :                                      DBUS_TYPE_INVALID)) {
     492        4004 :                 dbus_connection_send(iface->con, _signal, NULL);
     493             :         } else {
     494           0 :                 wpa_printf(MSG_ERROR,
     495             :                            "dbus: Not enough memory to construct signal");
     496             :         }
     497        4004 :         dbus_message_unref(_signal);
     498             : }
     499             : 
     500             : 
     501             : #ifdef CONFIG_WPS
     502          11 : void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
     503             :                                          const struct wps_credential *cred)
     504             : {
     505             :         struct wpas_dbus_priv *iface;
     506          11 :         DBusMessage *_signal = NULL;
     507             : 
     508             :         /* Do nothing if the control interface is not turned on */
     509          11 :         if (wpa_s->global == NULL)
     510           0 :                 return;
     511          11 :         iface = wpa_s->global->dbus;
     512          11 :         if (iface == NULL || !wpa_s->dbus_path)
     513           0 :                 return;
     514             : 
     515          11 :         _signal = dbus_message_new_signal(wpa_s->dbus_path,
     516             :                                           WPAS_DBUS_IFACE_INTERFACE,
     517             :                                           "WpsCred");
     518          11 :         if (_signal == NULL) {
     519           0 :                 wpa_printf(MSG_ERROR,
     520             :                            "dbus: %s: Could not create dbus signal; likely out of memory",
     521             :                            __func__);
     522           0 :                 return;
     523             :         }
     524             : 
     525          11 :         if (!dbus_message_append_args(_signal,
     526             :                                       DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
     527             :                                       &cred->cred_attr, cred->cred_attr_len,
     528             :                                       DBUS_TYPE_INVALID)) {
     529           0 :                 wpa_printf(MSG_ERROR,
     530             :                            "dbus: %s: Not enough memory to construct signal",
     531             :                            __func__);
     532           0 :                 goto out;
     533             :         }
     534             : 
     535          11 :         dbus_connection_send(iface->con, _signal, NULL);
     536             : 
     537             : out:
     538          11 :         dbus_message_unref(_signal);
     539             : }
     540             : #else /* CONFIG_WPS */
     541             : void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
     542             :                                          const struct wps_credential *cred)
     543             : {
     544             : }
     545             : #endif /* CONFIG_WPS */
     546             : 
     547         582 : void wpa_supplicant_dbus_notify_certification(struct wpa_supplicant *wpa_s,
     548             :                                               int depth, const char *subject,
     549             :                                               const char *cert_hash,
     550             :                                               const struct wpabuf *cert)
     551             : {
     552             :         struct wpas_dbus_priv *iface;
     553         582 :         DBusMessage *_signal = NULL;
     554             :         const char *hash;
     555             :         const char *cert_hex;
     556             :         int cert_hex_len;
     557             : 
     558             :         /* Do nothing if the control interface is not turned on */
     559         582 :         if (wpa_s->global == NULL)
     560          59 :                 return;
     561         582 :         iface = wpa_s->global->dbus;
     562         582 :         if (iface == NULL || !wpa_s->dbus_path)
     563          59 :                 return;
     564             : 
     565         523 :         _signal = dbus_message_new_signal(wpa_s->dbus_path,
     566             :                                           WPAS_DBUS_IFACE_INTERFACE,
     567             :                                           "Certification");
     568         523 :         if (_signal == NULL) {
     569           0 :                 wpa_printf(MSG_ERROR,
     570             :                            "dbus: %s: Could not create dbus signal; likely out of memory",
     571             :                            __func__);
     572           0 :                 return;
     573             :         }
     574             : 
     575         523 :         hash = cert_hash ? cert_hash : "";
     576         523 :         cert_hex = cert ? wpabuf_head(cert) : "";
     577         523 :         cert_hex_len = cert ? wpabuf_len(cert) : 0;
     578             : 
     579         523 :         if (!dbus_message_append_args(_signal,
     580             :                                       DBUS_TYPE_INT32, &depth,
     581             :                                       DBUS_TYPE_STRING, &subject,
     582             :                                       DBUS_TYPE_STRING, &hash,
     583             :                                       DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
     584             :                                       &cert_hex, cert_hex_len,
     585             :                                       DBUS_TYPE_INVALID)) {
     586           0 :                 wpa_printf(MSG_ERROR,
     587             :                            "dbus: %s: Not enough memory to construct signal",
     588             :                            __func__);
     589           0 :                 goto out;
     590             :         }
     591             : 
     592         523 :         dbus_connection_send(iface->con, _signal, NULL);
     593             : 
     594             : out:
     595         523 :         dbus_message_unref(_signal);
     596             : 
     597             : }
     598             : 
     599             : 
     600             : /**
     601             :  * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface
     602             :  * @global: Pointer to global data from wpa_supplicant_init()
     603             :  * Returns: 0 on success, -1 on failure
     604             :  *
     605             :  * Initialize the dbus control interface and start receiving commands from
     606             :  * external programs over the bus.
     607             :  */
     608           6 : int wpa_supplicant_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface)
     609             : {
     610             :         DBusError error;
     611           6 :         int ret = -1;
     612           6 :         DBusObjectPathVTable wpas_vtable = {
     613             :                 NULL, &wpas_message_handler, NULL, NULL, NULL, NULL
     614             :         };
     615             : 
     616             :         /* Register the message handler for the global dbus interface */
     617           6 :         if (!dbus_connection_register_object_path(iface->con,
     618             :                                                   WPAS_DBUS_PATH, &wpas_vtable,
     619             :                                                   iface)) {
     620           0 :                 wpa_printf(MSG_ERROR, "dbus: Could not set up message handler");
     621           0 :                 return -1;
     622             :         }
     623             : 
     624             :         /* Register our service with the message bus */
     625           6 :         dbus_error_init(&error);
     626           6 :         switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE,
     627             :                                       0, &error)) {
     628             :         case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
     629           6 :                 ret = 0;
     630           6 :                 break;
     631             :         case DBUS_REQUEST_NAME_REPLY_EXISTS:
     632             :         case DBUS_REQUEST_NAME_REPLY_IN_QUEUE:
     633             :         case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
     634           0 :                 wpa_printf(MSG_ERROR,
     635             :                            "dbus: Could not request service name: already registered");
     636           0 :                 break;
     637             :         default:
     638           0 :                 wpa_printf(MSG_ERROR,
     639             :                            "dbus: Could not request service name: %s %s",
     640             :                            error.name, error.message);
     641           0 :                 break;
     642             :         }
     643           6 :         dbus_error_free(&error);
     644             : 
     645           6 :         if (ret != 0)
     646           0 :                 return -1;
     647             : 
     648           6 :         wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE
     649             :                    "'.");
     650             : 
     651           6 :         return 0;
     652             : }
     653             : 
     654             : 
     655             : /**
     656             :  * wpas_dbus_register_new_iface - Register a new interface with dbus
     657             :  * @wpa_s: %wpa_supplicant interface description structure to register
     658             :  * Returns: 0 on success, -1 on error
     659             :  *
     660             :  * Registers a new interface with dbus and assigns it a dbus object path.
     661             :  */
     662         567 : int wpas_dbus_register_iface(struct wpa_supplicant *wpa_s)
     663             : {
     664         567 :         struct wpas_dbus_priv *ctrl_iface = wpa_s->global->dbus;
     665             :         DBusConnection * con;
     666             :         u32 next;
     667         567 :         DBusObjectPathVTable vtable = {
     668             :                 NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL
     669             :         };
     670             : 
     671             :         /* Do nothing if the control interface is not turned on */
     672         567 :         if (ctrl_iface == NULL)
     673         417 :                 return 0;
     674             : 
     675         150 :         con = ctrl_iface->con;
     676         150 :         next = ctrl_iface->next_objid++;
     677             : 
     678             :         /* Create and set the interface's object path */
     679         150 :         wpa_s->dbus_path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX);
     680         150 :         if (wpa_s->dbus_path == NULL)
     681           1 :                 return -1;
     682         149 :         os_snprintf(wpa_s->dbus_path, WPAS_DBUS_OBJECT_PATH_MAX,
     683             :                     WPAS_DBUS_PATH_INTERFACES "/%u",
     684             :                     next);
     685             : 
     686             :         /* Register the message handler for the interface functions */
     687         149 :         if (!dbus_connection_register_fallback(con, wpa_s->dbus_path, &vtable,
     688             :                                                wpa_s)) {
     689           0 :                 wpa_printf(MSG_ERROR,
     690             :                            "dbus: Could not set up message handler for interface %s",
     691           0 :                            wpa_s->ifname);
     692           0 :                 return -1;
     693             :         }
     694             : 
     695         149 :         return 0;
     696             : }
     697             : 
     698             : 
     699             : /**
     700             :  * wpas_dbus_unregister_iface - Unregister an interface from dbus
     701             :  * @wpa_s: wpa_supplicant interface structure
     702             :  * Returns: 0 on success, -1 on failure
     703             :  *
     704             :  * Unregisters the interface with dbus
     705             :  */
     706         567 : int wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s)
     707             : {
     708             :         struct wpas_dbus_priv *ctrl_iface;
     709             :         DBusConnection *con;
     710             : 
     711             :         /* Do nothing if the control interface is not turned on */
     712         567 :         if (wpa_s == NULL || wpa_s->global == NULL)
     713           0 :                 return 0;
     714         567 :         ctrl_iface = wpa_s->global->dbus;
     715         567 :         if (ctrl_iface == NULL || wpa_s->dbus_path == NULL)
     716         418 :                 return 0;
     717             : 
     718         149 :         con = ctrl_iface->con;
     719         149 :         if (!dbus_connection_unregister_object_path(con, wpa_s->dbus_path))
     720           0 :                 return -1;
     721             : 
     722         149 :         os_free(wpa_s->dbus_path);
     723         149 :         wpa_s->dbus_path = NULL;
     724             : 
     725         149 :         return 0;
     726             : }
     727             : 
     728             : 
     729             : /**
     730             :  * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface
     731             :  * @global: Pointer to global data from wpa_supplicant_init()
     732             :  * @path: Pointer to a dbus object path representing an interface
     733             :  * Returns: Pointer to the interface or %NULL if not found
     734             :  */
     735         141 : struct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path(
     736             :         struct wpa_global *global, const char *path)
     737             : {
     738             :         struct wpa_supplicant *wpa_s;
     739             : 
     740         142 :         for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
     741         141 :                 if (wpa_s->dbus_path && strcmp(wpa_s->dbus_path, path) == 0)
     742         140 :                         return wpa_s;
     743             :         }
     744           1 :         return NULL;
     745             : }

Generated by: LCOV version 1.10