예제 #1
0
static void wps_er_http_req(void *ctx, struct http_request *req)
{
	struct wps_er *er = ctx;
	struct sockaddr_in *cli = http_request_get_cli_addr(req);
	enum httpread_hdr_type type = http_request_get_type(req);
	struct wpabuf *buf;

	wpa_printf(MSG_DEBUG, "WPS ER: HTTP request: '%s' (type %d) from "
		   "%s:%d",
		   http_request_get_uri(req), type,
		   inet_ntoa(cli->sin_addr), ntohs(cli->sin_port));

	switch (type) {
	case HTTPREAD_HDR_TYPE_NOTIFY:
		wps_er_http_notify(er, req);
		break;
	default:
		wpa_printf(MSG_DEBUG, "WPS ER: Unsupported HTTP request type "
			   "%d", type);
		buf = wpabuf_alloc(200);
		if (buf == NULL) {
			http_request_deinit(req);
			return;
		}
		wpabuf_put_str(buf,
			       "HTTP/1.1 501 Unimplemented\r\n"
			       "Connection: close\r\n");
		http_put_date(buf);
		wpabuf_put_str(buf, "\r\n");
		http_request_send_and_deinit(req, buf);
		break;
	}
}
예제 #2
0
static void http_req(void *ctx, struct http_request *req)
{
	struct browser_data *data = ctx;
	struct wpabuf *resp;
	const char *url;
	int done = 0;

	url = http_request_get_uri(req);
	wpa_printf(MSG_INFO, "Browser response received: %s", url);

	if (os_strcmp(url, "/") == 0) {
		data->success = 1;
		done = 1;
	} else if (os_strncmp(url, "/osu/", 5) == 0) {
		data->success = atoi(url + 5);
		done = 1;
	}

	resp = wpabuf_alloc(1);
	if (resp == NULL) {
		http_request_deinit(req);
		if (done)
			eloop_terminate();
		return;
	}

	if (done) {
		eloop_cancel_timeout(browser_timeout, NULL, NULL);
		eloop_register_timeout(0, 500000, browser_timeout, &data, NULL);
	}

	http_request_send_and_deinit(req, resp);
}
예제 #3
0
static void wps_er_http_resp_not_found(struct http_request *req)
{
	struct wpabuf *buf;
	buf = wpabuf_alloc(200);
	if (buf == NULL) {
		http_request_deinit(req);
		return;
	}

	wpabuf_put_str(buf,
		       "HTTP/1.1 404 Not Found\r\n"
		       "Server: unspecified, UPnP/1.0, unspecified\r\n"
		       "Connection: close\r\n");
	http_put_date(buf);
	wpabuf_put_str(buf, "\r\n");
	http_request_send_and_deinit(req, buf);
}
예제 #4
0
static void web_connection_send_reply(struct http_request *req,
				      enum http_reply_code ret,
				      const char *action, int action_len,
				      const struct wpabuf *reply,
				      const char *replyname)
{
	struct wpabuf *buf;
	char *replydata;
	char *put_length_here = NULL;
	char *body_start = NULL;

	if (reply) {
		size_t len;
		replydata = (char *) base64_encode(wpabuf_head(reply),
						   wpabuf_len(reply), &len);
	} else
		replydata = NULL;

	/* Parameters of the response:
	 *      action(action_len) -- action we are responding to
	 *      replyname -- a name we need for the reply
	 *      replydata -- NULL or null-terminated string
	 */
	buf = wpabuf_alloc(1000 + (replydata ? os_strlen(replydata) : 0U) +
			   (action_len > 0 ? action_len * 2 : 0));
	if (buf == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: Cannot allocate reply to "
			   "POST");
		os_free(replydata);
		http_request_deinit(req);
		return;
	}

	/*
	 * Assuming we will be successful, put in the output header first.
	 * Note: we do not keep connections alive (and httpread does
	 * not support it)... therefore we must have Connection: close.
	 */
	if (ret == HTTP_OK) {
		wpabuf_put_str(buf,
			       "HTTP/1.1 200 OK\r\n"
			       "Content-Type: text/xml; "
			       "charset=\"utf-8\"\r\n");
	} else {
		wpabuf_printf(buf, "HTTP/1.1 %d Error\r\n", ret);
	}
	wpabuf_put_str(buf, http_connection_close);

	wpabuf_put_str(buf, "Content-Length: ");
	/*
	 * We will paste the length in later, leaving some extra whitespace.
	 * HTTP code is supposed to be tolerant of extra whitespace.
	 */
	put_length_here = wpabuf_put(buf, 0);
	wpabuf_put_str(buf, "        \r\n");

	http_put_date(buf);

	/* terminating empty line */
	wpabuf_put_str(buf, "\r\n");

	body_start = wpabuf_put(buf, 0);

	if (ret == HTTP_OK) {
		wpabuf_put_str(buf, soap_prefix);
		wpabuf_put_str(buf, "<u:");
		wpabuf_put_data(buf, action, action_len);
		wpabuf_put_str(buf, "Response xmlns:u=\"");
		wpabuf_put_str(buf, urn_wfawlanconfig);
		wpabuf_put_str(buf, "\">\n");
		if (replydata && replyname) {
			/* TODO: might possibly need to escape part of reply
			 * data? ...
			 * probably not, unlikely to have ampersand(&) or left
			 * angle bracket (<) in it...
			 */
			wpabuf_printf(buf, "<%s>", replyname);
			wpabuf_put_str(buf, replydata);
			wpabuf_printf(buf, "</%s>\n", replyname);
		}
		wpabuf_put_str(buf, "</u:");
		wpabuf_put_data(buf, action, action_len);
		wpabuf_put_str(buf, "Response>\n");
		wpabuf_put_str(buf, soap_postfix);
	} else {
		/* Error case */
		wpabuf_put_str(buf, soap_prefix);
		wpabuf_put_str(buf, soap_error_prefix);
		wpabuf_printf(buf, "<errorCode>%d</errorCode>\n", ret);
		wpabuf_put_str(buf, soap_error_postfix);
		wpabuf_put_str(buf, soap_postfix);
	}
	os_free(replydata);

	/* Now patch in the content length at the end */
	if (body_start && put_length_here) {
		int body_length = (char *) wpabuf_put(buf, 0) - body_start;
		char len_buf[10];
		os_snprintf(len_buf, sizeof(len_buf), "%d", body_length);
		os_memcpy(put_length_here, len_buf, os_strlen(len_buf));
	}

	http_request_send_and_deinit(req, buf);
}
예제 #5
0
/* Given that we have received a header w/ GET, act upon it
 *
 * Format of GET (case-insensitive):
 *
 * First line must be:
 *      GET /<file> HTTP/1.1
 * Since we don't do anything fancy we just ignore other lines.
 *
 * Our response (if no error) which includes only required lines is:
 * HTTP/1.1 200 OK
 * Connection: close
 * Content-Type: text/xml
 * Date: <rfc1123-date>
 *
 * Header lines must end with \r\n
 * Per RFC 2616, content-length: is not required but connection:close
 * would appear to be required (given that we will be closing it!).
 */
