1/*
2 * WPA Supplicant / dbus-based control interface (WPS)
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 "../config.h"
14#include "../wpa_supplicant_i.h"
15#include "../wps_supplicant.h"
16#include "dbus_old.h"
17#include "dbus_old_handlers.h"
18
19/**
20 * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
21 * @message: Pointer to incoming dbus message
22 * @wpa_s: %wpa_supplicant data structure
23 * Returns: A dbus message containing a UINT32 indicating success (1) or
24 *          failure (0)
25 *
26 * Handler function for "wpsPbc" method call
27 */
28DBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
29				      struct wpa_supplicant *wpa_s)
30{
31	char *arg_bssid = NULL;
32	u8 bssid[ETH_ALEN];
33	int ret = 0;
34
35	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
36				   DBUS_TYPE_INVALID))
37		return wpas_dbus_new_invalid_opts_error(message, NULL);
38
39	if (!os_strcmp(arg_bssid, "any"))
40		ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
41	else if (!hwaddr_aton(arg_bssid, bssid))
42		ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
43	else {
44		return wpas_dbus_new_invalid_opts_error(message,
45							"Invalid BSSID");
46	}
47
48	if (ret < 0) {
49		return dbus_message_new_error(message,
50					      WPAS_ERROR_WPS_PBC_ERROR,
51					      "Could not start PBC "
52					      "negotiation");
53	}
54
55	return wpas_dbus_new_success_reply(message);
56}
57
58
59/**
60 * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
61 * @message: Pointer to incoming dbus message
62 * @wpa_s: %wpa_supplicant data structure
63 * Returns: A dbus message containing a UINT32 indicating success (1) or
64 *          failure (0)
65 *
66 * Handler function for "wpsPin" method call
67 */
68DBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
69				      struct wpa_supplicant *wpa_s)
70{
71	DBusMessage *reply = NULL;
72	char *arg_bssid;
73	char *pin = NULL;
74	u8 bssid[ETH_ALEN], *_bssid = NULL;
75	int ret = 0;
76
77	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
78				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
79		return wpas_dbus_new_invalid_opts_error(message, NULL);
80
81	if (!os_strcmp(arg_bssid, "any"))
82		_bssid = NULL;
83	else if (!hwaddr_aton(arg_bssid, bssid))
84		_bssid = bssid;
85	else {
86		return wpas_dbus_new_invalid_opts_error(message,
87							"Invalid BSSID");
88	}
89
90	if (os_strlen(pin) > 0)
91		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
92					 DEV_PW_DEFAULT);
93	else
94		ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
95					 DEV_PW_DEFAULT);
96
97	if (ret < 0) {
98		return dbus_message_new_error(message,
99					      WPAS_ERROR_WPS_PIN_ERROR,
100					      "Could not init PIN");
101	}
102
103	reply = dbus_message_new_method_return(message);
104	if (reply == NULL)
105		return NULL;
106
107	if (ret == 0) {
108		dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
109					 DBUS_TYPE_INVALID);
110	} else {
111		char npin[9];
112		os_snprintf(npin, sizeof(npin), "%08d", ret);
113		dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin,
114					 DBUS_TYPE_INVALID);
115	}
116	return reply;
117}
118
119
120/**
121 * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
122 * @message: Pointer to incoming dbus message
123 * @wpa_s: %wpa_supplicant data structure
124 * Returns: A dbus message containing a UINT32 indicating success (1) or
125 *          failure (0)
126 *
127 * Handler function for "wpsReg" method call
128 */
129DBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
130				      struct wpa_supplicant *wpa_s)
131{
132	char *arg_bssid;
133	char *pin = NULL;
134	u8 bssid[ETH_ALEN];
135	int ret = 0;
136
137	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
138				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
139		return wpas_dbus_new_invalid_opts_error(message, NULL);
140
141	if (!os_strcmp(arg_bssid, "any"))
142		ret = wpas_wps_start_reg(wpa_s, NULL, pin, NULL);
143	else if (!hwaddr_aton(arg_bssid, bssid))
144		ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
145	else {
146		return wpas_dbus_new_invalid_opts_error(message,
147							"Invalid BSSID");
148	}
149
150	if (ret < 0) {
151		return dbus_message_new_error(message,
152					      WPAS_ERROR_WPS_PBC_ERROR,
153					      "Could not request credentials");
154	}
155
156	return wpas_dbus_new_success_reply(message);
157}
158