/** * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: A dbus message containing a UINT32 indicating success (1) or * failure (0) * * Handler function for "wpsPin" method call */ DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; char *arg_bssid; char *pin = NULL; u8 bssid[ETH_ALEN], *_bssid = NULL; int ret = 0; if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid, DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID)) return wpas_dbus_new_invalid_opts_error(message, NULL); if (!os_strcmp(arg_bssid, "any")) _bssid = NULL; else if (!hwaddr_aton(arg_bssid, bssid)) _bssid = bssid; else { return wpas_dbus_new_invalid_opts_error(message, "Invalid BSSID"); } if (os_strlen(pin) > 0) ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0, DEV_PW_DEFAULT); else ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0, DEV_PW_DEFAULT); if (ret < 0) { return dbus_message_new_error(message, WPAS_ERROR_WPS_PIN_ERROR, "Could not init PIN"); } reply = dbus_message_new_method_return(message); if (reply == NULL) return NULL; if (ret == 0) { dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID); } else { char npin[9]; os_snprintf(npin, sizeof(npin), "%08d", ret); dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin, DBUS_TYPE_INVALID); } return reply; }
static int wpa_supplicant_ctrl_iface_wps_pin(struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { u8 bssid[ETH_ALEN], *_bssid = bssid; char *pin; int ret; pin = os_strchr(cmd, ' '); if (pin) *pin++ = '\0'; if (os_strcmp(cmd, "any") == 0) _bssid = NULL; else if (hwaddr_aton(cmd, bssid)) { wpa_printf(MSG_DEBUG, "CTRL_IFACE WPS_PIN: invalid BSSID '%s'", cmd); return -1; } if (pin) { ret = wpas_wps_start_pin(wpa_s, _bssid, pin); if (ret < 0) return -1; ret = os_snprintf(buf, buflen, "%s", pin); if (ret < 0 || (size_t) ret >= buflen) return -1; return ret; } ret = wpas_wps_start_pin(wpa_s, _bssid, NULL); if (ret < 0) return -1; /* Return the generated PIN */ ret = os_snprintf(buf, buflen, "%08d", ret); if (ret < 0 || (size_t) ret >= buflen) return -1; return ret; }
int wpas_wps_start_oob(struct wpa_supplicant *wpa_s, char *device_type, char *path, char *method, char *name) { struct wps_context *wps = wpa_s->wps; struct oob_device_data *oob_dev; oob_dev = wps_get_oob_device(device_type); if (oob_dev == NULL) return -1; oob_dev->device_path = path; oob_dev->device_name = name; wps->oob_conf.oob_method = wps_get_oob_method(method); if (wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E) { /* * Use pre-configured DH keys in order to be able to write the * key hash into the OOB file. */ wpabuf_free(wps->dh_pubkey); wpabuf_free(wps->dh_privkey); wps->dh_privkey = NULL; wps->dh_pubkey = NULL; dh5_free(wps->dh_ctx); wps->dh_ctx = dh5_init(&wps->dh_privkey, &wps->dh_pubkey); wps->dh_pubkey = wpabuf_zeropad(wps->dh_pubkey, 192); if (wps->dh_ctx == NULL || wps->dh_pubkey == NULL) { wpa_printf(MSG_ERROR, "WPS: Failed to initialize " "Diffie-Hellman handshake"); return -1; } } if (wps->oob_conf.oob_method == OOB_METHOD_CRED) wpas_clear_wps(wpa_s); if (wps_process_oob(wps, oob_dev, 0) < 0) return -1; if ((wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_E || wps->oob_conf.oob_method == OOB_METHOD_DEV_PWD_R) && wpas_wps_start_pin(wpa_s, NULL, wpabuf_head(wps->oob_conf.dev_password), 0, DEV_PW_DEFAULT) < 0) return -1; return 0; }
/** * wpas_dbus_handler_wps_start - Start WPS configuration * @message: Pointer to incoming dbus message * @wpa_s: %wpa_supplicant data structure * Returns: DBus message dictionary on success or DBus error on failure * * Handler for "Start" method call. DBus dictionary argument contains * information about role (enrollee or registrar), authorization method * (pin or push button) and optionally pin and bssid. Returned message * has a dictionary argument which may contain newly generated pin (optional). */ DBusMessage * wpas_dbus_handler_wps_start(DBusMessage *message, struct wpa_supplicant *wpa_s) { DBusMessage *reply = NULL; DBusMessageIter iter, dict_iter, entry_iter; struct wps_start_params params; char *key; char npin[9] = { '\0' }; int ret; os_memset(¶ms, 0, sizeof(params)); dbus_message_iter_init(message, &iter); dbus_message_iter_recurse(&iter, &dict_iter); while (dbus_message_iter_get_arg_type(&dict_iter) == DBUS_TYPE_DICT_ENTRY) { dbus_message_iter_recurse(&dict_iter, &entry_iter); dbus_message_iter_get_basic(&entry_iter, &key); dbus_message_iter_next(&entry_iter); if (wpas_dbus_handler_wps_start_entry(message, key, &entry_iter, ¶ms, &reply)) return reply; dbus_message_iter_next(&dict_iter); } #ifdef CONFIG_AP if (wpa_s->ap_iface && params.type == 1) { if (params.pin == NULL) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for registrar role"); return wpas_dbus_error_invalid_args( message, "Pin required for registrar role."); } ret = wpa_supplicant_ap_wps_pin(wpa_s, params.bssid, params.pin, npin, sizeof(npin), 0); } else if (wpa_s->ap_iface) { ret = wpa_supplicant_ap_wps_pbc(wpa_s, params.bssid, params.p2p_dev_addr); } else #endif /* CONFIG_AP */ if (params.role == 0) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Role not specified"); return wpas_dbus_error_invalid_args(message, "Role not specified"); } else if (params.role == 2) { if (params.pin == NULL) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Pin required for registrar role"); return wpas_dbus_error_invalid_args( message, "Pin required for registrar role."); } ret = wpas_wps_start_reg(wpa_s, params.bssid, params.pin, NULL); } else if (params.type == 0) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start - Type not specified"); return wpas_dbus_error_invalid_args(message, "Type not specified"); } else if (params.type == 1) { ret = wpas_wps_start_pin(wpa_s, params.bssid, params.pin, 0, DEV_PW_DEFAULT); if (ret > 0) os_snprintf(npin, sizeof(npin), "%08d", ret); } else { ret = wpas_wps_start_pbc(wpa_s, params.bssid, 0); } if (ret < 0) { wpa_printf(MSG_DEBUG, "dbus: WPS.Start wpas_wps_failed in role %s and key %s", (params.role == 1 ? "enrollee" : "registrar"), (params.type == 0 ? "" : (params.type == 1 ? "pin" : "pbc"))); return wpas_dbus_error_unknown_error(message, "WPS start failed"); } reply = dbus_message_new_method_return(message); if (!reply) return wpas_dbus_error_no_memory(message); dbus_message_iter_init_append(reply, &iter); if (!wpa_dbus_dict_open_write(&iter, &dict_iter) || (os_strlen(npin) > 0 && !wpa_dbus_dict_append_string(&dict_iter, "Pin", npin)) || !wpa_dbus_dict_close_write(&iter, &dict_iter)) { dbus_message_unref(reply); return wpas_dbus_error_no_memory(message); } return reply; }