static void web_connection_parse_get(struct upnp_wps_device_sm *sm,
				     struct http_request *hreq, char *filename)
{
	struct wpabuf *buf; /* output buffer, allocated */
	char *put_length_here;
	char *body_start;
	enum {
		GET_DEVICE_XML_FILE,
		GET_SCPD_XML_FILE
	} req;
	size_t extra_len = 0;
	int body_length;
	char len_buf[10];
	struct upnp_wps_device_interface *iface;

	iface = dl_list_first(&sm->interfaces,
			      struct upnp_wps_device_interface, list);
	if (iface == NULL) {
		http_request_deinit(hreq);
		return;
	}

	/*
	 * It is not required that filenames be case insensitive but it is
	 * allowed and cannot hurt here.
	 */
	if (os_strcasecmp(filename, UPNP_WPS_DEVICE_XML_FILE) == 0) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: HTTP GET for device XML");
		req = GET_DEVICE_XML_FILE;
		extra_len = 3000;
		if (iface->wps->friendly_name)
			extra_len += os_strlen(iface->wps->friendly_name);
		if (iface->wps->manufacturer_url)
			extra_len += os_strlen(iface->wps->manufacturer_url);
		if (iface->wps->model_description)
			extra_len += os_strlen(iface->wps->model_description);
		if (iface->wps->model_url)
			extra_len += os_strlen(iface->wps->model_url);
		if (iface->wps->upc)
			extra_len += os_strlen(iface->wps->upc);
	} else if (!os_strcasecmp(filename, UPNP_WPS_SCPD_XML_FILE)) {
		wpa_printf(MSG_DEBUG, "WPS UPnP: HTTP GET for SCPD XML");
		req = GET_SCPD_XML_FILE;
		extra_len = os_strlen(wps_scpd_xml);
	} else {
		/* File not found */
		wpa_printf(MSG_DEBUG, "WPS UPnP: HTTP GET file not found: %s",
			   filename);
		buf = wpabuf_alloc(200);
		if (buf == NULL) {
			http_request_deinit(hreq);
			return;
		}
		wpabuf_put_str(buf,
			       "HTTP/1.1 404 Not Found\r\n"
			       "Connection: close\r\n");

		http_put_date(buf);

		/* terminating empty line */
		wpabuf_put_str(buf, "\r\n");

		goto send_buf;
	}

	buf = wpabuf_alloc(1000 + extra_len);
	if (buf == NULL) {
		http_request_deinit(hreq);
		return;
	}

	wpabuf_put_str(buf,
		       "HTTP/1.1 200 OK\r\n"
		       "Content-Type: text/xml; charset=\"utf-8\"\r\n");
	wpabuf_put_str(buf, "Server: Unspecified, UPnP/1.0, Unspecified\r\n");
	wpabuf_put_str(buf, "Connection: close\r\n");
	wpabuf_put_str(buf, "Content-Length: ");
	/*
	 * We will paste the length in later, leaving some extra whitespace.
	 * HTTP code is supposed to be tolerant of extra whitespace.
	 */
	put_length_here = wpabuf_put(buf, 0);
	wpabuf_put_str(buf, "        \r\n");

	http_put_date(buf);

	/* terminating empty line */
	wpabuf_put_str(buf, "\r\n");

	body_start = wpabuf_put(buf, 0);

	switch (req) {
	case GET_DEVICE_XML_FILE:
		format_wps_device_xml(iface, sm, buf);
		break;
	case GET_SCPD_XML_FILE:
		wpabuf_put_str(buf, wps_scpd_xml);
		break;
	}

	/* Now patch in the content length at the end */
	body_length = (char *) wpabuf_put(buf, 0) - body_start;
	os_snprintf(len_buf, 10, "%d", body_length);
	os_memcpy(put_length_here, len_buf, os_strlen(len_buf));

send_buf:
	http_request_send_and_deinit(hreq, buf);
}