Пример #1
0
static void wps_er_ap_unsubscribe(struct wps_er *er, struct wps_er_ap *ap)
{
	struct wpabuf *req;
	struct sockaddr_in dst;
	char *url, *path;
	char sid[100];

	if (ap->event_sub_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
			   "subscribe");
		goto fail;
	}
	if (ap->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
			   "send subscribe request");
		goto fail;
	}

	url = http_client_url_parse(ap->event_sub_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
		goto fail;
	}

	req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
	if (req == NULL) {
		os_free(url);
		goto fail;
	}
	uuid_bin2str(ap->sid, sid, sizeof(sid));
	wpabuf_printf(req,
		      "UNSUBSCRIBE %s HTTP/1.1\r\n"
		      "HOST: %s:%d\r\n"
		      "SID: uuid:%s\r\n"
		      "\r\n",
		      path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port), sid);
	os_free(url);
	wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Unsubscription request",
			  wpabuf_head(req), wpabuf_len(req));

	ap->http = http_client_addr(&dst, req, 1000,
				    wps_er_http_unsubscribe_cb, ap);
	if (ap->http == NULL) {
		wpabuf_free(req);
		goto fail;
	}
	return;

fail:
	/*
	 * Need to get rid of the AP entry even when we fail to unsubscribe
	 * cleanly.
	 */
	wps_er_ap_unsubscribed(ap->er, ap);
}
Пример #2
0
static void wps_er_subscribe(struct wps_er_ap *ap)
{
	struct wpabuf *req;
	struct sockaddr_in dst;
	char *url, *path;

	if (ap->event_sub_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No eventSubURL - cannot "
			   "subscribe");
		return;
	}
	if (ap->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request - cannot "
			   "send subscribe request");
		return;
	}

	url = http_client_url_parse(ap->event_sub_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse eventSubURL");
		return;
	}

	req = wpabuf_alloc(os_strlen(ap->event_sub_url) + 1000);
	if (req == NULL) {
		os_free(url);
		return;
	}
	wpabuf_printf(req,
		      "SUBSCRIBE %s HTTP/1.1\r\n"
		      "HOST: %s:%d\r\n"
		      "CALLBACK: <http://%s:%d/event/%u/%u>\r\n"
		      "NT: upnp:event\r\n"
		      "TIMEOUT: Second-%d\r\n"
		      "\r\n",
		      path, inet_ntoa(dst.sin_addr), ntohs(dst.sin_port),
		      ap->er->ip_addr_text, ap->er->http_port,
		      ap->er->event_id, ap->id, 1800);
	os_free(url);
	wpa_hexdump_ascii(MSG_MSGDUMP, "WPS ER: Subscription request",
			  wpabuf_head(req), wpabuf_len(req));

	ap->http = http_client_addr(&dst, req, 1000, wps_er_http_subscribe_cb,
				    ap);
	if (ap->http == NULL)
		wpabuf_free(req);
}
Пример #3
0
struct http_client * http_client_url(const char *url,
				     struct wpabuf *req, size_t max_response,
				     void (*cb)(void *ctx,
						struct http_client *c,
						enum http_client_event event),
				     void *cb_ctx)
{
	struct sockaddr_in dst;
	struct http_client *c;
	char *u, *path;
	struct wpabuf *req_buf = NULL;

	if (os_strncmp(url, "http://", 7) != 0)
		return NULL;
	u = http_client_url_parse(url, &dst, &path);
	if (u == NULL)
		return NULL;

	if (req == NULL) {
		req_buf = wpabuf_alloc(os_strlen(url) + 1000);
		if (req_buf == NULL) {
			os_free(u);
			return NULL;
		}
		req = req_buf;
		wpabuf_printf(req,
			      "GET %s HTTP/1.1\r\n"
			      "Cache-Control: no-cache\r\n"
			      "Pragma: no-cache\r\n"
			      "Accept: text/xml, application/xml\r\n"
			      "User-Agent: wpa_supplicant\r\n"
			      "Host: %s:%d\r\n"
			      "\r\n",
			      path, inet_ntoa(dst.sin_addr),
			      ntohs(dst.sin_port));
	}
	os_free(u);

	c = http_client_addr(&dst, req, max_response, cb, cb_ctx);
	if (c == NULL) {
		wpabuf_free(req_buf);
		return NULL;
	}

	return c;
}
Пример #4
0
static void wps_er_sta_send_msg(struct wps_er_sta *sta, struct wpabuf *msg)
{
	struct wpabuf *buf;
	char *len_ptr, *body_ptr;
	struct sockaddr_in dst;
	char *url, *path;

	if (sta->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for STA - "
			   "ignore new request");
		wpabuf_free(msg);
		return;
	}

	if (sta->ap->control_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
		wpabuf_free(msg);
		return;
	}

	url = http_client_url_parse(sta->ap->control_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
		wpabuf_free(msg);
		return;
	}

	buf = wps_er_soap_hdr(msg, "PutWLANResponse", "NewMessage", path, &dst,
			      &len_ptr, &body_ptr);
	wpabuf_free(msg);
	os_free(url);
	if (buf == NULL)
		return;
	wpabuf_printf(buf, "<NewWLANEventType>%d</NewWLANEventType>\n",
		      UPNP_WPS_WLANEVENT_TYPE_EAP);
	wpabuf_printf(buf, "<NewWLANEventMAC>" MACSTR "</NewWLANEventMAC>\n",
		      MAC2STR(sta->addr));

	wps_er_soap_end(buf, "PutWLANResponse", len_ptr, body_ptr);

	sta->http = http_client_addr(&dst, buf, 1000,
				     wps_er_http_put_wlan_response_cb, sta);
	if (sta->http == NULL)
		wpabuf_free(buf);
}
Пример #5
0
static int wps_er_send_get_device_info(struct wps_er_ap *ap,
				       void (*m1_handler)(struct wps_er_ap *ap,
							  struct wpabuf *m1))
{
	struct wpabuf *buf;
	char *len_ptr, *body_ptr;
	struct sockaddr_in dst;
	char *url, *path;

