Exemplo n.º 1
0
TEST(BstrTest, Alloc) {
    bstr *p1;
    p1 = bstr_alloc(10);
    EXPECT_EQ(10, bstr_size(p1));
    EXPECT_EQ(0, bstr_len(p1));
    bstr_free(p1);
}
Exemplo n.º 2
0
TEST(BstrTest, ExpandSmaller) {
    bstr *p1;
    bstr *p2;

    p1 = bstr_alloc(100);
    p2 = bstr_expand(p1, 10);
    ASSERT_TRUE(p2 == NULL);

    bstr_free(p1);
}
Exemplo n.º 3
0
TEST(BstrTest, ExpandLocal) {
    bstr *p1;
    bstr *p2;

    p1 = bstr_alloc(10);
    p2 = bstr_expand(p1, 100);
    ASSERT_NE(reinterpret_cast<bstr*>(NULL), p2);
    EXPECT_EQ(100, bstr_size(p2));
    EXPECT_EQ(0, bstr_len(p2));

    bstr_free(p2);
}
Exemplo n.º 4
0
TEST(BstrTest, Chop) {
    bstr *p1 = bstr_dup_c("abcdef");
    bstr *p2 = bstr_alloc(10);
    bstr_chop(p1);
    EXPECT_EQ(0, bstr_cmp_c(p1,"abcde"));

    bstr_chop(p2);
    EXPECT_EQ(0, bstr_len(p2));

    bstr_free(p1);
    bstr_free(p2);
}
Exemplo n.º 5
0
TEST(BstrTest, AddMemNoex) {
    bstr *p1;
    bstr *p2;
    p1 = bstr_alloc(10);
    p1 = bstr_add_c(p1, "12345");
    p2 = bstr_add_mem_noex(p1,"abcdefghijklmnop",6);

    EXPECT_EQ(p1,p2);
    EXPECT_EQ(0,bstr_cmp_c(p2,"12345abcde"));

    bstr_free(p1);
}
Exemplo n.º 6
0
TEST(BstrTest, AddNoex) {
    bstr *p1;
    bstr *p2;
    bstr *p3;
    p1 = bstr_alloc(10);
    p1 = bstr_add_c(p1, "12345");
    p2 = bstr_dup_c("abcdef");
    p3 = bstr_add_noex(p1,p2);

    EXPECT_EQ(p1,p3);
    EXPECT_EQ(0,bstr_cmp_c(p3,"12345abcde"));
    bstr_free(p1);
    bstr_free(p2);
}
Exemplo n.º 7
0
bstr *bstr_builder_to_str(const bstr_builder_t *bb) {
    size_t len = 0;

    // Determine the size of the string
    for (size_t i = 0, n = htp_list_size(bb->pieces); i < n; i++) {
        bstr *b = htp_list_get(bb->pieces, i);
        len += bstr_len(b);
    }

    // Allocate string
    bstr *bnew = bstr_alloc(len);
    if (bnew == NULL) return NULL;

    // Determine the size of the string
    for (size_t i = 0, n = htp_list_size(bb->pieces); i < n; i++) {
        bstr *b = htp_list_get(bb->pieces, i);
        bstr_add_noex(bnew, b);
    }

    return bnew;
}
Exemplo n.º 8
0
/**
 * \brief Generates the normalized uri.
 *
 *        Libhtp doesn't recreate the whole normalized uri and save it.
 *        That duty has now been passed to us.  A lot of this code has been
 *        copied from libhtp.
 *
 *        Keep an eye out on the tx->parsed_uri struct and how the parameters
 *        in it are generated, just in case some modifications are made to
 *        them in the future.
 *
 * \param uri_include_all boolean to indicate if scheme, username/password,
                          hostname and port should be part of the buffer
 */
