static void http_upload_position(struct evhttp_request *r, const char *remote_host) { struct evbuffer *bufin, *bufout; struct evkeyvalq *req_headers; const char *ctype, *clength; int clength_i; char post[MAX_HTTP_POST_DATA+1]; ev_ssize_t l; char *login_string = NULL; char *packet = NULL; char *username = NULL; char validated; int e; int packet_len; req_headers = evhttp_request_get_input_headers(r); ctype = evhttp_find_header(req_headers, "Content-Type"); if (!ctype || strcasecmp(ctype, "application/octet-stream") != 0) { evhttp_send_error(r, HTTP_BADREQUEST, "Bad request, wrong or missing content-type"); return; } clength = evhttp_find_header(req_headers, "Content-Length"); if (!clength) { evhttp_send_error(r, HTTP_BADREQUEST, "Bad request, missing content-length"); return; } clength_i = atoi(clength); if (clength_i > MAX_HTTP_POST_DATA) { evhttp_send_error(r, HTTP_BADREQUEST, "Bad request, too large body"); return; } /* get the HTTP POST body */ bufin = evhttp_request_get_input_buffer(r); l = evbuffer_copyout(bufin, post, MAX_HTTP_POST_DATA); /* Just for convenience and safety, null-terminate. Easier to log. */ post[MAX_HTTP_POST_DATA] = 0; if (l <= MAX_HTTP_POST_DATA) post[l] = 0; if (l != clength_i) { evhttp_send_error(r, HTTP_BADREQUEST, "Body size does not match content-length"); return; } hlog(LOG_DEBUG, "got post data: %s", post); packet_len = loginpost_split(post, l, &login_string, &packet); if (packet_len == -1) { evhttp_send_error(r, HTTP_BADREQUEST, "No newline (LF) found in data"); return; } if (!login_string) { evhttp_send_error(r, HTTP_BADREQUEST, "No login string in data"); return; } if (!packet) { evhttp_send_error(r, HTTP_BADREQUEST, "No packet data found in data"); return; } hlog(LOG_DEBUG, "login string: %s", login_string); hlog(LOG_DEBUG, "packet: %s", packet); /* process the login string */ validated = http_udp_upload_login(remote_host, login_string, &username, "HTTP POST"); if (validated < 0) { evhttp_send_error(r, HTTP_BADREQUEST, "Invalid login string"); return; } if (validated != 1) { evhttp_send_error(r, 403, "Invalid passcode"); return; } /* packet size limits */ if (packet_len < PACKETLEN_MIN) { evhttp_send_error(r, HTTP_BADREQUEST, "Packet too short"); return; } if (packet_len > PACKETLEN_MAX-2) { evhttp_send_error(r, HTTP_BADREQUEST, "Packet too long"); return; } e = pseudoclient_push_packet(http_worker, http_pseudoclient, username, packet, packet_len); if (e < 0) { hlog(LOG_DEBUG, "http incoming packet parse failure code %d: %s", e, packet); evhttp_send_error(r, HTTP_BADREQUEST, "Packet parsing failure"); return; } bufout = evbuffer_new(); evbuffer_add(bufout, "ok\n", 3); struct evkeyvalq *headers = evhttp_request_get_output_headers(r); http_header_base(headers, 0); evhttp_add_header(headers, "Content-Type", "text/plain; charset=UTF-8"); evhttp_send_reply(r, HTTP_OK, "OK", bufout); evbuffer_free(bufout); }
static void accept_process_udpsubmit(struct listen_t *l, char *buf, int len, char *remote_host) { int packet_len; char *login_string = NULL; char *packet = NULL; char *username = NULL; char validated; int e; //hlog(LOG_DEBUG, "got udp submit: %.*s", len, buf); packet_len = loginpost_split(buf, len, &login_string, &packet); if (packet_len == -1) { hlog(LOG_DEBUG, "UDP submit [%s]: No newline (LF) found in data", remote_host); return; } if (!login_string) { hlog(LOG_DEBUG, "UDP submit [%s]: No login string in data", remote_host); return; } if (!packet) { hlog(LOG_DEBUG, "UDP submit [%s]: No packet data found in data", remote_host); return; } hlog(LOG_DEBUG, "UDP submit [%s]: login string: %s", remote_host, login_string); hlog(LOG_DEBUG, "UDP submit [%s]: packet: %s", remote_host, packet); /* process the login string */ validated = http_udp_upload_login(remote_host, login_string, &username, "UDP submit"); if (validated < 0) { hlog(LOG_DEBUG, "UDP submit [%s]: Invalid login string", remote_host); return; } if (validated != 1) { hlog(LOG_DEBUG, "UDP submit [%s]: Invalid passcode for user %s", remote_host, username); return; } /* packet size limits */ if (packet_len < PACKETLEN_MIN) { hlog(LOG_DEBUG, "UDP submit [%s]: Packet too short: %d bytes", remote_host, packet_len); return; } if (packet_len > PACKETLEN_MAX-2) { hlog(LOG_DEBUG, "UDP submit [%s]: Packet too long: %d bytes", remote_host, packet_len); return; } udp_pseudoclient->portaccount = l->portaccount; e = pseudoclient_push_packet(udp_worker, udp_pseudoclient, username, packet, packet_len); clientaccount_add(udp_pseudoclient, IPPROTO_UDP, len, 1, 0, 0, (e < 0) ? e : 0, 0); udp_pseudoclient->portaccount = NULL; if (e < 0) hlog(LOG_DEBUG, "UDP submit [%s]: Incoming packet parse failure code %d: %s", remote_host, e, packet); else hlog(LOG_DEBUG, "UDP submit [%s]: Incoming packet parsed, code %d: %s", remote_host, e, packet); }