WPS ER: Add PutWLANResponse generation and transmission
This allows the M2D message to be transmitted as a response to the Enrollee via the proxying AP.
This commit is contained in:
parent
b345031997
commit
ecc6d04b89
1 changed files with 101 additions and 13 deletions
114
src/wps/wps_er.c
114
src/wps/wps_er.c
|
@ -15,6 +15,7 @@
|
||||||
#include "includes.h"
|
#include "includes.h"
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "base64.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "eloop.h"
|
#include "eloop.h"
|
||||||
#include "httpread.h"
|
#include "httpread.h"
|
||||||
|
@ -140,13 +141,6 @@ static void wps_er_sta_remove_all(struct wps_er_ap *ap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void wps_er_pin_needed_cb(void *ctx, const u8 *uuid_e,
|
|
||||||
const struct wps_device_data *dev)
|
|
||||||
{
|
|
||||||
wpa_printf(MSG_DEBUG, "WPS ER: PIN needed");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
|
static struct wps_er_ap * wps_er_ap_get(struct wps_er *er,
|
||||||
struct in_addr *addr)
|
struct in_addr *addr)
|
||||||
{
|
{
|
||||||
|
@ -717,12 +711,110 @@ static void wps_er_process_wlanevent_probe_req(struct wps_er_ap *ap,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void wps_er_http_put_wlan_response_cb(void *ctx, struct http_client *c,
|
||||||
|
enum http_client_event event)
|
||||||
|
{
|
||||||
|
struct wps_er_sta *sta = ctx;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case HTTP_CLIENT_OK:
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse OK");
|
||||||
|
break;
|
||||||
|
case HTTP_CLIENT_FAILED:
|
||||||
|
case HTTP_CLIENT_INVALID_REPLY:
|
||||||
|
case HTTP_CLIENT_TIMEOUT:
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS ER: PutWLANResponse failed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
http_client_free(sta->http);
|
||||||
|
sta->http = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *soap_prefix =
|
||||||
|
"<?xml version=\"1.0\"?>\n"
|
||||||
|
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
|
||||||
|
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
|
||||||
|
"<s:Body>\n";
|
||||||
|
static const char *soap_postfix =
|
||||||
|
"</s:Body>\n</s:Envelope>\n";
|
||||||
|
static const char *urn_wfawlanconfig =
|
||||||
|
"urn:schemas-wifialliance-org:service:WFAWLANConfig:1";
|
||||||
|
|
||||||
static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
|
static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
|
||||||
{
|
{
|
||||||
/* TODO: send msg as UPnP POST: PutWLANResponse(NewMessage,
|
unsigned char *encoded;
|
||||||
* NewWLANEventType, NewWLANEventMAC) */
|
size_t encoded_len;
|
||||||
|
struct wpabuf *buf;
|
||||||
|
char *len_ptr, *body_ptr;
|
||||||
|
char len_buf[10];
|
||||||
|
struct sockaddr_in dst;
|
||||||
|
char *url, *path;
|
||||||
|
|
||||||
|
if (sta->http) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
|
||||||
|
"ignore new request");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
url = http_client_url_parse(sta->ap->control_url, &dst, &path);
|
||||||
|
if (url == NULL) {
|
||||||
|
wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
encoded = base64_encode(wpabuf_head(msg), wpabuf_len(msg),
|
||||||
|
&encoded_len);
|
||||||
wpabuf_free(msg);
|
wpabuf_free(msg);
|
||||||
|
if (encoded == NULL) {
|
||||||
|
os_free(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = wpabuf_alloc(1000 + encoded_len);
|
||||||
|
if (buf == NULL) {
|
||||||
|
os_free(encoded);
|
||||||
|
os_free(url);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wpabuf_printf(buf,
|
||||||
|
"POST %s HTTP/1.1\r\n"
|
||||||
|
"Host: %s:%d\r\n"
|
||||||
|
"Content-Type: text/xml; charset=\"utf-8\"\r\n"
|
||||||
|
"Content-Length: ",
|
||||||
|
path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port));
|
||||||
|
os_free(url);
|
||||||
|
len_ptr = wpabuf_put(buf, 0);
|
||||||
|
wpabuf_printf(buf,
|
||||||
|
" \r\n"
|
||||||
|
"SOAPACTION: \"%s#PutWLANResponse\"\r\n"
|
||||||
|
"\r\n",
|
||||||
|
urn_wfawlanconfig);
|
||||||
|
|
||||||
|
body_ptr = wpabuf_put(buf, 0);
|
||||||
|
|
||||||
|
wpabuf_put_str(buf, soap_prefix);
|
||||||
|
wpabuf_put_str(buf, "<u:PutWLANResponse xmlns:u=\"");
|
||||||
|
wpabuf_put_str(buf, urn_wfawlanconfig);
|
||||||
|
wpabuf_put_str(buf, "\">\n");
|
||||||
|
wpabuf_printf(buf, "<NewMessage>%s</NewMessage>\n", (char *) encoded);
|
||||||
|
os_free(encoded);
|
||||||
|
wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n",
|
||||||
|
UPNP_WPS_WLANEVENT_TYPE_EAP);
|
||||||
|
wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n",
|
||||||
|
MAC2STR(sta->addr));
|
||||||
|
wpabuf_put_str(buf, "</u:PutWLANResponse>\n");
|
||||||
|
wpabuf_put_str(buf, soap_postfix);
|
||||||
|
|
||||||
|
os_snprintf(len_buf, sizeof(len_buf), "%d",
|
||||||
|
(int) ((char *) wpabuf_put(buf, 0) - body_ptr));
|
||||||
|
os_memcpy(len_ptr, len_buf, os_strlen(len_buf));
|
||||||
|
|
||||||
|
sta->http = http_client_addr(&dst, buf, 1000,
|
||||||
|
wps_er_http_put_wlan_response_cb, sta);
|
||||||
|
if (sta->http == NULL)
|
||||||
|
wpabuf_free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -915,7 +1007,6 @@ struct wps_er *
|
||||||
wps_er_init(struct wps_context *wps, const char *ifname)
|
wps_er_init(struct wps_context *wps, const char *ifname)
|
||||||
{
|
{
|
||||||
struct wps_er *er;
|
struct wps_er *er;
|
||||||
struct wps_registrar_config rcfg;
|
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
er = os_zalloc(sizeof(*er));
|
er = os_zalloc(sizeof(*er));
|
||||||
|
@ -927,9 +1018,6 @@ wps_er_init(struct wps_context *wps, const char *ifname)
|
||||||
|
|
||||||
os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
|
os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
|
||||||
er->wps = wps;
|
er->wps = wps;
|
||||||
os_memset(&rcfg, 0, sizeof(rcfg));
|
|
||||||
rcfg.pin_needed_cb = wps_er_pin_needed_cb;
|
|
||||||
rcfg.cb_ctx = er;
|
|
||||||
|
|
||||||
if (get_netif_info(ifname,
|
if (get_netif_info(ifname,
|
||||||
&er->ip_addr, &er->ip_addr_text,
|
&er->ip_addr, &er->ip_addr_text,
|
||||||
|
|
Loading…
Reference in a new issue