Пример #1
0
static enum http_reply_code
web_process_set_selected_registrar(struct upnp_wps_device_sm *sm,
				   struct sockaddr_in *cli, char *data,
				   struct wpabuf **reply,
				   const char **replyname)
{
	struct wpabuf *msg;
	enum http_reply_code ret;
	struct subscription *s;
	struct upnp_wps_device_interface *iface;
	int err = 0;

	wpa_printf(MSG_DEBUG, "WPS UPnP: SetSelectedRegistrar");
	s = find_er(sm, cli);
	if (s == NULL) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Ignore SetSelectedRegistrar "
			   "from unknown ER");
		return UPNP_ACTION_FAILED;
	}
	msg = xml_get_base64_item(data, "NewMessage", &ret);
	if (msg == NULL)
		return ret;
	dl_list_for_each(iface, &sm->interfaces,
			 struct upnp_wps_device_interface, list) {
		if (upnp_er_set_selected_registrar(iface->wps->registrar, s,
						   msg))
			err = 1;
	}
	wpabuf_free(msg);
	if (err)
		return HTTP_INTERNAL_SERVER_ERROR;
	*replyname = NULL;
	*reply = NULL;
	return HTTP_OK;
}
Пример #2
0
static void wps_er_http_event(struct wps_er *er, struct http_request *req,
			      unsigned int ap_id)
{
	struct wps_er_ap *ap = wps_er_ap_get_id(er, ap_id);
	struct wpabuf *event;
	enum http_reply_code ret;

	if (ap == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: HTTP event from unknown AP id "
			   "%u", ap_id);
		wps_er_http_resp_not_found(req);
		return;
	}
	wpa_printf(MSG_MSGDUMP, "WPS ER: HTTP event from AP id %u: %s",
		   ap_id, http_request_get_data(req));

	event = xml_get_base64_item(http_request_get_data(req), "WLANEvent",
				    &ret);
	if (event == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Could not extract WLANEvent "
			   "from the event notification");
		/*
		 * Reply with OK anyway to avoid getting unregistered from
		 * events.
		 */
		wps_er_http_resp_ok(req);
		return;
	}

	wps_er_process_wlanevent(ap, event);

	wpabuf_free(event);
	wps_er_http_resp_ok(req);
}
Пример #3
0
static enum http_reply_code
web_process_put_message(struct upnp_wps_device_sm *sm, char *data,
			struct wpabuf **reply, const char **replyname)
{
	struct wpabuf *msg;
	static const char *name = "NewOutMessage";
	enum http_reply_code ret;
	enum wps_process_res res;
	enum wsc_op_code op_code;

	/*
	 * PutMessage is used by external UPnP-based Registrar to perform WPS
	 * operation with the access point itself; as compared with
	 * PutWLANResponse which is for proxying.
	 */
	wpa_printf(MSG_DEBUG, "WPS UPnP: PutMessage");
	msg = xml_get_base64_item(data, "NewInMessage", &ret);
	if (msg == NULL)
		return ret;
	res = wps_process_msg(sm->peer.wps, WSC_UPnP, msg);
	if (res == WPS_FAILURE)
		*reply = NULL;
	else
		*reply = wps_get_msg(sm->peer.wps, &op_code);
	wpabuf_free(msg);
	if (*reply == NULL)
		return HTTP_INTERNAL_SERVER_ERROR;
	*replyname = name;
	return HTTP_OK;
}
Пример #4
0
static enum http_reply_code
web_process_put_wlan_response(struct upnp_wps_device_sm *sm, char *data,
			      struct wpabuf **reply, const char **replyname)
{
	struct wpabuf *msg;
	enum http_reply_code ret;
	u8 macaddr[ETH_ALEN];
	int ev_type;
	int type;
	char *val;

	/*
	 * External UPnP-based Registrar is passing us a message to be proxied
	 * over to a Wi-Fi -based client of ours.
	 */

	wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse");
	msg = xml_get_base64_item(data, "NewMessage", &ret);
	if (msg == NULL)
		return ret;
	val = xml_get_first_item(data, "NewWLANEventType");
	if (val == NULL) {
		wpabuf_free(msg);
		return UPNP_ARG_VALUE_INVALID;
	}
	ev_type = atol(val);
	os_free(val);
	val = xml_get_first_item(data, "NewWLANEventMAC");
	if (val == NULL || hwaddr_aton(val, macaddr)) {
		wpabuf_free(msg);
		os_free(val);
		return UPNP_ARG_VALUE_INVALID;
	}
	os_free(val);
	if (ev_type == UPNP_WPS_WLANEVENT_TYPE_EAP) {
		struct wps_parse_attr attr;
		if (wps_parse_msg(msg, &attr) < 0 ||
		    attr.msg_type == NULL)
			type = -1;
		else
			type = *attr.msg_type;
		wpa_printf(MSG_DEBUG, "WPS UPnP: Message Type %d", type);
	} else
		type = -1;
	if (!sm->ctx->rx_req_put_wlan_response ||
	    sm->ctx->rx_req_put_wlan_response(sm->priv, ev_type, macaddr, msg,
					      type)) {
		wpa_printf(MSG_INFO, "WPS UPnP: Fail: sm->ctx->"
			   "rx_req_put_wlan_response");
		wpabuf_free(msg);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	wpabuf_free(msg);
	*replyname = NULL;
	*reply = NULL;
	return HTTP_OK;
}
Пример #5
0
static void wps_er_http_put_message_cb(void *ctx, struct http_client *c,
				       enum http_client_event event)
{
	struct wps_er_ap *ap = ctx;
	struct wpabuf *reply;
	char *msg = NULL;

	switch (event) {
	case HTTP_CLIENT_OK:
		wpa_printf(MSG_DEBUG, "WPS ER: PutMessage OK");
		reply = http_client_get_body(c);
		if (reply == NULL)
			break;
		msg = os_zalloc(wpabuf_len(reply) + 1);
		if (msg == NULL)
			break;
		os_memcpy(msg, wpabuf_head(reply), wpabuf_len(reply));
		break;
	case HTTP_CLIENT_FAILED:
	case HTTP_CLIENT_INVALID_REPLY:
	case HTTP_CLIENT_TIMEOUT:
		wpa_printf(MSG_DEBUG, "WPS ER: PutMessage failed");
		if (ap->wps) {
			wps_deinit(ap->wps);
			ap->wps = NULL;
		}
		break;
	}
	http_client_free(ap->http);
	ap->http = NULL;

	if (msg) {
		struct wpabuf *buf;
		enum http_reply_code ret;
		buf = xml_get_base64_item(msg, "NewOutMessage", &ret);
		os_free(msg);
		if (buf == NULL) {
			wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
				   "NewOutMessage from PutMessage response");
			wps_deinit(ap->wps);
			ap->wps = NULL;
			return;
		}
		wps_er_ap_process(ap, buf);
		wpabuf_free(buf);
	}
}
Пример #6
0
static void wps_er_ap_learn(struct wps_er_ap *ap, const char *dev_info)
{
	struct wpabuf *info;
	enum http_reply_code ret;

	wpa_printf(MSG_DEBUG, "WPS ER: Received GetDeviceInfo response (M1) "
		   "from the AP");
	info = xml_get_base64_item(dev_info, "NewDeviceInfo", &ret);
	if (info == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Could not extract "
			   "NewDeviceInfo from GetDeviceInfo response");
		return;
	}

	ap->m1_handler(ap, info);
	wpabuf_free(info);
}
Пример #7
0
static enum http_reply_code
web_process_put_wlan_response(struct upnp_wps_device_sm *sm, char *data,
			      struct wpabuf **reply, const char **replyname)
{
	struct wpabuf *msg;
	enum http_reply_code ret;
	u8 macaddr[ETH_ALEN];
	int ev_type;
	int type;
	char *val;
	struct upnp_wps_device_interface *iface;
	int ok = 0;

	/*
	 * External UPnP-based Registrar is passing us a message to be proxied
	 * over to a Wi-Fi -based client of ours.
	 */

	wpa_printf(MSG_DEBUG, "WPS UPnP: PutWLANResponse");
	msg = xml_get_base64_item(data, "NewMessage", &ret);
	if (msg == NULL) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Could not extract NewMessage "
			   "from PutWLANResponse");
		return ret;
	}
	val = xml_get_first_item(data, "NewWLANEventType");
	if (val == NULL) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: No NewWLANEventType in "
			   "PutWLANResponse");
		wpabuf_free(msg);
		return UPNP_ARG_VALUE_INVALID;
	}
	ev_type = atol(val);
	os_free(val);
	val = xml_get_first_item(data, "NewWLANEventMAC");
	if (val == NULL) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: No NewWLANEventMAC in "
			   "PutWLANResponse");
		wpabuf_free(msg);
		return UPNP_ARG_VALUE_INVALID;
	}
	if (hwaddr_aton(val, macaddr)) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: Invalid NewWLANEventMAC in "
			   "PutWLANResponse: '%s'", val);
