miniupnpc-libevent: check SID and other headers in event NOTIFY
This commit is contained in:
parent
1b4f132284
commit
e644f219fa
|
@ -431,6 +431,11 @@ static void upnpc_subscribe_response(struct evhttp_request * req, void * pvoid)
|
||||||
struct evkeyvalq * headers = evhttp_request_get_input_headers(req);
|
struct evkeyvalq * headers = evhttp_request_get_input_headers(req);
|
||||||
sid = evhttp_find_header(headers, "sid");
|
sid = evhttp_find_header(headers, "sid");
|
||||||
debug_printf("SID=%s\n", sid);
|
debug_printf("SID=%s\n", sid);
|
||||||
|
if(sid) {
|
||||||
|
if(d->event_conn_sid)
|
||||||
|
free(d->event_conn_sid);
|
||||||
|
d->event_conn_sid = strdup(sid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* ENABLE_UPNP_EVENTS */
|
#endif /* ENABLE_UPNP_EVENTS */
|
||||||
|
@ -639,28 +644,39 @@ void upnpc_event_conn_req(struct evhttp_request * req, void * data)
|
||||||
struct evkeyvalq * headers;
|
struct evkeyvalq * headers;
|
||||||
const char * sid;
|
const char * sid;
|
||||||
const char * nts;
|
const char * nts;
|
||||||
|
const char * nt;
|
||||||
const char * seq;
|
const char * seq;
|
||||||
struct NameValueParserData parsed_data;
|
struct NameValueParserData parsed_data;
|
||||||
struct NameValue * nv;
|
struct NameValue * nv;
|
||||||
upnpc_device_t * d = (upnpc_device_t *)data;
|
upnpc_device_t * d = (upnpc_device_t *)data;
|
||||||
|
|
||||||
debug_printf("%s(%p, %p)\n", __func__, req, d);
|
debug_printf("%s(%p, %p)\n", __func__, req, d);
|
||||||
|
headers = evhttp_request_get_input_headers(req);
|
||||||
input_buffer = evhttp_request_get_input_buffer(req);
|
input_buffer = evhttp_request_get_input_buffer(req);
|
||||||
len = evbuffer_get_length(input_buffer);
|
len = evbuffer_get_length(input_buffer);
|
||||||
if(len == 0) {
|
|
||||||
evhttp_send_reply(req, 406, "Not Acceptable", NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xml_data = (char *)evbuffer_pullup(input_buffer, len);
|
|
||||||
headers = evhttp_request_get_input_headers(req);
|
|
||||||
sid = evhttp_find_header(headers, "sid");
|
sid = evhttp_find_header(headers, "sid");
|
||||||
nts = evhttp_find_header(headers, "nts");
|
nts = evhttp_find_header(headers, "nts");
|
||||||
|
nt = evhttp_find_header(headers, "nt");
|
||||||
seq = evhttp_find_header(headers, "seq");
|
seq = evhttp_find_header(headers, "seq");
|
||||||
|
if(len == 0 || nts == NULL || nt == NULL) {
|
||||||
|
/* 400 Bad request :
|
||||||
|
* The NT or NTS header field is missing
|
||||||
|
* or the request is malformed. */
|
||||||
|
evhttp_send_reply(req, 400, "Bad Request", NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
debug_printf("SID=%s NTS=%s SEQ=%s\n", sid, nts, seq);
|
debug_printf("SID=%s NTS=%s SEQ=%s\n", sid, nts, seq);
|
||||||
if(sid == NULL || nts == NULL || seq == NULL) {
|
if(sid == NULL || 0 != strcmp(sid, d->event_conn_sid)
|
||||||
|
|| 0 != strcmp(nt, "upnp:event") || 0 != strcmp(nts, "upnp:propchange")) {
|
||||||
|
/* 412 Precondition Failed :
|
||||||
|
* An SID does not correspond to a known, un-expired subscription
|
||||||
|
* or the NT header field does not equal upnp:event
|
||||||
|
* or the NTS header field does not equal upnp:propchange
|
||||||
|
* or the SID header field is missing or empty. */
|
||||||
evhttp_send_reply(req, 412, "Precondition Failed", NULL);
|
evhttp_send_reply(req, 412, "Precondition Failed", NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
xml_data = (char *)evbuffer_pullup(input_buffer, len);
|
||||||
/*debug_printf("%.*s\n", len, xml_data);*/
|
/*debug_printf("%.*s\n", len, xml_data);*/
|
||||||
ParseNameValue(xml_data, len, &parsed_data);
|
ParseNameValue(xml_data, len, &parsed_data);
|
||||||
for(nv = parsed_data.l_head; nv != NULL; nv = nv->l_next) {
|
for(nv = parsed_data.l_head; nv != NULL; nv = nv->l_next) {
|
||||||
|
@ -798,6 +814,10 @@ static void upnpc_device_finalize(upnpc_device_t * d)
|
||||||
d->soap_conn = NULL;
|
d->soap_conn = NULL;
|
||||||
}
|
}
|
||||||
ClearNameValueList(&d->soap_response_data);
|
ClearNameValueList(&d->soap_response_data);
|
||||||
|
#ifdef ENABLE_UPNP_EVENTS
|
||||||
|
free(d->event_conn_sid);
|
||||||
|
d->event_conn_sid = NULL;
|
||||||
|
#endif /* ENABLE_UPNP_EVENTS */
|
||||||
}
|
}
|
||||||
|
|
||||||
int upnpc_finalize(upnpc_t * p)
|
int upnpc_finalize(upnpc_t * p)
|
||||||
|
|
|
@ -67,6 +67,9 @@ struct upnpc_device {
|
||||||
struct evhttp_connection * soap_conn;
|
struct evhttp_connection * soap_conn;
|
||||||
struct NameValueParserData soap_response_data;
|
struct NameValueParserData soap_response_data;
|
||||||
unsigned int state;
|
unsigned int state;
|
||||||
|
#ifdef ENABLE_UPNP_EVENTS
|
||||||
|
char * event_conn_sid;
|
||||||
|
#endif /* ENABLE_UPNP_EVENTS */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct upnpc {
|
struct upnpc {
|
||||||
|
|
Loading…
Reference in New Issue