bstr *SCHTPGenerateNormalizedUri(htp_tx_t *tx, htp_uri_t *uri, int uri_include_all)
{
    if (uri == NULL)
        return NULL;

    // On the first pass determine the length of the final string
    size_t len = 0;

    if (uri_include_all) {
        if (uri->scheme != NULL) {
            len += bstr_len(uri->scheme);
            len += 3; // "://"
        }

        if ((uri->username != NULL) || (uri->password != NULL)) {
            if (uri->username != NULL) {
                len += bstr_len(uri->username);
            }

            len += 1; // ":"

            if (uri->password != NULL) {
                len += bstr_len(uri->password);
            }

            len += 1; // "@"
        }

        if (uri->hostname != NULL) {
            len += bstr_len(uri->hostname);
        }

        if (uri->port != NULL) {
            len += 1; // ":"
            len += bstr_len(uri->port);
        }
    }

    if (uri->path != NULL) {
        len += bstr_len(uri->path);
    }

    if (uri->query != NULL) {
        len += 1; // "?"
        len += bstr_len(uri->query);
    }

    if (uri->fragment != NULL) {
        len += 1; // "#"
        len += bstr_len(uri->fragment);
    }

    // On the second pass construct the string
    /* FIXME in memcap */
    bstr *r = bstr_alloc(len);
    if (r == NULL) {
        return NULL;
    }

    if (uri_include_all) {
        if (uri->scheme != NULL) {
            bstr_add_noex(r, uri->scheme);
            bstr_add_c_noex(r, "://");
        }

        if ((uri->username != NULL) || (uri->password != NULL)) {
            if (uri->username != NULL) {
                bstr_add_noex(r, uri->username);
            }

            bstr_add_c_noex(r, ":");

            if (uri->password != NULL) {
                bstr_add_noex(r, uri->password);
            }

            bstr_add_c_noex(r, "@");
        }

        if (uri->hostname != NULL) {
            bstr_add_noex(r, uri->hostname);
        }

        if (uri->port != NULL) {
            bstr_add_c_noex(r, ":");
            bstr_add_noex(r, uri->port);
        }
    }

    if (uri->path != NULL) {
        bstr_add_noex(r, uri->path);
    }

    if (uri->query != NULL) {
        bstr *query = bstr_dup(uri->query);
        if (query) {
            uint64_t flags = 0;
            htp_urldecode_inplace(tx->cfg, HTP_DECODER_URLENCODED, query, &flags);
            bstr_add_c_noex(r, "?");
            bstr_add_noex(r, query);
            bstr_free(query);
        }
    }

    if (uri->fragment != NULL) {
        bstr_add_c_noex(r, "#");
        bstr_add_noex(r, uri->fragment);
    }

    return r;
}
Exemplo n.º 9
0
/**
 * Extract one request header. A header can span multiple lines, in
 * which case they will be folded into one before parsing is attempted.
 *
 * @param connp
 * @return HTP_OK or HTP_ERROR
 */
int htp_process_request_header_apache_2_2(htp_connp_t *connp) {
    bstr *tempstr = NULL;
    unsigned char *data = NULL;
    size_t len = 0;

    // Create new header structure
    htp_header_t *h = calloc(1, sizeof (htp_header_t));
    if (h == NULL) return HTP_ERROR;

    // Ensure we have the necessary header data in a single buffer
    if (connp->in_header_line_index + 1 == connp->in_header_line_counter) {
        // Single line
        htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines,
            connp->in_header_line_index);
        if (hl == NULL) {
            // Internal error
            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
                "Process request header (Apache 2.2): Internal error");
            free(h);
            return HTP_ERROR;
        }

        data = (unsigned char *) bstr_ptr(hl->line);
        len = bstr_len(hl->line);
        hl->header = h;
    } else {
        // Multiple lines (folded)
        int i = 0;

        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
            if (hl == NULL) {
                // Internal error
                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
                        "Process request header (Apache 2.2): Internal error");
                free(h);
                return HTP_ERROR;
            }
            len += bstr_len(hl->line);
        }

        tempstr = bstr_alloc(len);
        if (tempstr == NULL) {
            htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
                "Process request header (Apache 2.2): Failed to allocate bstring of %d bytes", len);
            free(h);
            return HTP_ERROR;
        }

        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
            htp_header_line_t *hl = list_get(connp->in_tx->request_header_lines, i);
            if (hl == NULL) {
                // Internal error
                htp_log(connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0,
                        "Process request header (Apache 2.2): Internal error");
                bstr_free(tempstr);
                free(h);
                return HTP_ERROR;
            }
            char *data = bstr_ptr(hl->line);
            size_t len = bstr_len(hl->line);
            htp_chomp((unsigned char *)data, &len);
            bstr_add_mem_noex(tempstr, data, len);
            hl->header = h;
        }

        data = (unsigned char *) bstr_ptr(tempstr);
    }

    // Now try to parse the header
    if (htp_parse_request_header_apache_2_2(connp, h, data, len) != HTP_OK) {
        // Note: downstream responsible for error logging
        if (tempstr != NULL) {
            free(tempstr);
        }
        free(h);
        return HTP_ERROR;
    }

    // Do we already have a header with the same name?
    htp_header_t *h_existing = table_get(connp->in_tx->request_headers, h->name);
    if (h_existing != NULL) {
        // TODO Do we want to keep a list of the headers that are
        //      allowed to be combined in this way?

        // Add to existing header
        h_existing->value = bstr_expand(h_existing->value, bstr_len(h_existing->value)
            + 2 + bstr_len(h->value));
        bstr_add_mem_noex(h_existing->value, ", ", 2);
        bstr_add_str_noex(h_existing->value, h->value);

        // The header is no longer needed
        if (h->name != NULL)
            free(h->name);
        if (h->value != NULL)
            free(h->value);
        free(h);

        // Keep track of same-name headers        
        h_existing->flags |= HTP_FIELD_REPEATED;
    } else {
        // Add as a new header
        table_add(connp->in_tx->request_headers, h->name, h);
    }

    if (tempstr != NULL) {
        free(tempstr);
    }

    return HTP_OK;
}
Exemplo n.º 10
0
/**
 * 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
 * @return HTP_OK or HTP_ERROR
 */