#ifdef CONFIG_WPS_STRICT
		{
			struct wps_parse_attr attr;
			if (wps_parse_msg(msg, &attr) < 0 || attr.version2) {
				wpabuf_free(msg);
				os_free(val);
				return UPNP_ARG_VALUE_INVALID;
			}
		}
#endif /* CONFIG_WPS_STRICT */
		if (hwaddr_aton2(val, macaddr) > 0) {
			/*
			 * At least some versions of Intel PROset seem to be
			 * using dot-deliminated MAC address format here.
			 */
			wpa_printf(MSG_DEBUG, "WPS UPnP: Workaround - allow "
				   "incorrect MAC address format in "
				   "NewWLANEventMAC: %s -> " MACSTR,
				   val, MAC2STR(macaddr));
		} else {
			wpabuf_free(msg);
			os_free(val);
			return UPNP_ARG_VALUE_INVALID;
		}
	}
	os_free(val);
	if (ev_type == UPNP_WPS_WLANEVENT_TYPE_EAP) {
		struct wps_parse_attr attr;
		if (wps_parse_msg(msg, &attr) < 0 ||
		    attr.msg_type == NULL)
			type = -1;
		else
			type = *attr.msg_type;
		wpa_printf(MSG_DEBUG, "WPS UPnP: Message Type %d", type);
	} else
		type = -1;
	dl_list_for_each(iface, &sm->interfaces,
			 struct upnp_wps_device_interface, list) {
		if (iface->ctx->rx_req_put_wlan_response &&
		    iface->ctx->rx_req_put_wlan_response(iface->priv, ev_type,
							 macaddr, msg, type)
		    == 0)
			ok = 1;
	}

	if (!ok) {
		wpa_printf(MSG_INFO, "WPS UPnP: Fail: sm->ctx->"
			   "rx_req_put_wlan_response");
		wpabuf_free(msg);
		return HTTP_INTERNAL_SERVER_ERROR;
	}
	wpabuf_free(msg);
	*replyname = NULL;
	*reply = NULL;
	return HTTP_OK;
}
Пример #8
0
static enum http_reply_code
web_process_put_message(struct upnp_wps_device_sm *sm, char *data,
			struct wpabuf **reply, const char **replyname)
{
	struct wpabuf *msg;
	static const char *name = "NewOutMessage";
	enum http_reply_code ret;
	enum wps_process_res res;
	enum wsc_op_code op_code;
	struct upnp_wps_device_interface *iface;
	struct wps_parse_attr attr;
	struct upnp_wps_peer *tmp, *peer;

	iface = dl_list_first(&sm->interfaces,
			      struct upnp_wps_device_interface, list);
	if (!iface)
		return HTTP_INTERNAL_SERVER_ERROR;

	/*
	 * PutMessage is used by external UPnP-based Registrar to perform WPS
	 * operation with the access point itself; as compared with
	 * PutWLANResponse which is for proxying.
	 */
	wpa_printf(MSG_DEBUG, "WPS UPnP: PutMessage");
	msg = xml_get_base64_item(data, "NewInMessage", &ret);
	if (msg == NULL)
		return ret;

	if (wps_parse_msg(msg, &attr)) {
		wpa_printf(MSG_DEBUG,
			   "WPS UPnP: Could not parse PutMessage - NewInMessage");
		wpabuf_free(msg);
		return HTTP_BAD_REQUEST;
	}

	/* Find a matching active peer session */
	peer = NULL;
	dl_list_for_each(tmp, &iface->peers, struct upnp_wps_peer, list) {
		if (!tmp->wps)
			continue;
		if (attr.enrollee_nonce &&
		    os_memcmp(tmp->wps->nonce_e, attr.enrollee_nonce,
			      WPS_NONCE_LEN) != 0)
			continue; /* Enrollee nonce mismatch */
		if (attr.msg_type &&
		    *attr.msg_type != WPS_M2 &&
		    *attr.msg_type != WPS_M2D &&
		    attr.registrar_nonce &&
		    os_memcmp(tmp->wps->nonce_r, attr.registrar_nonce,
			      WPS_NONCE_LEN) != 0)
			continue; /* Registrar nonce mismatch */
		peer = tmp;
		break;
	}
	if (!peer) {
		/*
		  Try to use the first entry in case message could work with
		 * it. The actual handler function will reject this, if needed.
		 * This maintains older behavior where only a single peer entry
		 * was supported.
		 */
		peer = dl_list_first(&iface->peers, struct upnp_wps_peer, list);
	}