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