int htp_process_request_header_generic(htp_connp_t *connp) {
    bstr *tempstr = NULL;
    unsigned char *data = NULL;
    size_t len = 0;

    // Create new header structure
    htp_header_t *h = calloc(1, sizeof (htp_header_t));
    if (h == NULL) {        
        return HTP_ERROR;
    }

    // Ensure we have the necessary header data in a single buffer
    if (connp->in_header_line_index + 1 == connp->in_header_line_counter) {
        // Single line
        htp_header_line_t *hl = htp_list_get(connp->in_tx->request_header_lines,
            connp->in_header_line_index);
        if (hl == NULL) {
            // Internal error            
            free(h);
            return HTP_ERROR;
        }

        data = (unsigned char *)bstr_ptr(hl->line);
        len = bstr_len(hl->line);
        hl->header = h;
    } else {
        // Multiple lines (folded)
        int i = 0;

        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
            htp_header_line_t *hl = htp_list_get(connp->in_tx->request_header_lines, i);
            len += bstr_len(hl->line);
        }

        tempstr = bstr_alloc(len);
        if (tempstr == NULL) {            
            free(h);
            return HTP_ERROR;
        }

        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
            htp_header_line_t *hl = htp_list_get(connp->in_tx->request_header_lines, i);
            unsigned char *line = bstr_ptr(hl->line);
            size_t llen = bstr_len(hl->line);
            htp_chomp((unsigned char *)line, &llen);
            bstr_add_mem_noex(tempstr, line, llen);
            hl->header = h;

            if (i != connp->in_header_line_index) {
                hl->flags |= HTP_FIELD_FOLDED;
            }
        }

        h->flags |= HTP_FIELD_FOLDED;

        data = (unsigned char *)bstr_ptr(tempstr);
        len = bstr_len(tempstr);
    }

    // Now try to parse the header
    if (htp_parse_request_header_generic(connp, h, data, len) != HTP_OK) {
        bstr_free(tempstr);
        free(h);
        return HTP_ERROR;
    }

    // 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) {
        // repeated header
        int i = 0;

        // TODO Do we want to keep a list of the headers that are
        //      allowed to be combined in this way?

        // Add to 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);
            bstr_free(tempstr);
            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);

        // replace the header references in all lines
        for (i = connp->in_header_line_index; i < connp->in_header_line_counter; i++) {
          htp_header_line_t *hl = htp_list_get(connp->in_tx->request_header_lines, i);
          hl->header = h_existing;
        }

        // The header fields are no longer needed
        bstr_free(h->name);
        bstr_free(h->value);
        free(h);

        // Keep track of 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);
    }

    bstr_free(tempstr);

    return HTP_OK;
}