$search
00001 /* 00002 * WPA Supplicant / dbus-based control interface (WPS) 00003 * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 00004 * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License version 2 as 00008 * published by the Free Software Foundation. 00009 * 00010 * Alternatively, this software may be distributed under the terms of BSD 00011 * license. 00012 * 00013 * See README and COPYING for more details. 00014 */ 00015 00016 #include "includes.h" 00017 00018 #include "common.h" 00019 #include "../config.h" 00020 #include "../wpa_supplicant_i.h" 00021 #include "../wps_supplicant.h" 00022 #include "dbus_new_helpers.h" 00023 #include "dbus_new.h" 00024 #include "dbus_new_handlers.h" 00025 #include "dbus_dict_helpers.h" 00026 00027 00028 struct wps_start_params { 00029 int role; /* 0 - not set, 1 - enrollee, 2 - registrar */ 00030 int type; /* 0 - not set, 1 - pin, 2 - pbc */ 00031 u8 *bssid; 00032 char *pin; 00033 }; 00034 00035 00036 static int wpas_dbus_handler_wps_role(DBusMessage *message, 00037 DBusMessageIter *entry_iter, 00038 struct wps_start_params *params, 00039 DBusMessage **reply) 00040 { 00041 DBusMessageIter variant_iter; 00042 char *val; 00043 00044 dbus_message_iter_recurse(entry_iter, &variant_iter); 00045 if (dbus_message_iter_get_arg_type(&variant_iter) != 00046 DBUS_TYPE_STRING) { 00047 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Role type, " 00048 "string required"); 00049 *reply = wpas_dbus_error_invalid_args(message, 00050 "Role must be a string"); 00051 return -1; 00052 } 00053 dbus_message_iter_get_basic(&variant_iter, &val); 00054 if (os_strcmp(val, "enrollee") == 0) 00055 params->role = 1; 00056 else if (os_strcmp(val, "registrar") == 0) 00057 params->role = 2; 00058 else { 00059 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Uknown role %s", val); 00060 *reply = wpas_dbus_error_invalid_args(message, val); 00061 return -1; 00062 } 00063 return 0; 00064 } 00065 00066 00067 static int wpas_dbus_handler_wps_type(DBusMessage *message, 00068 DBusMessageIter *entry_iter, 00069 struct wps_start_params *params, 00070 DBusMessage **reply) 00071 { 00072 DBusMessageIter variant_iter; 00073 char *val; 00074 00075 dbus_message_iter_recurse(entry_iter, &variant_iter); 00076 if (dbus_message_iter_get_arg_type(&variant_iter) != 00077 DBUS_TYPE_STRING) { 00078 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Type type, " 00079 "string required"); 00080 *reply = wpas_dbus_error_invalid_args(message, 00081 "Type must be a string"); 00082 return -1; 00083 } 00084 dbus_message_iter_get_basic(&variant_iter, &val); 00085 if (os_strcmp(val, "pin") == 0) 00086 params->type = 1; 00087 else if (os_strcmp(val, "pbc") == 0) 00088 params->type = 2; 00089 else { 00090 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Unknown type %s", 00091 val); 00092 *reply = wpas_dbus_error_invalid_args(message, val); 00093 return -1; 00094 } 00095 return 0; 00096 } 00097 00098 00099 static int wpas_dbus_handler_wps_bssid(DBusMessage *message, 00100 DBusMessageIter *entry_iter, 00101 struct wps_start_params *params, 00102 DBusMessage **reply) 00103 { 00104 DBusMessageIter variant_iter, array_iter; 00105 int len; 00106 00107 dbus_message_iter_recurse(entry_iter, &variant_iter); 00108 if (dbus_message_iter_get_arg_type(&variant_iter) != DBUS_TYPE_ARRAY || 00109 dbus_message_iter_get_element_type(&variant_iter) != 00110 DBUS_TYPE_ARRAY) { 00111 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Bssid type, " 00112 "byte array required"); 00113 *reply = wpas_dbus_error_invalid_args( 00114 message, "Bssid must be a byte array"); 00115 return -1; 00116 } 00117 dbus_message_iter_recurse(&variant_iter, &array_iter); 00118 dbus_message_iter_get_fixed_array(&array_iter, ¶ms->bssid, &len); 00119 if (len != ETH_ALEN) { 00120 wpa_printf(MSG_DEBUG, "dbus: WPS.Stsrt - Wrong Bssid length " 00121 "%d", len); 00122 *reply = wpas_dbus_error_invalid_args(message, 00123 "Bssid is wrong length"); 00124 return -1; 00125 } 00126 return 0; 00127 } 00128 00129 00130 static int wpas_dbus_handler_wps_pin(DBusMessage *message, 00131 DBusMessageIter *entry_iter, 00132 struct wps_start_params *params, 00133 DBusMessage **reply) 00134 { 00135 DBusMessageIter variant_iter; 00136 00137 dbus_message_iter_recurse(entry_iter, &variant_iter); 00138 if (dbus_message_iter_get_arg_type(&variant_iter) != 00139 DBUS_TYPE_STRING) { 00140 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Wrong Pin type, " 00141 "string required"); 00142 *reply = wpas_dbus_error_invalid_args(message, 00143 "Pin must be a string"); 00144 return -1; 00145 } 00146 dbus_message_iter_get_basic(&variant_iter, ¶ms->pin); 00147 return 0; 00148 } 00149 00150 00151 static int wpas_dbus_handler_wps_start_entry(DBusMessage *message, char *key, 00152 DBusMessageIter *entry_iter, 00153 struct wps_start_params *params, 00154 DBusMessage **reply) 00155 { 00156 if (os_strcmp(key, "Role") == 0) 00157 return wpas_dbus_handler_wps_role(message, entry_iter, 00158 params, reply); 00159 else if (os_strcmp(key, "Type") == 0) 00160 return wpas_dbus_handler_wps_type(message, entry_iter, 00161 params, reply); 00162 else if (os_strcmp(key, "Bssid") == 0) 00163 return wpas_dbus_handler_wps_bssid(message, entry_iter, 00164 params, reply); 00165 else if (os_strcmp(key, "Pin") == 0) 00166 return wpas_dbus_handler_wps_pin(message, entry_iter, 00167 params, reply); 00168 00169 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - unknown key %s", key); 00170 *reply = wpas_dbus_error_invalid_args(message, key); 00171 return -1; 00172 } 00173 00174 00186 DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, 00187 struct wpa_supplicant *wpa_s) 00188 { 00189 DBusMessage *reply = NULL; 00190 DBusMessageIter iter, dict_iter, entry_iter; 00191 struct wps_start_params params; 00192 char *key; 00193 char npin[9] = { '\0' }; 00194 int ret; 00195 00196 os_memset(¶ms, 0, sizeof(params)); 00197 dbus_message_iter_init(message, &iter); 00198 00199 dbus_message_iter_recurse(&iter, &dict_iter); 00200 while (dbus_message_iter_get_arg_type(&dict_iter) == 00201 DBUS_TYPE_DICT_ENTRY) { 00202 dbus_message_iter_recurse(&dict_iter, &entry_iter); 00203 00204 dbus_message_iter_get_basic(&entry_iter, &key); 00205 dbus_message_iter_next(&entry_iter); 00206 00207 if (wpas_dbus_handler_wps_start_entry(message, key, 00208 &entry_iter, 00209 ¶ms, &reply)) 00210 return reply; 00211 00212 dbus_message_iter_next(&dict_iter); 00213 } 00214 00215 if (params.role == 0) { 00216 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified"); 00217 return wpas_dbus_error_invalid_args(message, 00218 "Role not specified"); 00219 } else if (params.role == 1 && params.type == 0) { 00220 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified"); 00221 return wpas_dbus_error_invalid_args(message, 00222 "Type not specified"); 00223 } else if (params.role == 2 && params.pin == NULL) { 00224 wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for " 00225 "registrar role"); 00226 return wpas_dbus_error_invalid_args( 00227 message, "Pin required for registrar role."); 00228 } 00229 00230 if (params.role == 2) 00231 ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin, 00232 NULL); 00233 else if (params.type == 1) { 00234 ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin); 00235 if (ret > 0) 00236 os_snprintf(npin, sizeof(npin), "%08d", ret); 00237 } else 00238 ret = wpas_wps_start_pbc(wpa_s, params.bssid); 00239 00240 if (ret < 0) { 00241 wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in " 00242 "role %s and key %s", 00243 (params.role == 1 ? "enrollee" : "registrar"), 00244 (params.type == 0 ? "" : 00245 (params.type == 1 ? "pin" : "pbc"))); 00246 return wpas_dbus_error_unknown_error(message, 00247 "WPS start failed"); 00248 } 00249 00250 reply = dbus_message_new_method_return(message); 00251 if (!reply) { 00252 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, 00253 NULL); 00254 } 00255 00256 dbus_message_iter_init_append(reply, &iter); 00257 if (!wpa_dbus_dict_open_write(&iter, &dict_iter)) { 00258 dbus_message_unref(reply); 00259 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, 00260 NULL); 00261 } 00262 00263 if (os_strlen(npin) > 0) { 00264 if (!wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) { 00265 dbus_message_unref(reply); 00266 return dbus_message_new_error(message, 00267 DBUS_ERROR_NO_MEMORY, 00268 NULL); 00269 } 00270 } 00271 00272 if (!wpa_dbus_dict_close_write(&iter, &dict_iter)) { 00273 dbus_message_unref(reply); 00274 return dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, 00275 NULL); 00276 } 00277 00278 return reply; 00279 } 00280 00281 00292 DBusMessage * wpas_dbus_getter_process_credentials( 00293 DBusMessage *message, struct wpa_supplicant *wpa_s) 00294 { 00295 dbus_bool_t process = (wpa_s->conf->wps_cred_processing != 1); 00296 return wpas_dbus_simple_property_getter(message, DBUS_TYPE_BOOLEAN, 00297 &process); 00298 } 00299 00300 00310 DBusMessage * wpas_dbus_setter_process_credentials( 00311 DBusMessage *message, struct wpa_supplicant *wpa_s) 00312 { 00313 DBusMessage *reply = NULL; 00314 dbus_bool_t process_credentials, old_pc; 00315 00316 reply = wpas_dbus_simple_property_setter(message, DBUS_TYPE_BOOLEAN, 00317 &process_credentials); 00318 if (reply) 00319 return reply; 00320 00321 old_pc = (wpa_s->conf->wps_cred_processing != 1); 00322 wpa_s->conf->wps_cred_processing = (process_credentials ? 2 : 1); 00323 00324 if ((wpa_s->conf->wps_cred_processing != 1) != old_pc) 00325 wpa_dbus_mark_property_changed(wpa_s->global->dbus, 00326 wpa_s->dbus_new_path, 00327 WPAS_DBUS_NEW_IFACE_WPS, 00328 "ProcessCredentials"); 00329 00330 return NULL; 00331 }