From: Victor Julien Date: Tue, 14 Aug 2012 11:49:13 +0000 (+0200) Subject: http: add more decoding unittests. X-Git-Tag: suricata-1.3.1~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ad827ad030c81d30c75341f3946fb2fdbb7682a8;p=thirdparty%2Fsuricata.git http: add more decoding unittests. --- diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index 1e29dc797e..383b8ecad5 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -3888,6 +3888,312 @@ end: return result; } +/** \test Test %2f decoding in profile Apache_2_2 + * + * %2f in path is left untouched + * %2f in query string is normalized to %2F + * %252f in query string is decoded/normalized to %2F + */ +static int HTPParserDecodingTest01(void) +{ + int result = 0; + Flow *f = NULL; + uint8_t httpbuf1[] = + "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" + "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" + "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; + uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ + TcpSession ssn; + + HtpState *htp_state = NULL; + int r = 0; + char input[] = "\ +%YAML 1.1\n\ +---\n\ +libhtp:\n\ +\n\ + default-config:\n\ + personality: Apache_2_2\n\ +"; + + ConfCreateContextBackup(); + ConfInit(); + HtpConfigCreateBackup(); + ConfYamlLoadString(input, strlen(input)); + HTPConfigure(); + char *addr = "4.3.2.1"; + memset(&ssn, 0, sizeof(ssn)); + + f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); + if (f == NULL) + goto end; + f->protoctx = &ssn; + + StreamTcpInitConfig(TRUE); + + uint32_t u; + for (u = 0; u < httplen1; u++) { + uint8_t flags = 0; + + if (u == 0) flags = STREAM_TOSERVER|STREAM_START; + else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; + else flags = STREAM_TOSERVER; + + r = AppLayerParse(NULL, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); + if (r != 0) { + printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" + " 0: ", u, r); + result = 0; + goto end; + } + } + + htp_state = f->alstate; + if (htp_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + uint8_t ref1[] = "/abc%2fdef"; + size_t reflen = sizeof(ref1) - 1; + + htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref1, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref1, reflen); + printf("\": "); + goto end; + } + } + + uint8_t ref2[] = "/abc/def?ghi%2Fjkl"; + reflen = sizeof(ref2) - 1; + + tx = list_get(htp_state->connp->conn->transactions, 1); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref2, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref2, reflen); + printf("\": "); + goto end; + } + } + + uint8_t ref3[] = "/abc/def?ghi%2Fjkl"; + reflen = sizeof(ref2) - 1; + tx = list_get(htp_state->connp->conn->transactions, 2); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref3, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref3, reflen); + printf("\": "); + goto end; + } + } + + result = 1; + +end: + HTPFreeConfig(); + ConfDeInit(); + ConfRestoreContextBackup(); + HtpConfigRestoreBackup(); + + StreamTcpFreeConfig(TRUE); + if (htp_state != NULL) + HTPStateFree(htp_state); + UTHFreeFlow(f); + return result; +} + +/** \test Test %2f decoding in profile IDS + * + * %2f in path decoded to / + * %2f in query string is decoded to / + * %252f in query string is decoded to / + */ +static int HTPParserDecodingTest02(void) +{ + int result = 0; + Flow *f = NULL; + uint8_t httpbuf1[] = + "GET /abc%2fdef HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" + "GET /abc/def?ghi%2fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n" + "GET /abc/def?ghi%252fjkl HTTP/1.1\r\nHost: www.domain.ltd\r\n\r\n"; + uint32_t httplen1 = sizeof(httpbuf1) - 1; /* minus the \0 */ + TcpSession ssn; + + HtpState *htp_state = NULL; + int r = 0; + char input[] = "\ +%YAML 1.1\n\ +---\n\ +libhtp:\n\ +\n\ + default-config:\n\ + personality: IDS\n\ +"; + + ConfCreateContextBackup(); + ConfInit(); + HtpConfigCreateBackup(); + ConfYamlLoadString(input, strlen(input)); + HTPConfigure(); + char *addr = "4.3.2.1"; + memset(&ssn, 0, sizeof(ssn)); + + f = UTHBuildFlow(AF_INET, "1.2.3.4", addr, 1024, 80); + if (f == NULL) + goto end; + f->protoctx = &ssn; + + StreamTcpInitConfig(TRUE); + + uint32_t u; + for (u = 0; u < httplen1; u++) { + uint8_t flags = 0; + + if (u == 0) flags = STREAM_TOSERVER|STREAM_START; + else if (u == (httplen1 - 1)) flags = STREAM_TOSERVER|STREAM_EOF; + else flags = STREAM_TOSERVER; + + r = AppLayerParse(NULL, f, ALPROTO_HTTP, flags, &httpbuf1[u], 1); + if (r != 0) { + printf("toserver chunk %" PRIu32 " returned %" PRId32 ", expected" + " 0: ", u, r); + result = 0; + goto end; + } + } + + htp_state = f->alstate; + if (htp_state == NULL) { + printf("no http state: "); + result = 0; + goto end; + } + + uint8_t ref1[] = "/abc/def"; + size_t reflen = sizeof(ref1) - 1; + + htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, 0); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref1, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref1, reflen); + printf("\": "); + goto end; + } + } + + uint8_t ref2[] = "/abc/def?ghi/jkl"; + reflen = sizeof(ref2) - 1; + + tx = list_get(htp_state->connp->conn->transactions, 1); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref2, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref2, reflen); + printf("\": "); + goto end; + } + } + + uint8_t ref3[] = "/abc/def?ghi/jkl"; + reflen = sizeof(ref2) - 1; + tx = list_get(htp_state->connp->conn->transactions, 2); + if (tx != NULL && tx->request_uri_normalized != NULL) { + if (reflen != bstr_size(tx->request_uri_normalized)) { + printf("normalized uri len should be %"PRIuMAX", is %"PRIuMAX, + (uintmax_t)reflen, + (uintmax_t)bstr_size(tx->request_uri_normalized)); + goto end; + } + + if (memcmp(bstr_ptr(tx->request_uri_normalized), ref3, + bstr_size(tx->request_uri_normalized)) != 0) + { + printf("normalized uri \""); + PrintRawUriFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized), bstr_size(tx->request_uri_normalized)); + printf("\" != \""); + PrintRawUriFp(stdout, ref3, reflen); + printf("\": "); + goto end; + } + } + + result = 1; + +end: + HTPFreeConfig(); + ConfDeInit(); + ConfRestoreContextBackup(); + HtpConfigRestoreBackup(); + + StreamTcpFreeConfig(TRUE); + if (htp_state != NULL) + HTPStateFree(htp_state); + UTHFreeFlow(f); + return result; +} + #endif /* UNITTESTS */ /** @@ -3912,6 +4218,9 @@ void HTPParserRegisterTests(void) { UtRegisterTest("HTPParserConfigTest02", HTPParserConfigTest02, 1); UtRegisterTest("HTPParserConfigTest03", HTPParserConfigTest03, 1); + UtRegisterTest("HTPParserDecodingTest01", HTPParserDecodingTest01, 1); + UtRegisterTest("HTPParserDecodingTest02", HTPParserDecodingTest02, 1); + HTPFileParserRegisterTests(); #endif /* UNITTESTS */ }