/** * Extract one request header. A header can span multiple lines, in * which case they will be folded into one before parsing is attempted. * * @param[in] connp * @param[in] data * @param[in] len * @return HTP_OK or HTP_ERROR */ htp_status_t htp_process_request_header_generic(htp_connp_t *connp, unsigned char *data, size_t len) { // Create a new header structure. htp_header_t *h = calloc(1, sizeof (htp_header_t)); if (h == NULL) return HTP_ERROR; // Now try to parse the header. if (htp_parse_request_header_generic(connp, h, data, len) != HTP_OK) { free(h); return HTP_ERROR; } #ifdef HTP_DEBUG fprint_bstr(stderr, "Header name", h->name); fprint_bstr(stderr, "Header value", h->value); #endif // Do we already have a header with the same name? htp_header_t *h_existing = htp_table_get(connp->in_tx->request_headers, h->name); if (h_existing != NULL) { // TODO Do we want to have a list of the headers that are // allowed to be combined in this way? // Add to the existing header. bstr *new_value = bstr_expand(h_existing->value, bstr_len(h_existing->value) + 2 + bstr_len(h->value)); if (new_value == NULL) { bstr_free(h->name); bstr_free(h->value); free(h); return HTP_ERROR; } h_existing->value = new_value; bstr_add_mem_noex(h_existing->value, ", ", 2); bstr_add_noex(h_existing->value, h->value); // The new header structure is no longer needed. bstr_free(h->name); bstr_free(h->value); free(h); // Keep track of repeated same-name headers. h_existing->flags |= HTP_FIELD_REPEATED; } else { // Add as a new header. htp_table_add(connp->in_tx->request_headers, h->name, h); } return HTP_OK; }
int generate_test_vectors() { FILE *fp; char fileName[MAX_FILE_NAME]; unsigned char msg[MAX_MESSAGE_LENGTH]; unsigned char digest[CRYPTO_BYTES]; int ret_val = KAT_SUCCESS; int count = 1; unsigned long long mlen; init_buffer(msg, sizeof(msg)); sprintf(fileName, "LWC_HASH_KAT_%d.txt", (CRYPTO_BYTES * 8)); if ((fp = fopen(fileName, "w")) == NULL) { fprintf(stderr, "Couldn't open <%s> for write\n", fileName); return KAT_FILE_OPEN_ERROR; } for (mlen = 0; mlen <= MAX_MESSAGE_LENGTH; mlen++) { fprintf(fp, "Count = %d\n", count++); fprint_bstr(fp, "Msg = ", msg, mlen); ret_val = crypto_hash(digest, msg, mlen); if(ret_val != 0) { fprintf(fp, "crypto_hash returned <%d>\n", ret_val); ret_val = KAT_CRYPTO_FAILURE; break; } fprint_bstr(fp, "MD = ", digest, CRYPTO_BYTES); fprintf(fp, "\n"); } fclose(fp); return ret_val; }
/** * Generic response header line(s) processor, which assembles folded lines * into a single buffer before invoking the parsing function. * * @param[in] connp * @param[in] data * @param[in] len * @return HTP status */ htp_status_t htp_process_response_header_generic(htp_connp_t *connp, unsigned char *data, size_t len) { // Create a new header structure. htp_header_t *h = calloc(1, sizeof (htp_header_t)); if (h == NULL) return HTP_ERROR; if (htp_parse_response_header_generic(connp, h, data, len) != HTP_OK) { free(h); return HTP_ERROR; } #ifdef HTP_DEBUG fprint_bstr(stderr, "Header name", h->name); fprint_bstr(stderr, "Header value", h->value); #endif // Do we already have a header with the same name? htp_header_t *h_existing = htp_table_get(connp->out_tx->response_headers, h->name); if (h_existing != NULL) { // Keep track of repeated same-name headers. h_existing->flags |= HTP_FIELD_REPEATED; // Having multiple C-L headers is against the RFC but many // browsers ignore the subsequent headers if the values are the same. if (bstr_cmp_c_nocase(h->name, "Content-Length") == 0) { // Don't use string comparison here because we want to // ignore small formatting differences. int64_t existing_cl, new_cl; existing_cl = htp_parse_content_length(h_existing->value); new_cl = htp_parse_content_length(h->value); if ((existing_cl == -1) || (new_cl == -1) || (existing_cl != new_cl)) { // Ambiguous response C-L value. htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Ambiguous response C-L value"); bstr_free(h->name); bstr_free(h->value); free(h); return HTP_ERROR; } // Ignoring the new C-L header that has the same value as the previous ones. } else { // Add to the existing header. bstr *new_value = bstr_expand(h_existing->value, bstr_len(h_existing->value) + 2 + bstr_len(h->value)); if (new_value == NULL) { bstr_free(h->name); bstr_free(h->value); free(h); return HTP_ERROR; } h_existing->value = new_value; bstr_add_mem_noex(h_existing->value, (unsigned char *) ", ", 2); bstr_add_noex(h_existing->value, h->value); } // The new header structure is no longer needed. bstr_free(h->name); bstr_free(h->value); free(h); } else { // Add as a new header. if (htp_table_add(connp->out_tx->response_headers, h->name, h) != HTP_OK) { bstr_free(h->name); bstr_free(h->value); free(h); return HTP_ERROR; } } return HTP_OK; }