	if (ap->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
			   "with the AP - cannot get device info");
		return -1;
	}

	if (ap->control_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
		return -1;
	}

	url = http_client_url_parse(ap->control_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
		return -1;
	}

	buf = wps_er_soap_hdr(NULL, "GetDeviceInfo", NULL, path, &dst,
			      &len_ptr, &body_ptr);
	os_free(url);
	if (buf == NULL)
		return -1;

	wps_er_soap_end(buf, "GetDeviceInfo", len_ptr, body_ptr);

	ap->http = http_client_addr(&dst, buf, 10000,
				    wps_er_http_get_dev_info_cb, ap);
	if (ap->http == NULL) {
		wpabuf_free(buf);
		return -1;
	}

	ap->m1_handler = m1_handler;

	return 0;
}
Пример #6
0
static void wps_er_send_set_sel_reg(struct wps_er_ap *ap, struct wpabuf *msg)
{
	struct wpabuf *buf;
	char *len_ptr, *body_ptr;
	struct sockaddr_in dst;
	char *url, *path;

	if (ap->control_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
		return;
	}

	if (ap->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP request for AP - "
			   "ignore new request");
		return;
	}

	if (ap->wps) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending WPS operation for AP - "
			   "skip SetSelectedRegistrar");
		return;
	}

	url = http_client_url_parse(ap->control_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
		return;
	}

	buf = wps_er_soap_hdr(msg, "SetSelectedRegistrar", "NewMessage", path,
			      &dst, &len_ptr, &body_ptr);
	os_free(url);
	if (buf == NULL)
		return;

	wps_er_soap_end(buf, "SetSelectedRegistrar", len_ptr, body_ptr);

	ap->http = http_client_addr(&dst, buf, 1000,
				    wps_er_http_set_sel_reg_cb, ap);
	if (ap->http == NULL)
		wpabuf_free(buf);
}
Пример #7
0
/* event_send_start -- prepare to send a event message to subscriber
 *
 * This gets complicated because:
 * -- The message is sent via TCP and we have to keep the stream open
 *      for 30 seconds to get a response... then close it.
 * -- But we might have other event happen in the meantime...
 *      we have to queue them, if we lose them then the subscriber will
 *      be forced to unsubscribe and subscribe again.
 * -- If multiple URLs are provided then we are supposed to try successive
 *      ones after 30 second timeout.
 * -- The URLs might use domain names instead of dotted decimal addresses,
 *      and resolution of those may cause unwanted sleeping.
 * -- Doing the initial TCP connect can take a while, so we have to come
 *      back after connection and then send the data.
 *
 * Returns nonzero on error;
 *
 * Prerequisite: No current event send (s->current_event == NULL)
 *      and non-empty queue.
 */
static int event_send_start(struct subscription *s)
{
	struct wps_event_ *e;
	unsigned int itry;
	struct wpabuf *buf;

	/*
	 * Assume we are called ONLY with no current event and ONLY with
	 * nonempty event queue and ONLY with at least one address to send to.
	 */
	if (dl_list_empty(&s->addr_list) ||
	    s->current_event ||
	    dl_list_empty(&s->event_queue))
		return -1;

	s->current_event = e = event_dequeue(s);

	/* Use address according to number of retries */
	itry = 0;
	dl_list_for_each(e->addr, &s->addr_list, struct subscr_addr, list)
		if (itry++ == e->retry)
			break;
	if (itry < e->retry)
		return -1;

	buf = event_build_message(e);
	if (buf == NULL) {
		event_retry(e, 0);
		return -1;
	}

	e->http_event = http_client_addr(&e->addr->saddr, buf, 0,
					 event_http_cb, e);
	if (e->http_event == NULL) {
		wpabuf_free(buf);
		event_retry(e, 0);
		return -1;
	}

	return 0;
}
Пример #8
0
static void wps_er_ap_put_message(struct wps_er_ap *ap,
				  const struct wpabuf *msg)
{
	struct wpabuf *buf;
	char *len_ptr, *body_ptr;
	struct sockaddr_in dst;
	char *url, *path;

	if (ap->http) {
		wpa_printf(MSG_DEBUG, "WPS ER: Pending HTTP operation ongoing "
			   "with the AP - cannot continue learn");
		return;
	}

	if (ap->control_url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: No controlURL for AP");
		return;
	}

	url = http_client_url_parse(ap->control_url, &dst, &path);
	if (url == NULL) {
		wpa_printf(MSG_DEBUG, "WPS ER: Failed to parse controlURL");
		return;
	}

	buf = wps_er_soap_hdr(msg, "PutMessage", "NewInMessage", path, &dst,
			      &len_ptr, &body_ptr);
	os_free(url);
	if (buf == NULL)
		return;

	wps_er_soap_end(buf, "PutMessage", len_ptr, body_ptr);

	ap->http = http_client_addr(&dst, buf, 10000,
				    wps_er_http_put_message_cb, ap);
	if (ap->http == NULL)
		wpabuf_free(buf);
}