1214501Srpaulo/*
2214501Srpaulo * WPA Supplicant / dbus-based control interface (WPS)
3214501Srpaulo * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc.
4214501Srpaulo *
5252190Srpaulo * This software may be distributed under the terms of the BSD license.
6252190Srpaulo * See README for more details.
7214501Srpaulo */
8214501Srpaulo
9214501Srpaulo#include "includes.h"
10214501Srpaulo#include <dbus/dbus.h>
11214501Srpaulo
12214501Srpaulo#include "common.h"
13214501Srpaulo#include "../config.h"
14214501Srpaulo#include "../wpa_supplicant_i.h"
15214501Srpaulo#include "../wps_supplicant.h"
16214501Srpaulo#include "dbus_old.h"
17214501Srpaulo#include "dbus_old_handlers.h"
18214501Srpaulo
19214501Srpaulo/**
20214501Srpaulo * wpas_dbus_iface_wps_pbc - Request credentials using WPS PBC method
21214501Srpaulo * @message: Pointer to incoming dbus message
22214501Srpaulo * @wpa_s: %wpa_supplicant data structure
23214501Srpaulo * Returns: A dbus message containing a UINT32 indicating success (1) or
24214501Srpaulo *          failure (0)
25214501Srpaulo *
26214501Srpaulo * Handler function for "wpsPbc" method call
27214501Srpaulo */
28214501SrpauloDBusMessage * wpas_dbus_iface_wps_pbc(DBusMessage *message,
29214501Srpaulo				      struct wpa_supplicant *wpa_s)
30214501Srpaulo{
31214501Srpaulo	char *arg_bssid = NULL;
32214501Srpaulo	u8 bssid[ETH_ALEN];
33214501Srpaulo	int ret = 0;
34214501Srpaulo
35214501Srpaulo	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
36214501Srpaulo				   DBUS_TYPE_INVALID))
37214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message, NULL);
38214501Srpaulo
39214501Srpaulo	if (!os_strcmp(arg_bssid, "any"))
40252190Srpaulo		ret = wpas_wps_start_pbc(wpa_s, NULL, 0);
41214501Srpaulo	else if (!hwaddr_aton(arg_bssid, bssid))
42252190Srpaulo		ret = wpas_wps_start_pbc(wpa_s, bssid, 0);
43214501Srpaulo	else {
44214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message,
45214501Srpaulo							"Invalid BSSID");
46214501Srpaulo	}
47214501Srpaulo
48214501Srpaulo	if (ret < 0) {
49214501Srpaulo		return dbus_message_new_error(message,
50214501Srpaulo					      WPAS_ERROR_WPS_PBC_ERROR,
51214501Srpaulo					      "Could not start PBC "
52214501Srpaulo					      "negotiation");
53214501Srpaulo	}
54214501Srpaulo
55214501Srpaulo	return wpas_dbus_new_success_reply(message);
56214501Srpaulo}
57214501Srpaulo
58214501Srpaulo
59214501Srpaulo/**
60214501Srpaulo * wpas_dbus_iface_wps_pin - Establish the PIN number of the enrollee
61214501Srpaulo * @message: Pointer to incoming dbus message
62214501Srpaulo * @wpa_s: %wpa_supplicant data structure
63214501Srpaulo * Returns: A dbus message containing a UINT32 indicating success (1) or
64214501Srpaulo *          failure (0)
65214501Srpaulo *
66214501Srpaulo * Handler function for "wpsPin" method call
67214501Srpaulo */
68214501SrpauloDBusMessage * wpas_dbus_iface_wps_pin(DBusMessage *message,
69214501Srpaulo				      struct wpa_supplicant *wpa_s)
70214501Srpaulo{
71214501Srpaulo	DBusMessage *reply = NULL;
72214501Srpaulo	char *arg_bssid;
73214501Srpaulo	char *pin = NULL;
74214501Srpaulo	u8 bssid[ETH_ALEN], *_bssid = NULL;
75214501Srpaulo	int ret = 0;
76214501Srpaulo
77214501Srpaulo	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
78214501Srpaulo				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
79214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message, NULL);
80214501Srpaulo
81214501Srpaulo	if (!os_strcmp(arg_bssid, "any"))
82214501Srpaulo		_bssid = NULL;
83214501Srpaulo	else if (!hwaddr_aton(arg_bssid, bssid))
84214501Srpaulo		_bssid = bssid;
85214501Srpaulo	else {
86214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message,
87214501Srpaulo							"Invalid BSSID");
88214501Srpaulo	}
89214501Srpaulo
90214501Srpaulo	if (os_strlen(pin) > 0)
91252190Srpaulo		ret = wpas_wps_start_pin(wpa_s, _bssid, pin, 0,
92252190Srpaulo					 DEV_PW_DEFAULT);
93214501Srpaulo	else
94252190Srpaulo		ret = wpas_wps_start_pin(wpa_s, _bssid, NULL, 0,
95252190Srpaulo					 DEV_PW_DEFAULT);
96214501Srpaulo
97214501Srpaulo	if (ret < 0) {
98214501Srpaulo		return dbus_message_new_error(message,
99214501Srpaulo					      WPAS_ERROR_WPS_PIN_ERROR,
100214501Srpaulo					      "Could not init PIN");
101214501Srpaulo	}
102214501Srpaulo
103214501Srpaulo	reply = dbus_message_new_method_return(message);
104214501Srpaulo	if (reply == NULL)
105214501Srpaulo		return NULL;
106214501Srpaulo
107214501Srpaulo	if (ret == 0) {
108214501Srpaulo		dbus_message_append_args(reply, DBUS_TYPE_STRING, &pin,
109214501Srpaulo					 DBUS_TYPE_INVALID);
110214501Srpaulo	} else {
111214501Srpaulo		char npin[9];
112214501Srpaulo		os_snprintf(npin, sizeof(npin), "%08d", ret);
113214501Srpaulo		dbus_message_append_args(reply, DBUS_TYPE_STRING, &npin,
114214501Srpaulo					 DBUS_TYPE_INVALID);
115214501Srpaulo	}
116214501Srpaulo	return reply;
117214501Srpaulo}
118214501Srpaulo
119214501Srpaulo
120214501Srpaulo/**
121214501Srpaulo * wpas_dbus_iface_wps_reg - Request credentials using the PIN of the AP
122214501Srpaulo * @message: Pointer to incoming dbus message
123214501Srpaulo * @wpa_s: %wpa_supplicant data structure
124214501Srpaulo * Returns: A dbus message containing a UINT32 indicating success (1) or
125214501Srpaulo *          failure (0)
126214501Srpaulo *
127214501Srpaulo * Handler function for "wpsReg" method call
128214501Srpaulo */
129214501SrpauloDBusMessage * wpas_dbus_iface_wps_reg(DBusMessage *message,
130214501Srpaulo				      struct wpa_supplicant *wpa_s)
131214501Srpaulo{
132214501Srpaulo	char *arg_bssid;
133214501Srpaulo	char *pin = NULL;
134214501Srpaulo	u8 bssid[ETH_ALEN];
135214501Srpaulo	int ret = 0;
136214501Srpaulo
137214501Srpaulo	if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg_bssid,
138214501Srpaulo				   DBUS_TYPE_STRING, &pin, DBUS_TYPE_INVALID))
139214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message, NULL);
140214501Srpaulo
141214501Srpaulo	if (!os_strcmp(arg_bssid, "any"))
142214501Srpaulo		ret = wpas_wps_start_reg(wpa_s, NULL, pin, NULL);
143214501Srpaulo	else if (!hwaddr_aton(arg_bssid, bssid))
144214501Srpaulo		ret = wpas_wps_start_reg(wpa_s, bssid, pin, NULL);
145214501Srpaulo	else {
146214501Srpaulo		return wpas_dbus_new_invalid_opts_error(message,
147214501Srpaulo							"Invalid BSSID");
148214501Srpaulo	}
149214501Srpaulo
150214501Srpaulo	if (ret < 0) {
151214501Srpaulo		return dbus_message_new_error(message,
152214501Srpaulo					      WPAS_ERROR_WPS_PBC_ERROR,
153214501Srpaulo					      "Could not request credentials");
154214501Srpaulo	}
155214501Srpaulo
156214501Srpaulo	return wpas_dbus_new_success_reply(message);
157214501Srpaulo}
158