Calculate an md over the incoming HTTP body.

This is calculated while the HTTP body is incoming over the wire, once
the body is fully received the digest will be available for the page
handlers to obtain.

You can obtain a hex string for this md via http_body_digest() or
dereferences the http_request and look at http_body_digest manually
for the bytes.
This commit is contained in:
Joris Vink 2018-07-17 14:53:55 +02:00
parent 9f2759e7b2
commit 616af063e3
2 changed files with 39 additions and 1 deletions

View File

@ -210,6 +210,9 @@ struct http_file {
#define HTTP_VALIDATOR_IS_REQUEST 0x8000
#define HTTP_BODY_DIGEST_LEN 32
#define HTTP_BODY_DIGEST_STRLEN ((HTTP_BODY_DIGEST_LEN * 2) + 1)
struct kore_task;
struct http_request {
@ -226,6 +229,7 @@ struct http_request {
const char *agent;
const char *referer;
struct connection *owner;
SHA256_CTX hashctx;
u_int8_t *headers;
struct kore_buf *http_body;
int http_body_fd;
@ -238,6 +242,8 @@ struct http_request {
char *query_string;
struct kore_module_handle *hdlr;
u_int8_t http_body_digest[HTTP_BODY_DIGEST_LEN];
#if defined(KORE_USE_PYTHON)
void *py_coro;
#endif
@ -293,6 +299,7 @@ void http_process_request(struct http_request *);
int http_body_rewind(struct http_request *);
int http_media_register(const char *, const char *);
ssize_t http_body_read(struct http_request *, void *, size_t);
int http_body_digest(struct http_request *, char *, size_t);
void http_response(struct http_request *, int, const void *, size_t);
void http_response_fileref(struct http_request *, int,
struct kore_fileref *);

View File

@ -762,6 +762,9 @@ http_header_recv(struct netbuf *nb)
(nb->s_off - len));
}
SHA256_Init(&req->hashctx);
SHA256_Update(&req->hashctx, end_headers, (nb->s_off - len));
bytes_left = req->content_length - (nb->s_off - len);
if (bytes_left > 0) {
kore_debug("%ld/%ld (%ld - %ld) more bytes for body",
@ -772,9 +775,10 @@ http_header_recv(struct netbuf *nb)
c->rnb->extra = req;
http_request_sleep(req);
req->content_length = bytes_left;
} else if (bytes_left == 0) {
} else {
req->flags |= HTTP_REQUEST_COMPLETE;
req->flags &= ~HTTP_REQUEST_EXPECT_BODY;
SHA256_Final(req->http_body_digest, &req->hashctx);
if (!http_body_rewind(req)) {
req->flags |= HTTP_REQUEST_DELETE;
http_error_response(req->owner, 500);
@ -1163,6 +1167,30 @@ http_body_rewind(struct http_request *req)
return (KORE_RESULT_OK);
}
int
http_body_digest(struct http_request *req, char *out, size_t len)
{
size_t idx;
int slen;
if (len != HTTP_BODY_DIGEST_STRLEN) {
fatal("http_body_digest: bad len:%zu wanted:%zu",
len, HTTP_BODY_DIGEST_STRLEN);
}
if (!(req->flags & HTTP_REQUEST_COMPLETE))
return (KORE_RESULT_ERROR);
for (idx = 0; idx < sizeof(req->http_body_digest); idx++) {
slen = snprintf(out + (idx * 2), len - (idx * 2), "%02x",
req->http_body_digest[idx]);
if (slen == -1 || (size_t)slen >= len)
fatal("failed to create hex string");
}
return (KORE_RESULT_OK);
}
ssize_t
http_body_read(struct http_request *req, void *out, size_t len)
{
@ -1662,6 +1690,8 @@ http_body_recv(struct netbuf *nb)
u_int64_t bytes_left;
struct http_request *req = (struct http_request *)nb->extra;
SHA256_Update(&req->hashctx, nb->buf, nb->s_off);
if (req->http_body_fd != -1) {
ret = write(req->http_body_fd, nb->buf, nb->s_off);
if (ret == -1 || (size_t)ret != nb->s_off) {
@ -1690,6 +1720,7 @@ http_body_recv(struct netbuf *nb)
http_error_response(req->owner, 500);
return (KORE_RESULT_ERROR);
}
SHA256_Final(req->http_body_digest, &req->hashctx);
net_recv_reset(nb->owner, http_header_max, http_header_recv);
} else {
bytes_left = req->content_length;