dbus_old_handlers.c
Go to the documentation of this file.
00001 /*
00002  * WPA Supplicant / dbus-based control interface
00003  * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
00004  *
00005  * This program is free software; you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 2 as
00007  * published by the Free Software Foundation.
00008  *
00009  * Alternatively, this software may be distributed under the terms of BSD
00010  * license.
00011  *
00012  * See README and COPYING for more details.
00013  */
00014 
00015 #include "includes.h"
00016 #include <dbus/dbus.h>
00017 
00018 #include "common.h"
00019 #include "eap_peer/eap_methods.h"
00020 #include "common/ieee802_11_defs.h"
00021 #include "eapol_supp/eapol_supp_sm.h"
00022 #include "rsn_supp/wpa.h"
00023 #include "../config.h"
00024 #include "../wpa_supplicant_i.h"
00025 #include "../driver_i.h"
00026 #include "../notify.h"
00027 #include "../wpas_glue.h"
00028 #include "../bss.h"
00029 #include "../scan.h"
00030 #include "dbus_old.h"
00031 #include "dbus_old_handlers.h"
00032 #include "dbus_dict_helpers.h"
00033 
00034 extern int wpa_debug_level;
00035 extern int wpa_debug_show_keys;
00036 extern int wpa_debug_timestamp;
00037 
00045 DBusMessage * wpas_dbus_new_invalid_opts_error(DBusMessage *message,
00046                                                const char *arg)
00047 {
00048         DBusMessage *reply;
00049 
00050         reply = dbus_message_new_error(message, WPAS_ERROR_INVALID_OPTS,
00051                                        "Did not receive correct message "
00052                                        "arguments.");
00053         if (arg != NULL)
00054                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &arg,
00055                                          DBUS_TYPE_INVALID);
00056 
00057         return reply;
00058 }
00059 
00060 
00069 DBusMessage * wpas_dbus_new_success_reply(DBusMessage *message)
00070 {
00071         DBusMessage *reply;
00072         unsigned int success = 1;
00073 
00074         reply = dbus_message_new_method_return(message);
00075         dbus_message_append_args(reply, DBUS_TYPE_UINT32, &success,
00076                                  DBUS_TYPE_INVALID);
00077         return reply;
00078 }
00079 
00080 
00092 DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message,
00093                                              struct wpa_global *global)
00094 {
00095         char *ifname = NULL;
00096         char *driver = NULL;
00097         char *driver_param = NULL;
00098         char *confname = NULL;
00099         char *bridge_ifname = NULL;
00100         DBusMessage *reply = NULL;
00101         DBusMessageIter iter;
00102 
00103         dbus_message_iter_init(message, &iter);
00104 
00105         /* First argument: interface name (DBUS_TYPE_STRING)
00106          *    Required; must be non-zero length
00107          */
00108         if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
00109                 goto error;
00110         dbus_message_iter_get_basic(&iter, &ifname);
00111         if (!os_strlen(ifname))
00112                 goto error;
00113 
00114         /* Second argument: dict of options */
00115         if (dbus_message_iter_next(&iter)) {
00116                 DBusMessageIter iter_dict;
00117                 struct wpa_dbus_dict_entry entry;
00118 
00119                 if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
00120                         goto error;
00121                 while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
00122                         if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
00123                                 goto error;
00124                         if (!strcmp(entry.key, "driver") &&
00125                             (entry.type == DBUS_TYPE_STRING)) {
00126                                 driver = os_strdup(entry.str_value);
00127                                 wpa_dbus_dict_entry_clear(&entry);
00128                                 if (driver == NULL)
00129                                         goto error;
00130                         } else if (!strcmp(entry.key, "driver-params") &&
00131                                    (entry.type == DBUS_TYPE_STRING)) {
00132                                 driver_param = os_strdup(entry.str_value);
00133                                 wpa_dbus_dict_entry_clear(&entry);
00134                                 if (driver_param == NULL)
00135                                         goto error;
00136                         } else if (!strcmp(entry.key, "config-file") &&
00137                                    (entry.type == DBUS_TYPE_STRING)) {
00138                                 confname = os_strdup(entry.str_value);
00139                                 wpa_dbus_dict_entry_clear(&entry);
00140                                 if (confname == NULL)
00141                                         goto error;
00142                         } else if (!strcmp(entry.key, "bridge-ifname") &&
00143                                    (entry.type == DBUS_TYPE_STRING)) {
00144                                 bridge_ifname = os_strdup(entry.str_value);
00145                                 wpa_dbus_dict_entry_clear(&entry);
00146                                 if (bridge_ifname == NULL)
00147                                         goto error;
00148                         } else {
00149                                 wpa_dbus_dict_entry_clear(&entry);
00150                                 goto error;
00151                         }
00152                 }
00153         }
00154 
00155         /*
00156          * Try to get the wpa_supplicant record for this iface, return
00157          * an error if we already control it.
00158          */
00159         if (wpa_supplicant_get_iface(global, ifname) != NULL) {
00160                 reply = dbus_message_new_error(message,
00161                                                WPAS_ERROR_EXISTS_ERROR,
00162                                                "wpa_supplicant already "
00163                                                "controls this interface.");
00164         } else {
00165                 struct wpa_supplicant *wpa_s;
00166                 struct wpa_interface iface;
00167                 os_memset(&iface, 0, sizeof(iface));
00168                 iface.ifname = ifname;
00169                 iface.driver = driver;
00170                 iface.driver_param = driver_param;
00171                 iface.confname = confname;
00172                 iface.bridge_ifname = bridge_ifname;
00173                 /* Otherwise, have wpa_supplicant attach to it. */
00174                 if ((wpa_s = wpa_supplicant_add_iface(global, &iface))) {
00175                         const char *path = wpa_s->dbus_path;
00176                         reply = dbus_message_new_method_return(message);
00177                         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
00178                                                  &path, DBUS_TYPE_INVALID);
00179                 } else {
00180                         reply = dbus_message_new_error(message,
00181                                                        WPAS_ERROR_ADD_ERROR,
00182                                                        "wpa_supplicant "
00183                                                        "couldn't grab this "
00184                                                        "interface.");
00185                 }
00186         }
00187 
00188 out:
00189         os_free(driver);
00190         os_free(driver_param);
00191         os_free(confname);
00192         os_free(bridge_ifname);
00193         return reply;
00194 
00195 error:
00196         reply = wpas_dbus_new_invalid_opts_error(message, NULL);
00197         goto out;
00198 }
00199 
00200 
00212 DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message,
00213                                                 struct wpa_global *global)
00214 {
00215         struct wpa_supplicant *wpa_s;
00216         char *path;
00217         DBusMessage *reply = NULL;
00218 
00219         if (!dbus_message_get_args(message, NULL,
00220                                    DBUS_TYPE_OBJECT_PATH, &path,
00221                                    DBUS_TYPE_INVALID)) {
00222                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
00223                 goto out;
00224         }
00225 
00226         wpa_s = wpa_supplicant_get_iface_by_dbus_path(global, path);
00227         if (wpa_s == NULL) {
00228                 reply = wpas_dbus_new_invalid_iface_error(message);
00229                 goto out;
00230         }
00231 
00232         if (!wpa_supplicant_remove_iface(global, wpa_s)) {
00233                 reply = wpas_dbus_new_success_reply(message);
00234         } else {
00235                 reply = dbus_message_new_error(message,
00236                                                WPAS_ERROR_REMOVE_ERROR,
00237                                                "wpa_supplicant couldn't "
00238                                                "remove this interface.");
00239         }
00240 
00241 out:
00242         return reply;
00243 }
00244 
00245 
00256 DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message,
00257                                              struct wpa_global *global)
00258 {
00259         DBusMessage *reply = NULL;
00260         const char *ifname;
00261         const char *path;
00262         struct wpa_supplicant *wpa_s;
00263 
00264         if (!dbus_message_get_args(message, NULL,
00265                                    DBUS_TYPE_STRING, &ifname,
00266                                    DBUS_TYPE_INVALID)) {
00267                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
00268                 goto out;
00269         }
00270 
00271         wpa_s = wpa_supplicant_get_iface(global, ifname);
00272         if (wpa_s == NULL) {
00273                 reply = wpas_dbus_new_invalid_iface_error(message);
00274                 goto out;
00275         }
00276 
00277         path = wpa_s->dbus_path;
00278         reply = dbus_message_new_method_return(message);
00279         dbus_message_append_args(reply,
00280                                  DBUS_TYPE_OBJECT_PATH, &path,
00281                                  DBUS_TYPE_INVALID);
00282 
00283 out:
00284         return reply;
00285 }
00286 
00287 
00298 DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message,
00299                                                struct wpa_global *global)
00300 {
00301         DBusMessage *reply = NULL;
00302         int debug_level;
00303         dbus_bool_t debug_timestamp;
00304         dbus_bool_t debug_show_keys;
00305 
00306         if (!dbus_message_get_args(message, NULL,
00307                                    DBUS_TYPE_INT32, &debug_level,
00308                                    DBUS_TYPE_BOOLEAN, &debug_timestamp,
00309                                    DBUS_TYPE_BOOLEAN, &debug_show_keys,
00310                                    DBUS_TYPE_INVALID)) {
00311                 return wpas_dbus_new_invalid_opts_error(message, NULL);
00312         }
00313 
00314         if (wpa_supplicant_set_debug_params(global, debug_level,
00315                                             debug_timestamp ? 1 : 0,
00316                                             debug_show_keys ? 1 : 0)) {
00317                 return wpas_dbus_new_invalid_opts_error(message, NULL);
00318         }
00319 
00320         reply = wpas_dbus_new_success_reply(message);
00321 
00322         return reply;
00323 }
00324 
00325 
00337 DBusMessage * wpas_dbus_iface_scan(DBusMessage *message,
00338                                    struct wpa_supplicant *wpa_s)
00339 {
00340         wpa_s->scan_req = 2;
00341         wpa_supplicant_req_scan(wpa_s, 0, 0);
00342         return wpas_dbus_new_success_reply(message);
00343 }
00344 
00345 
00356 DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message,
00357                                            struct wpa_supplicant *wpa_s)
00358 {
00359         DBusMessage *reply = NULL;
00360         DBusMessageIter iter;
00361         DBusMessageIter sub_iter;
00362         struct wpa_bss *bss;
00363 
00364         /* Create and initialize the return message */
00365         reply = dbus_message_new_method_return(message);
00366         dbus_message_iter_init_append(reply, &iter);
00367         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
00368                                          DBUS_TYPE_OBJECT_PATH_AS_STRING,
00369                                          &sub_iter);
00370 
00371         /* Loop through scan results and append each result's object path */
00372         dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
00373                 char path_buf[WPAS_DBUS_OBJECT_PATH_MAX];
00374                 char *path = path_buf;
00375 
00376                 /* Construct the object path for this network.  Note that ':'
00377                  * is not a valid character in dbus object paths.
00378                  */
00379                 os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
00380                             "%s/" WPAS_DBUS_BSSIDS_PART "/"
00381                             WPAS_DBUS_BSSID_FORMAT,
00382                             wpa_s->dbus_path, MAC2STR(bss->bssid));
00383                 dbus_message_iter_append_basic(&sub_iter,
00384                                                DBUS_TYPE_OBJECT_PATH, &path);
00385         }
00386 
00387         dbus_message_iter_close_container(&iter, &sub_iter);
00388 
00389         return reply;
00390 }
00391 
00392 
00403 DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message,
00404                                          struct wpa_supplicant *wpa_s,
00405                                          struct wpa_bss *bss)
00406 {
00407         DBusMessage *reply;
00408         DBusMessageIter iter, iter_dict;
00409         const u8 *ie;
00410 
00411         /* Dump the properties into a dbus message */
00412         reply = dbus_message_new_method_return(message);
00413 
00414         dbus_message_iter_init_append(reply, &iter);
00415         if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
00416                 goto error;
00417 
00418         if (!wpa_dbus_dict_append_byte_array(&iter_dict, "bssid",
00419                                              (const char *) bss->bssid,
00420                                              ETH_ALEN))
00421                 goto error;
00422 
00423         ie = wpa_bss_get_ie(bss, WLAN_EID_SSID);
00424         if (ie) {
00425                 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "ssid",
00426                                                      (const char *) (ie + 2),
00427                                                      ie[1]))
00428                 goto error;
00429         }
00430 
00431         ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
00432         if (ie) {
00433                 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpaie",
00434                                                      (const char *) ie,
00435                                                      ie[1] + 2))
00436                         goto error;
00437         }
00438 
00439         ie = wpa_bss_get_ie(bss, WLAN_EID_RSN);
00440         if (ie) {
00441                 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "rsnie",
00442                                                      (const char *) ie,
00443                                                      ie[1] + 2))
00444                         goto error;
00445         }
00446 
00447         ie = wpa_bss_get_vendor_ie(bss, WPS_IE_VENDOR_TYPE);
00448         if (ie) {
00449                 if (!wpa_dbus_dict_append_byte_array(&iter_dict, "wpsie",
00450                                                      (const char *) ie,
00451                                                      ie[1] + 2))
00452                         goto error;
00453         }
00454 
00455         if (bss->freq) {
00456                 if (!wpa_dbus_dict_append_int32(&iter_dict, "frequency",
00457                                                 bss->freq))
00458                         goto error;
00459         }
00460         if (!wpa_dbus_dict_append_uint16(&iter_dict, "capabilities",
00461                                          bss->caps))
00462                 goto error;
00463         if (!(bss->flags & WPA_BSS_QUAL_INVALID) &&
00464             !wpa_dbus_dict_append_int32(&iter_dict, "quality", bss->qual))
00465                 goto error;
00466         if (!(bss->flags & WPA_BSS_NOISE_INVALID) &&
00467             !wpa_dbus_dict_append_int32(&iter_dict, "noise", bss->noise))
00468                 goto error;
00469         if (!(bss->flags & WPA_BSS_LEVEL_INVALID) &&
00470             !wpa_dbus_dict_append_int32(&iter_dict, "level", bss->level))
00471                 goto error;
00472         if (!wpa_dbus_dict_append_int32(&iter_dict, "maxrate",
00473                                         wpa_bss_get_max_rate(bss) * 500000))
00474                 goto error;
00475 
00476         if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
00477                 goto error;
00478 
00479         return reply;
00480 
00481 error:
00482         if (reply)
00483                 dbus_message_unref(reply);
00484         return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
00485                                       "an internal error occurred returning "
00486                                       "BSSID properties.");
00487 }
00488 
00489 
00498 DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message,
00499                                            struct wpa_supplicant *wpa_s)
00500 {
00501         DBusMessage *reply = NULL;
00502         struct wpa_driver_capa capa;
00503         int res;
00504         DBusMessageIter iter, iter_dict;
00505         char **eap_methods;
00506         size_t num_items;
00507         dbus_bool_t strict = FALSE;
00508         DBusMessageIter iter_dict_entry, iter_dict_val, iter_array;
00509 
00510         if (!dbus_message_get_args(message, NULL,
00511                                    DBUS_TYPE_BOOLEAN, &strict,
00512                                    DBUS_TYPE_INVALID))
00513                 strict = FALSE;
00514 
00515         reply = dbus_message_new_method_return(message);
00516 
00517         dbus_message_iter_init_append(reply, &iter);
00518         if (!wpa_dbus_dict_open_write(&iter, &iter_dict))
00519                 goto error;
00520 
00521         /* EAP methods */
00522         eap_methods = eap_get_names_as_string_array(&num_items);
00523         if (eap_methods) {
00524                 dbus_bool_t success = FALSE;
00525                 size_t i = 0;
00526 
00527                 success = wpa_dbus_dict_append_string_array(
00528                         &iter_dict, "eap", (const char **) eap_methods,
00529                         num_items);
00530 
00531                 /* free returned method array */
00532                 while (eap_methods[i])
00533                         os_free(eap_methods[i++]);
00534                 os_free(eap_methods);
00535 
00536                 if (!success)
00537                         goto error;
00538         }
00539 
00540         res = wpa_drv_get_capa(wpa_s, &capa);
00541 
00542         /***** pairwise cipher */
00543         if (res < 0) {
00544                 if (!strict) {
00545                         const char *args[] = {"CCMP", "TKIP", "NONE"};
00546                         if (!wpa_dbus_dict_append_string_array(
00547                                     &iter_dict, "pairwise", args,
00548                                     sizeof(args) / sizeof(char*)))
00549                                 goto error;
00550                 }
00551         } else {
00552                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "pairwise",
00553                                                       &iter_dict_entry,
00554                                                       &iter_dict_val,
00555                                                       &iter_array))
00556                         goto error;
00557 
00558                 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
00559                         if (!wpa_dbus_dict_string_array_add_element(
00560                                     &iter_array, "CCMP"))
00561                                 goto error;
00562                 }
00563 
00564                 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
00565                         if (!wpa_dbus_dict_string_array_add_element(
00566                                     &iter_array, "TKIP"))
00567                                 goto error;
00568                 }
00569 
00570                 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
00571                         if (!wpa_dbus_dict_string_array_add_element(
00572                                     &iter_array, "NONE"))
00573                                 goto error;
00574                 }
00575 
00576                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
00577                                                     &iter_dict_entry,
00578                                                     &iter_dict_val,
00579                                                     &iter_array))
00580                         goto error;
00581         }
00582 
00583         /***** group cipher */
00584         if (res < 0) {
00585                 if (!strict) {
00586                         const char *args[] = {
00587                                 "CCMP", "TKIP", "WEP104", "WEP40"
00588                         };
00589                         if (!wpa_dbus_dict_append_string_array(
00590                                     &iter_dict, "group", args,
00591                                     sizeof(args) / sizeof(char*)))
00592                                 goto error;
00593                 }
00594         } else {
00595                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "group",
00596                                                       &iter_dict_entry,
00597                                                       &iter_dict_val,
00598                                                       &iter_array))
00599                         goto error;
00600 
00601                 if (capa.enc & WPA_DRIVER_CAPA_ENC_CCMP) {
00602                         if (!wpa_dbus_dict_string_array_add_element(
00603                                     &iter_array, "CCMP"))
00604                                 goto error;
00605                 }
00606 
00607                 if (capa.enc & WPA_DRIVER_CAPA_ENC_TKIP) {
00608                         if (!wpa_dbus_dict_string_array_add_element(
00609                                     &iter_array, "TKIP"))
00610                                 goto error;
00611                 }
00612 
00613                 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP104) {
00614                         if (!wpa_dbus_dict_string_array_add_element(
00615                                     &iter_array, "WEP104"))
00616                                 goto error;
00617                 }
00618 
00619                 if (capa.enc & WPA_DRIVER_CAPA_ENC_WEP40) {
00620                         if (!wpa_dbus_dict_string_array_add_element(
00621                                     &iter_array, "WEP40"))
00622                                 goto error;
00623                 }
00624 
00625                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
00626                                                     &iter_dict_entry,
00627                                                     &iter_dict_val,
00628                                                     &iter_array))
00629                         goto error;
00630         }
00631 
00632         /***** key management */
00633         if (res < 0) {
00634                 if (!strict) {
00635                         const char *args[] = {
00636                                 "WPA-PSK", "WPA-EAP", "IEEE8021X", "WPA-NONE",
00637                                 "NONE"
00638                         };
00639                         if (!wpa_dbus_dict_append_string_array(
00640                                     &iter_dict, "key_mgmt", args,
00641                                     sizeof(args) / sizeof(char*)))
00642                                 goto error;
00643                 }
00644         } else {
00645                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "key_mgmt",
00646                                                       &iter_dict_entry,
00647                                                       &iter_dict_val,
00648                                                       &iter_array))
00649                         goto error;
00650 
00651                 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
00652                                                             "NONE"))
00653                         goto error;
00654 
00655                 if (!wpa_dbus_dict_string_array_add_element(&iter_array,
00656                                                             "IEEE8021X"))
00657                         goto error;
00658 
00659                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
00660                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
00661                         if (!wpa_dbus_dict_string_array_add_element(
00662                                     &iter_array, "WPA-EAP"))
00663                                 goto error;
00664                 }
00665 
00666                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
00667                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
00668                         if (!wpa_dbus_dict_string_array_add_element(
00669                                     &iter_array, "WPA-PSK"))
00670                                 goto error;
00671                 }
00672 
00673                 if (capa.key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_WPA_NONE) {
00674                         if (!wpa_dbus_dict_string_array_add_element(
00675                                     &iter_array, "WPA-NONE"))
00676                                 goto error;
00677                 }
00678 
00679                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
00680                                                     &iter_dict_entry,
00681                                                     &iter_dict_val,
00682                                                     &iter_array))
00683                         goto error;
00684         }
00685 
00686         /***** WPA protocol */
00687         if (res < 0) {
00688                 if (!strict) {
00689                         const char *args[] = { "RSN", "WPA" };
00690                         if (!wpa_dbus_dict_append_string_array(
00691                                     &iter_dict, "proto", args,
00692                                     sizeof(args) / sizeof(char*)))
00693                                 goto error;
00694                 }
00695         } else {
00696                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "proto",
00697                                                       &iter_dict_entry,
00698                                                       &iter_dict_val,
00699                                                       &iter_array))
00700                         goto error;
00701 
00702                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA2 |
00703                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
00704                         if (!wpa_dbus_dict_string_array_add_element(
00705                                     &iter_array, "RSN"))
00706                                 goto error;
00707                 }
00708 
00709                 if (capa.key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA |
00710                                      WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK)) {
00711                         if (!wpa_dbus_dict_string_array_add_element(
00712                                     &iter_array, "WPA"))
00713                                 goto error;
00714                 }
00715 
00716                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
00717                                                     &iter_dict_entry,
00718                                                     &iter_dict_val,
00719                                                     &iter_array))
00720                         goto error;
00721         }
00722 
00723         /***** auth alg */
00724         if (res < 0) {
00725                 if (!strict) {
00726                         const char *args[] = { "OPEN", "SHARED", "LEAP" };
00727                         if (!wpa_dbus_dict_append_string_array(
00728                                     &iter_dict, "auth_alg", args,
00729                                     sizeof(args) / sizeof(char*)))
00730                                 goto error;
00731                 }
00732         } else {
00733                 if (!wpa_dbus_dict_begin_string_array(&iter_dict, "auth_alg",
00734                                                       &iter_dict_entry,
00735                                                       &iter_dict_val,
00736                                                       &iter_array))
00737                         goto error;
00738 
00739                 if (capa.auth & (WPA_DRIVER_AUTH_OPEN)) {
00740                         if (!wpa_dbus_dict_string_array_add_element(
00741                                     &iter_array, "OPEN"))
00742                                 goto error;
00743                 }
00744 
00745                 if (capa.auth & (WPA_DRIVER_AUTH_SHARED)) {
00746                         if (!wpa_dbus_dict_string_array_add_element(
00747                                     &iter_array, "SHARED"))
00748                                 goto error;
00749                 }
00750 
00751                 if (capa.auth & (WPA_DRIVER_AUTH_LEAP)) {
00752                         if (!wpa_dbus_dict_string_array_add_element(
00753                                     &iter_array, "LEAP"))
00754                                 goto error;
00755                 }
00756 
00757                 if (!wpa_dbus_dict_end_string_array(&iter_dict,
00758                                                     &iter_dict_entry,
00759                                                     &iter_dict_val,
00760                                                     &iter_array))
00761                         goto error;
00762         }
00763 
00764         if (!wpa_dbus_dict_close_write(&iter, &iter_dict))
00765                 goto error;
00766 
00767         return reply;
00768 
00769 error:
00770         if (reply)
00771                 dbus_message_unref(reply);
00772         return dbus_message_new_error(message, WPAS_ERROR_INTERNAL_ERROR,
00773                                       "an internal error occurred returning "
00774                                       "interface capabilities.");
00775 }
00776 
00777 
00786 DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message,
00787                                           struct wpa_supplicant *wpa_s)
00788 {
00789         DBusMessage *reply = NULL;
00790         struct wpa_ssid *ssid;
00791         char path_buf[WPAS_DBUS_OBJECT_PATH_MAX], *path = path_buf;
00792 
00793         ssid = wpa_config_add_network(wpa_s->conf);
00794         if (ssid == NULL) {
00795                 reply = dbus_message_new_error(message,
00796                                                WPAS_ERROR_ADD_NETWORK_ERROR,
00797                                                "wpa_supplicant could not add "
00798                                                "a network on this interface.");
00799                 goto out;
00800         }
00801         wpas_notify_network_added(wpa_s, ssid);
00802         ssid->disabled = 1;
00803         wpa_config_set_network_defaults(ssid);
00804 
00805         /* Construct the object path for this network. */
00806         os_snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX,
00807                     "%s/" WPAS_DBUS_NETWORKS_PART "/%d",
00808                     wpa_s->dbus_path, ssid->id);
00809 
00810         reply = dbus_message_new_method_return(message);
00811         dbus_message_append_args(reply, DBUS_TYPE_OBJECT_PATH,
00812                                  &path, DBUS_TYPE_INVALID);
00813 
00814 out:
00815         return reply;
00816 }
00817 
00818 
00828 DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message,
00829                                              struct wpa_supplicant *wpa_s)
00830 {
00831         DBusMessage *reply = NULL;
00832         const char *op;
00833         char *iface = NULL, *net_id = NULL;
00834         int id;
00835         struct wpa_ssid *ssid;
00836 
00837         if (!dbus_message_get_args(message, NULL,
00838                                    DBUS_TYPE_OBJECT_PATH, &op,
00839                                    DBUS_TYPE_INVALID)) {
00840                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
00841                 goto out;
00842         }
00843 
00844         /* Extract the network ID */
00845         iface = wpas_dbus_decompose_object_path(op, &net_id, NULL);
00846         if (iface == NULL) {
00847                 reply = wpas_dbus_new_invalid_network_error(message);
00848                 goto out;
00849         }
00850 
00851         /* Ensure the network is actually a child of this interface */
00852         if (os_strcmp(iface, wpa_s->dbus_path) != 0) {
00853                 reply = wpas_dbus_new_invalid_network_error(message);
00854                 goto out;
00855         }
00856 
00857         id = strtoul(net_id, NULL, 10);
00858         ssid = wpa_config_get_network(wpa_s->conf, id);
00859         if (ssid == NULL) {
00860                 reply = wpas_dbus_new_invalid_network_error(message);
00861                 goto out;
00862         }
00863 
00864         wpas_notify_network_removed(wpa_s, ssid);
00865 
00866         if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
00867                 reply = dbus_message_new_error(message,
00868                                                WPAS_ERROR_REMOVE_NETWORK_ERROR,
00869                                                "error removing the specified "
00870                                                "on this interface.");
00871                 goto out;
00872         }
00873 
00874         if (ssid == wpa_s->current_ssid)
00875                 wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
00876         reply = wpas_dbus_new_success_reply(message);
00877 
00878 out:
00879         os_free(iface);
00880         os_free(net_id);
00881         return reply;
00882 }
00883 
00884 
00885 static const char *dont_quote[] = {
00886         "key_mgmt", "proto", "pairwise", "auth_alg", "group", "eap",
00887         "opensc_engine_path", "pkcs11_engine_path", "pkcs11_module_path",
00888         "bssid", NULL
00889 };
00890 
00891 
00892 static dbus_bool_t should_quote_opt(const char *key)
00893 {
00894         int i = 0;
00895         while (dont_quote[i] != NULL) {
00896                 if (strcmp(key, dont_quote[i]) == 0)
00897                         return FALSE;
00898                 i++;
00899         }
00900         return TRUE;
00901 }
00902 
00903 
00914 DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message,
00915                                           struct wpa_supplicant *wpa_s,
00916                                           struct wpa_ssid *ssid)
00917 {
00918         DBusMessage *reply = NULL;
00919         struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
00920         DBusMessageIter iter, iter_dict;
00921 
00922         dbus_message_iter_init(message, &iter);
00923 
00924         if (!wpa_dbus_dict_open_read(&iter, &iter_dict)) {
00925                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
00926                 goto out;
00927         }
00928 
00929         while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
00930                 char *value = NULL;
00931                 size_t size = 50;
00932                 int ret;
00933 
00934                 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
00935                         reply = wpas_dbus_new_invalid_opts_error(message,
00936                                                                  NULL);
00937                         goto out;
00938                 }
00939 
00940                 /* Type conversions, since wpa_supplicant wants strings */
00941                 if (entry.type == DBUS_TYPE_ARRAY &&
00942                     entry.array_type == DBUS_TYPE_BYTE) {
00943                         if (entry.array_len <= 0)
00944                                 goto error;
00945 
00946                         size = entry.array_len * 2 + 1;
00947                         value = os_zalloc(size);
00948                         if (value == NULL)
00949                                 goto error;
00950                         ret = wpa_snprintf_hex(value, size,
00951                                                (u8 *) entry.bytearray_value,
00952                                                entry.array_len);
00953                         if (ret <= 0)
00954                                 goto error;
00955                 } else if (entry.type == DBUS_TYPE_STRING) {
00956                         if (should_quote_opt(entry.key)) {
00957                                 size = os_strlen(entry.str_value);
00958                                 /* Zero-length option check */
00959                                 if (size <= 0)
00960                                         goto error;
00961                                 size += 3;  /* For quotes and terminator */
00962                                 value = os_zalloc(size);
00963                                 if (value == NULL)
00964                                         goto error;
00965                                 ret = os_snprintf(value, size, "\"%s\"",
00966                                                   entry.str_value);
00967                                 if (ret < 0 || (size_t) ret != (size - 1))
00968                                         goto error;
00969                         } else {
00970                                 value = os_strdup(entry.str_value);
00971                                 if (value == NULL)
00972                                         goto error;
00973                         }
00974                 } else if (entry.type == DBUS_TYPE_UINT32) {
00975                         value = os_zalloc(size);
00976                         if (value == NULL)
00977                                 goto error;
00978                         ret = os_snprintf(value, size, "%u",
00979                                           entry.uint32_value);
00980                         if (ret <= 0)
00981                                 goto error;
00982                 } else if (entry.type == DBUS_TYPE_INT32) {
00983                         value = os_zalloc(size);
00984                         if (value == NULL)
00985                                 goto error;
00986                         ret = os_snprintf(value, size, "%d",
00987                                           entry.int32_value);
00988                         if (ret <= 0)
00989                                 goto error;
00990                 } else
00991                         goto error;
00992 
00993                 if (wpa_config_set(ssid, entry.key, value, 0) < 0)
00994                         goto error;
00995 
00996                 if ((os_strcmp(entry.key, "psk") == 0 &&
00997                      value[0] == '"' && ssid->ssid_len) ||
00998                     (os_strcmp(entry.key, "ssid") == 0 && ssid->passphrase))
00999                         wpa_config_update_psk(ssid);
01000                 else if (os_strcmp(entry.key, "priority") == 0)
01001                         wpa_config_update_prio_list(wpa_s->conf);
01002 
01003                 os_free(value);
01004                 wpa_dbus_dict_entry_clear(&entry);
01005                 continue;
01006 
01007         error:
01008                 os_free(value);
01009                 reply = wpas_dbus_new_invalid_opts_error(message, entry.key);
01010                 wpa_dbus_dict_entry_clear(&entry);
01011                 break;
01012         }
01013 
01014         if (!reply)
01015                 reply = wpas_dbus_new_success_reply(message);
01016 
01017 out:
01018         return reply;
01019 }
01020 
01021 
01032 DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message,
01033                                              struct wpa_supplicant *wpa_s,
01034                                              struct wpa_ssid *ssid)
01035 {
01036         wpa_supplicant_enable_network(wpa_s, ssid);
01037         return wpas_dbus_new_success_reply(message);
01038 }
01039 
01040 
01051 DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message,
01052                                               struct wpa_supplicant *wpa_s,
01053                                               struct wpa_ssid *ssid)
01054 {
01055         wpa_supplicant_disable_network(wpa_s, ssid);
01056         return wpas_dbus_new_success_reply(message);
01057 }
01058 
01059 
01069 DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message,
01070                                              struct wpa_supplicant *wpa_s)
01071 {
01072         DBusMessage *reply = NULL;
01073         const char *op;
01074         struct wpa_ssid *ssid;
01075         char *iface_obj_path = NULL;
01076         char *network = NULL;
01077 
01078         if (os_strlen(dbus_message_get_signature(message)) == 0) {
01079                 /* Any network */
01080                 ssid = NULL;
01081         } else {
01082                 int nid;
01083 
01084                 if (!dbus_message_get_args(message, NULL,
01085                                            DBUS_TYPE_OBJECT_PATH, &op,
01086                                            DBUS_TYPE_INVALID)) {
01087                         reply = wpas_dbus_new_invalid_opts_error(message,
01088                                                                  NULL);
01089                         goto out;
01090                 }
01091 
01092                 /* Extract the network number */
01093                 iface_obj_path = wpas_dbus_decompose_object_path(op,
01094                                                                  &network,
01095                                                                  NULL);
01096                 if (iface_obj_path == NULL) {
01097                         reply = wpas_dbus_new_invalid_iface_error(message);
01098                         goto out;
01099                 }
01100                 /* Ensure the object path really points to this interface */
01101                 if (os_strcmp(iface_obj_path, wpa_s->dbus_path) != 0) {
01102                         reply = wpas_dbus_new_invalid_network_error(message);
01103                         goto out;
01104                 }
01105 
01106                 nid = strtoul(network, NULL, 10);
01107                 if (errno == EINVAL) {
01108                         reply = wpas_dbus_new_invalid_network_error(message);
01109                         goto out;
01110                 }
01111 
01112                 ssid = wpa_config_get_network(wpa_s->conf, nid);
01113                 if (ssid == NULL) {
01114                         reply = wpas_dbus_new_invalid_network_error(message);
01115                         goto out;
01116                 }
01117         }
01118 
01119         /* Finally, associate with the network */
01120         wpa_supplicant_select_network(wpa_s, ssid);
01121 
01122         reply = wpas_dbus_new_success_reply(message);
01123 
01124 out:
01125         os_free(iface_obj_path);
01126         os_free(network);
01127         return reply;
01128 }
01129 
01130 
01140 DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message,
01141                                          struct wpa_supplicant *wpa_s)
01142 {
01143         wpa_s->disconnected = 1;
01144         wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);
01145 
01146         return wpas_dbus_new_success_reply(message);
01147 }
01148 
01149 
01159 DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message,
01160                                           struct wpa_supplicant *wpa_s)
01161 {
01162         DBusMessage *reply = NULL;
01163         dbus_uint32_t ap_scan = 1;
01164 
01165         if (!dbus_message_get_args(message, NULL, DBUS_TYPE_UINT32, &ap_scan,
01166                                    DBUS_TYPE_INVALID)) {
01167                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
01168                 goto out;
01169         }
01170 
01171         if (wpa_supplicant_set_ap_scan(wpa_s, ap_scan)) {
01172                 reply = wpas_dbus_new_invalid_opts_error(message, NULL);
01173                 goto out;
01174         }
01175 
01176         reply = wpas_dbus_new_success_reply(message);
01177 
01178 out:
01179         return reply;
01180 }
01181 
01182 
01192 DBusMessage * wpas_dbus_iface_set_smartcard_modules(
01193         DBusMessage *message, struct wpa_supplicant *wpa_s)
01194 {
01195         DBusMessageIter iter, iter_dict;
01196         char *opensc_engine_path = NULL;
01197         char *pkcs11_engine_path = NULL;
01198         char *pkcs11_module_path = NULL;
01199         struct wpa_dbus_dict_entry entry;
01200 
01201         if (!dbus_message_iter_init(message, &iter))
01202                 goto error;
01203 
01204         if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
01205                 goto error;
01206 
01207         while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
01208                 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
01209                         goto error;
01210                 if (!strcmp(entry.key, "opensc_engine_path") &&
01211                     (entry.type == DBUS_TYPE_STRING)) {
01212                         opensc_engine_path = os_strdup(entry.str_value);
01213                         if (opensc_engine_path == NULL)
01214                                 goto error;
01215                 } else if (!strcmp(entry.key, "pkcs11_engine_path") &&
01216                            (entry.type == DBUS_TYPE_STRING)) {
01217                         pkcs11_engine_path = os_strdup(entry.str_value);
01218                         if (pkcs11_engine_path == NULL)
01219                                 goto error;
01220                 } else if (!strcmp(entry.key, "pkcs11_module_path") &&
01221                                  (entry.type == DBUS_TYPE_STRING)) {
01222                         pkcs11_module_path = os_strdup(entry.str_value);
01223                         if (pkcs11_module_path == NULL)
01224                                 goto error;
01225                 } else {
01226                         wpa_dbus_dict_entry_clear(&entry);
01227                         goto error;
01228                 }
01229                 wpa_dbus_dict_entry_clear(&entry);
01230         }
01231 
01232         os_free(wpa_s->conf->opensc_engine_path);
01233         wpa_s->conf->opensc_engine_path = opensc_engine_path;
01234         os_free(wpa_s->conf->pkcs11_engine_path);
01235         wpa_s->conf->pkcs11_engine_path = pkcs11_engine_path;
01236         os_free(wpa_s->conf->pkcs11_module_path);
01237         wpa_s->conf->pkcs11_module_path = pkcs11_module_path;
01238 
01239         wpa_sm_set_eapol(wpa_s->wpa, NULL);
01240         eapol_sm_deinit(wpa_s->eapol);
01241         wpa_s->eapol = NULL;
01242         wpa_supplicant_init_eapol(wpa_s);
01243         wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
01244 
01245         return wpas_dbus_new_success_reply(message);
01246 
01247 error:
01248         os_free(opensc_engine_path);
01249         os_free(pkcs11_engine_path);
01250         os_free(pkcs11_module_path);
01251         return wpas_dbus_new_invalid_opts_error(message, NULL);
01252 }
01253 
01254 
01264 DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
01265                                         struct wpa_supplicant *wpa_s)
01266 {
01267         DBusMessage *reply = NULL;
01268         const char *str_state;
01269 
01270         reply = dbus_message_new_method_return(message);
01271         if (reply != NULL) {
01272                 str_state = wpa_supplicant_state_txt(wpa_s->wpa_state);
01273                 dbus_message_append_args(reply, DBUS_TYPE_STRING, &str_state,
01274                                          DBUS_TYPE_INVALID);
01275         }
01276 
01277         return reply;
01278 }
01279 
01280 
01289 DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
01290                                            struct wpa_supplicant *wpa_s)
01291 {
01292         DBusMessage *reply = NULL;
01293         dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
01294 
01295         reply = dbus_message_new_method_return(message);
01296         if (reply != NULL) {
01297                 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
01298                                          DBUS_TYPE_INVALID);
01299         } else {
01300                 wpa_printf(MSG_ERROR, "dbus: Not enough memory to return "
01301                            "scanning state");
01302         }
01303 
01304         return reply;
01305 }
01306 
01307 
01317 DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
01318                                         struct wpa_supplicant *wpa_s)
01319 {
01320         DBusMessage *reply = NULL;
01321         struct wpa_dbus_dict_entry entry = { .type = DBUS_TYPE_STRING };
01322         DBusMessageIter iter, iter_dict;
01323 
01324         dbus_message_iter_init(message, &iter);
01325 
01326         if (!wpa_dbus_dict_open_read(&iter, &iter_dict))
01327                 return wpas_dbus_new_invalid_opts_error(message, NULL);
01328 
01329         while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
01330                 struct wpa_config_blob *blob;
01331 
01332                 if (!wpa_dbus_dict_get_entry(&iter_dict, &entry)) {
01333                         reply = wpas_dbus_new_invalid_opts_error(message,
01334                                                                  NULL);
01335                         break;
01336                 }
01337 
01338                 if (entry.type != DBUS_TYPE_ARRAY ||
01339                     entry.array_type != DBUS_TYPE_BYTE) {
01340                         reply = wpas_dbus_new_invalid_opts_error(
01341                                 message, "Byte array expected.");
01342                         break;
01343                 }
01344 
01345                 if ((entry.array_len <= 0) || (entry.array_len > 65536) ||
01346                     !strlen(entry.key)) {
01347                         reply = wpas_dbus_new_invalid_opts_error(
01348                                 message, "Invalid array size.");
01349                         break;
01350                 }
01351 
01352                 blob = os_zalloc(sizeof(*blob));
01353                 if (blob == NULL) {
01354                         reply = dbus_message_new_error(
01355                                 message, WPAS_ERROR_ADD_ERROR,
01356                                 "Not enough memory to add blob.");
01357                         break;
01358                 }
01359                 blob->data = os_zalloc(entry.array_len);
01360                 if (blob->data == NULL) {
01361                         reply = dbus_message_new_error(
01362                                 message, WPAS_ERROR_ADD_ERROR,
01363                                 "Not enough memory to add blob data.");
01364                         os_free(blob);
01365                         break;
01366                 }
01367 
01368                 blob->name = os_strdup(entry.key);
01369                 blob->len = entry.array_len;
01370                 os_memcpy(blob->data, (u8 *) entry.bytearray_value,
01371                                 entry.array_len);
01372                 if (blob->name == NULL || blob->data == NULL) {
01373                         wpa_config_free_blob(blob);
01374                         reply = dbus_message_new_error(
01375                                 message, WPAS_ERROR_ADD_ERROR,
01376                                 "Error adding blob.");
01377                         break;
01378                 }
01379 
01380                 /* Success */
01381                 if (!wpa_config_remove_blob(wpa_s->conf, blob->name))
01382                         wpas_notify_blob_removed(wpa_s, blob->name);
01383                 wpa_config_set_blob(wpa_s->conf, blob);
01384                 wpas_notify_blob_added(wpa_s, blob->name);
01385 
01386                 wpa_dbus_dict_entry_clear(&entry);
01387         }
01388         wpa_dbus_dict_entry_clear(&entry);
01389 
01390         return reply ? reply : wpas_dbus_new_success_reply(message);
01391 }
01392 
01393 
01403 DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message,
01404                                            struct wpa_supplicant *wpa_s)
01405 {
01406         DBusMessageIter iter, array;
01407         char *err_msg = NULL;
01408 
01409         dbus_message_iter_init(message, &iter);
01410 
01411         if ((dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) ||
01412             (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_STRING))
01413                 return wpas_dbus_new_invalid_opts_error(message, NULL);
01414 
01415         dbus_message_iter_recurse(&iter, &array);
01416         while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRING) {
01417                 const char *name;
01418 
01419                 dbus_message_iter_get_basic(&array, &name);
01420                 if (!os_strlen(name))
01421                         err_msg = "Invalid blob name.";
01422 
01423                 if (wpa_config_remove_blob(wpa_s->conf, name) != 0)
01424                         err_msg = "Error removing blob.";
01425                 else
01426                         wpas_notify_blob_removed(wpa_s, name);
01427                 dbus_message_iter_next(&array);
01428         }
01429 
01430         if (err_msg)
01431                 return dbus_message_new_error(message, WPAS_ERROR_REMOVE_ERROR,
01432                                               err_msg);
01433 
01434         return wpas_dbus_new_success_reply(message);
01435 }


wpa_supplicant
Author(s): Package maintained by Blaise Gassend
autogenerated on Thu Apr 24 2014 15:34:34