PageRenderTime 228ms CodeModel.GetById 16ms app.highlight 196ms RepoModel.GetById 1ms app.codeStats 1ms

/src/detect-engine-uri.c

https://github.com/decanio/suricata-tilera
C | 3897 lines | 3009 code | 744 blank | 144 comment | 656 complexity | 33c718194613c083cfdf1a14767e0850 MD5 | raw file
   1/* Copyright (C) 2007-2010 Open Information Security Foundation
   2 *
   3 * You can copy, redistribute or modify this Program under the terms of
   4 * the GNU General Public License version 2 as published by the Free
   5 * Software Foundation.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 *
  12 * You should have received a copy of the GNU General Public License
  13 * version 2 along with this program; if not, write to the Free Software
  14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  15 * 02110-1301, USA.
  16 */
  17
  18/** \file
  19 *
  20 *  \author Victor Julien <victor@inliniac.net>
  21 *  \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
  22 *
  23 *  Based on detect-engine-uri.c
  24 */
  25
  26#include "suricata-common.h"
  27#include "suricata.h"
  28#include "decode.h"
  29
  30#include "detect.h"
  31#include "detect-engine.h"
  32#include "detect-parse.h"
  33#include "detect-engine-state.h"
  34#include "detect-engine-content-inspection.h"
  35
  36#include "flow-util.h"
  37#include "util-debug.h"
  38#include "util-print.h"
  39#include "flow.h"
  40
  41#include "app-layer-parser.h"
  42
  43#include "util-unittest.h"
  44#include "util-unittest-helper.h"
  45#include "app-layer.h"
  46#include "app-layer-htp.h"
  47#include "app-layer-protos.h"
  48
  49/** \brief Do the content inspection & validation for a signature
  50 *
  51 *  \param de_ctx Detection engine context
  52 *  \param det_ctx Detection engine thread context
  53 *  \param s Signature to inspect
  54 *  \param sm SigMatch to inspect
  55 *  \param f Flow
  56 *  \param flags app layer flags
  57 *  \param state App layer state
  58 *
  59 *  \retval 0 no match
  60 *  \retval 1 match
  61 */
  62int DetectEngineInspectPacketUris(ThreadVars *tv,
  63                                  DetectEngineCtx *de_ctx,
  64                                  DetectEngineThreadCtx *det_ctx,
  65                                  Signature *s, Flow *f, uint8_t flags,
  66                                  void *alstate, int tx_id)
  67{
  68    HtpState *htp_state = (HtpState *)alstate;
  69
  70    htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
  71    if (tx == NULL || tx->request_uri_normalized == NULL)
  72        return 0;
  73
  74    det_ctx->discontinue_matching = 0;
  75    det_ctx->buffer_offset = 0;
  76    det_ctx->inspection_recursion_counter = 0;
  77
  78    //PrintRawDataFp(stdout, (uint8_t *)bstr_ptr(tx->request_uri_normalized),
  79    //        bstr_len(tx->request_uri_normalized));
  80
  81    /* Inspect all the uricontents fetched on each
  82     * transaction at the app layer */
  83    int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_UMATCH],
  84                                          f,
  85                                          (uint8_t *)bstr_ptr(tx->request_uri_normalized),
  86                                          bstr_len(tx->request_uri_normalized),
  87                                          DETECT_ENGINE_CONTENT_INSPECTION_MODE_URI, NULL);
  88    if (r == 1) {
  89        return 1;
  90    }
  91
  92    return 0;
  93}
  94
  95/***********************************Unittests**********************************/
  96
  97#ifdef UNITTESTS
  98/** \test Test a simple uricontent option */
  99static int UriTestSig01(void)
 100{
 101    int result = 0;
 102    Flow f;
 103    HtpState *http_state = NULL;
 104    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
 105        "User-Agent: Mozilla/1.0\r\n"
 106        "Cookie: hellocatch\r\n\r\n";
 107    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 108    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
 109        "User-Agent: Mozilla/1.0\r\n"
 110        "Cookie: hellocatch\r\n\r\n";
 111    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 112    TcpSession ssn;
 113    Packet *p = NULL;
 114    Signature *s = NULL;
 115    ThreadVars tv;
 116    DetectEngineThreadCtx *det_ctx = NULL;
 117
 118    memset(&tv, 0, sizeof(ThreadVars));
 119    memset(&f, 0, sizeof(Flow));
 120    memset(&ssn, 0, sizeof(TcpSession));
 121
 122    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 123
 124    FLOW_INITIALIZE(&f);
 125    f.protoctx = (void *)&ssn;
 126    f.flags |= FLOW_IPV4;
 127
 128    p->flow = &f;
 129    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 130    p->flowflags |= FLOW_PKT_TOSERVER;
 131    p->flowflags |= FLOW_PKT_ESTABLISHED;
 132    f.alproto = ALPROTO_HTTP;
 133
 134    StreamTcpInitConfig(TRUE);
 135
 136    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 137    if (de_ctx == NULL) {
 138        goto end;
 139    }
 140    de_ctx->mpm_matcher = MPM_B2G;
 141    de_ctx->flags |= DE_QUIET;
 142
 143    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 144                                   "(msg:\"Test uricontent option\"; "
 145                                   "uricontent:\"one\"; sid:1;)");
 146    if (s == NULL) {
 147        goto end;
 148    }
 149
 150    SigGroupBuild(de_ctx);
 151    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 152
 153    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 154    if (r != 0) {
 155        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 156        goto end;
 157    }
 158
 159    http_state = f.alstate;
 160    if (http_state == NULL) {
 161        printf("no http state: ");
 162        goto end;
 163    }
 164
 165    /* do detect */
 166    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 167
 168    if (!PacketAlertCheck(p, 1)) {
 169        printf("sig 1 alerted, but it should not: ");
 170        goto end;
 171    }
 172
 173    DetectEngineStateReset(f.de_state);
 174
 175    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 176    if (r != 0) {
 177        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 178        goto end;
 179    }
 180
 181    http_state = f.alstate;
 182    if (http_state == NULL) {
 183        printf("no http state: ");
 184        goto end;
 185    }
 186
 187    if (!PacketAlertCheck(p, 1)) {
 188        printf("sig 1 alerted, but it should not: ");
 189        goto end;
 190    }
 191
 192    /* do detect */
 193    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 194
 195    result = 1;
 196
 197end:
 198    if (det_ctx != NULL)
 199        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 200    if (de_ctx != NULL)
 201        SigGroupCleanup(de_ctx);
 202    if (de_ctx != NULL)
 203        DetectEngineCtxFree(de_ctx);
 204
 205    StreamTcpFreeConfig(TRUE);
 206    FLOW_DESTROY(&f);
 207    UTHFreePacket(p);
 208    return result;
 209}
 210
 211/** \test Test the pcre /U option */
 212static int UriTestSig02(void)
 213{
 214    int result = 0;
 215    Flow f;
 216    HtpState *http_state = NULL;
 217    uint8_t http_buf1[] = "POST /on HTTP/1.0\r\n"
 218        "User-Agent: Mozilla/1.0\r\n"
 219        "Cookie: hellocatch\r\n\r\n";
 220    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 221    uint8_t http_buf2[] = "POST /one HTTP/1.0\r\n"
 222        "User-Agent: Mozilla/1.0\r\n"
 223        "Cookie: hellocatch\r\n\r\n";
 224    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 225    TcpSession ssn;
 226    Packet *p = NULL;
 227    Signature *s = NULL;
 228    ThreadVars tv;
 229    DetectEngineThreadCtx *det_ctx = NULL;
 230
 231    memset(&tv, 0, sizeof(ThreadVars));
 232    memset(&f, 0, sizeof(Flow));
 233    memset(&ssn, 0, sizeof(TcpSession));
 234
 235    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 236
 237    FLOW_INITIALIZE(&f);
 238    f.protoctx = (void *)&ssn;
 239    f.flags |= FLOW_IPV4;
 240
 241    p->flow = &f;
 242    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 243    p->flowflags |= FLOW_PKT_TOSERVER;
 244    p->flowflags |= FLOW_PKT_ESTABLISHED;
 245    f.alproto = ALPROTO_HTTP;
 246
 247    StreamTcpInitConfig(TRUE);
 248
 249    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 250    if (de_ctx == NULL) {
 251        goto end;
 252    }
 253    de_ctx->mpm_matcher = MPM_B2G;
 254    de_ctx->flags |= DE_QUIET;
 255
 256    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 257                                   "(msg:\"Test pcre /U option\"; "
 258                                   "pcre:/one/U; sid:1;)");
 259    if (s == NULL) {
 260        goto end;
 261    }
 262
 263    SigGroupBuild(de_ctx);
 264    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 265
 266    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 267    if (r != 0) {
 268        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 269        goto end;
 270    }
 271
 272    http_state = f.alstate;
 273    if (http_state == NULL) {
 274        printf("no http state: ");
 275        goto end;
 276    }
 277
 278    /* do detect */
 279    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 280
 281    if (PacketAlertCheck(p, 1)) {
 282        printf("sig 1 alerted with payload2, but it should not: ");
 283        goto end;
 284    }
 285
 286    DetectEngineStateReset(f.de_state);
 287
 288    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 289    if (r != 0) {
 290        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 291        goto end;
 292    }
 293
 294    http_state = f.alstate;
 295    if (http_state == NULL) {
 296        printf("no http state: ");
 297        goto end;
 298    }
 299
 300    /* do detect */
 301    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 302
 303    if (!PacketAlertCheck(p, 1)) {
 304        printf("sig 1 didnt alert, but it should: ");
 305        goto end;
 306    }
 307
 308    result = 1;
 309
 310end:
 311    if (det_ctx != NULL)
 312        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 313    if (de_ctx != NULL)
 314        SigGroupCleanup(de_ctx);
 315    if (de_ctx != NULL)
 316        DetectEngineCtxFree(de_ctx);
 317
 318    StreamTcpFreeConfig(TRUE);
 319    FLOW_DESTROY(&f);
 320    UTHFreePacket(p);
 321    return result;
 322}
 323
 324/** \test Test the pcre /U option */
 325static int UriTestSig03(void)
 326{
 327    int result = 0;
 328    Flow f;
 329    HtpState *http_state = NULL;
 330    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
 331        "User-Agent: Mozilla/1.0\r\n"
 332        "Cookie: hellocatch\r\n\r\n";
 333    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 334    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
 335        "User-Agent: Mozilla/1.0\r\n"
 336        "Cookie: hellocatch\r\n\r\n";
 337    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 338    TcpSession ssn;
 339    Packet *p = NULL;
 340    Signature *s = NULL;
 341    ThreadVars tv;
 342    DetectEngineThreadCtx *det_ctx = NULL;
 343
 344    memset(&tv, 0, sizeof(ThreadVars));
 345    memset(&f, 0, sizeof(Flow));
 346    memset(&ssn, 0, sizeof(TcpSession));
 347
 348    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 349
 350    FLOW_INITIALIZE(&f);
 351    f.protoctx = (void *)&ssn;
 352    f.flags |= FLOW_IPV4;
 353
 354    p->flow = &f;
 355    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 356    p->flowflags |= FLOW_PKT_TOSERVER;
 357    p->flowflags |= FLOW_PKT_ESTABLISHED;
 358    f.alproto = ALPROTO_HTTP;
 359
 360    StreamTcpInitConfig(TRUE);
 361
 362    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 363    if (de_ctx == NULL) {
 364        goto end;
 365    }
 366    de_ctx->mpm_matcher = MPM_B2G;
 367    de_ctx->flags |= DE_QUIET;
 368
 369    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 370                                   "(msg:\"Test pcre /U option\"; "
 371                                   "pcre:/blah/U; sid:1;)");
 372    if (s == NULL) {
 373        goto end;
 374    }
 375
 376    SigGroupBuild(de_ctx);
 377    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 378
 379    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 380    if (r != 0) {
 381        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 382        goto end;
 383    }
 384
 385    http_state = f.alstate;
 386    if (http_state == NULL) {
 387        printf("no http state: ");
 388        goto end;
 389    }
 390
 391    /* do detect */
 392    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 393
 394    if (PacketAlertCheck(p, 1)) {
 395        printf("sig 1 alerted, but it should not: ");
 396        goto end;
 397    }
 398
 399    DetectEngineStateReset(f.de_state);
 400
 401    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 402    if (r != 0) {
 403        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 404        goto end;
 405    }
 406
 407    http_state = f.alstate;
 408    if (http_state == NULL) {
 409        printf("no http state: ");
 410        goto end;
 411    }
 412
 413    /* do detect */
 414    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 415
 416    if (PacketAlertCheck(p, 1)) {
 417        printf("sig 1 alerted, but it should not: ");
 418        goto end;
 419    }
 420
 421    result = 1;
 422
 423end:
 424    if (det_ctx != NULL)
 425        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 426    if (de_ctx != NULL)
 427        SigGroupCleanup(de_ctx);
 428    if (de_ctx != NULL)
 429        DetectEngineCtxFree(de_ctx);
 430
 431    StreamTcpFreeConfig(TRUE);
 432    FLOW_DESTROY(&f);
 433    UTHFreePacket(p);
 434    return result;
 435}
 436
 437/** \test Test the urilen option */
 438static int UriTestSig04(void)
 439{
 440    int result = 0;
 441    Flow f;
 442    HtpState *http_state = NULL;
 443    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
 444        "User-Agent: Mozilla/1.0\r\n"
 445        "Cookie: hellocatch\r\n\r\n";
 446    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 447    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
 448        "User-Agent: Mozilla/1.0\r\n"
 449        "Cookie: hellocatch\r\n\r\n";
 450    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 451    TcpSession ssn;
 452    Packet *p = NULL;
 453    Signature *s = NULL;
 454    ThreadVars tv;
 455    DetectEngineThreadCtx *det_ctx = NULL;
 456
 457    memset(&tv, 0, sizeof(ThreadVars));
 458    memset(&f, 0, sizeof(Flow));
 459    memset(&ssn, 0, sizeof(TcpSession));
 460
 461    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 462
 463    FLOW_INITIALIZE(&f);
 464    f.protoctx = (void *)&ssn;
 465    f.flags |= FLOW_IPV4;
 466
 467    p->flow = &f;
 468    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 469    p->flowflags |= FLOW_PKT_TOSERVER;
 470    p->flowflags |= FLOW_PKT_ESTABLISHED;
 471    f.alproto = ALPROTO_HTTP;
 472
 473    StreamTcpInitConfig(TRUE);
 474
 475    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 476    if (de_ctx == NULL) {
 477        goto end;
 478    }
 479    de_ctx->mpm_matcher = MPM_B2G;
 480    de_ctx->flags |= DE_QUIET;
 481
 482    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 483                                   "(msg:\"Test urilen option\"; "
 484                                   "urilen:>20; sid:1;)");
 485    if (s == NULL) {
 486        goto end;
 487    }
 488
 489    SigGroupBuild(de_ctx);
 490    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 491
 492    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 493    if (r != 0) {
 494        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 495        goto end;
 496    }
 497
 498    http_state = f.alstate;
 499    if (http_state == NULL) {
 500        printf("no http state: ");
 501        goto end;
 502    }
 503
 504    /* do detect */
 505    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 506
 507    if (PacketAlertCheck(p, 1)) {
 508        printf("sig 1 alerted, but it should not: ");
 509        goto end;
 510    }
 511
 512    DetectEngineStateReset(f.de_state);
 513
 514    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 515    if (r != 0) {
 516        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 517        goto end;
 518    }
 519
 520    http_state = f.alstate;
 521    if (http_state == NULL) {
 522        printf("no http state: ");
 523        goto end;
 524    }
 525
 526    /* do detect */
 527    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 528
 529    if (PacketAlertCheck(p, 1)) {
 530        printf("sig 1 alerted, but it should not: ");
 531        goto end;
 532    }
 533
 534    result = 1;
 535
 536end:
 537    if (det_ctx != NULL)
 538        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 539    if (de_ctx != NULL)
 540        SigGroupCleanup(de_ctx);
 541    if (de_ctx != NULL)
 542        DetectEngineCtxFree(de_ctx);
 543
 544    StreamTcpFreeConfig(TRUE);
 545    FLOW_DESTROY(&f);
 546    UTHFreePacket(p);
 547    return result;
 548}
 549
 550/** \test Test the urilen option */
 551static int UriTestSig05(void)
 552{
 553    int result = 0;
 554    Flow f;
 555    HtpState *http_state = NULL;
 556    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
 557        "User-Agent: Mozilla/1.0\r\n"
 558        "Cookie: hellocatch\r\n\r\n";
 559    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 560    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
 561        "User-Agent: Mozilla/1.0\r\n"
 562        "Cookie: hellocatch\r\n\r\n";
 563    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 564    TcpSession ssn;
 565    Packet *p = NULL;
 566    Signature *s = NULL;
 567    ThreadVars tv;
 568    DetectEngineThreadCtx *det_ctx = NULL;
 569
 570    memset(&tv, 0, sizeof(ThreadVars));
 571    memset(&f, 0, sizeof(Flow));
 572    memset(&ssn, 0, sizeof(TcpSession));
 573
 574    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 575
 576    FLOW_INITIALIZE(&f);
 577    f.protoctx = (void *)&ssn;
 578    f.flags |= FLOW_IPV4;
 579
 580    p->flow = &f;
 581    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 582    p->flowflags |= FLOW_PKT_TOSERVER;
 583    p->flowflags |= FLOW_PKT_ESTABLISHED;
 584    f.alproto = ALPROTO_HTTP;
 585
 586    StreamTcpInitConfig(TRUE);
 587
 588    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 589    if (de_ctx == NULL) {
 590        goto end;
 591    }
 592    de_ctx->mpm_matcher = MPM_B2G;
 593    de_ctx->flags |= DE_QUIET;
 594
 595    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 596                                   "(msg:\"Test urilen option\"; "
 597                                   "urilen:>4; sid:1;)");
 598    if (s == NULL) {
 599        goto end;
 600    }
 601
 602    SigGroupBuild(de_ctx);
 603    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 604
 605    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 606    if (r != 0) {
 607        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 608        goto end;
 609    }
 610
 611    http_state = f.alstate;
 612    if (http_state == NULL) {
 613        printf("no http state: ");
 614        goto end;
 615    }
 616
 617    /* do detect */
 618    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 619
 620    if (PacketAlertCheck(p, 1)) {
 621        printf("sig 1 alerted, but it should not: ");
 622        goto end;
 623    }
 624
 625    DetectEngineStateReset(f.de_state);
 626
 627    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 628    if (r != 0) {
 629        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 630        goto end;
 631    }
 632
 633    http_state = f.alstate;
 634    if (http_state == NULL) {
 635        printf("no http state: ");
 636        goto end;
 637    }
 638
 639    /* do detect */
 640    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 641
 642    if (!PacketAlertCheck(p, 1)) {
 643        printf("sig 1 didnt alert with payload2, but it should: ");
 644        goto end;
 645    }
 646
 647    result = 1;
 648
 649end:
 650    if (det_ctx != NULL)
 651        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 652    if (de_ctx != NULL)
 653        SigGroupCleanup(de_ctx);
 654    if (de_ctx != NULL)
 655        DetectEngineCtxFree(de_ctx);
 656
 657    StreamTcpFreeConfig(TRUE);
 658    FLOW_DESTROY(&f);
 659    UTHFreePacket(p);
 660    return result;
 661}
 662
 663/** \test Test the pcre /U option */
 664static int UriTestSig06(void)
 665{
 666    int result = 0;
 667    Flow f;
 668    HtpState *http_state = NULL;
 669    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
 670        "User-Agent: Mozilla/1.0\r\n"
 671        "Cookie: hellocatch\r\n\r\n";
 672    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 673    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
 674        "User-Agent: Mozilla/1.0\r\n"
 675        "Cookie: hellocatch\r\n\r\n";
 676    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 677    TcpSession ssn;
 678    Packet *p = NULL;
 679    Signature *s = NULL;
 680    ThreadVars tv;
 681    DetectEngineThreadCtx *det_ctx = NULL;
 682
 683    memset(&tv, 0, sizeof(ThreadVars));
 684    memset(&f, 0, sizeof(Flow));
 685    memset(&ssn, 0, sizeof(TcpSession));
 686
 687    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 688
 689    FLOW_INITIALIZE(&f);
 690    f.protoctx = (void *)&ssn;
 691    f.flags |= FLOW_IPV4;
 692
 693    p->flow = &f;
 694    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 695    p->flowflags |= FLOW_PKT_TOSERVER;
 696    p->flowflags |= FLOW_PKT_ESTABLISHED;
 697    f.alproto = ALPROTO_HTTP;
 698
 699    StreamTcpInitConfig(TRUE);
 700
 701    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 702    if (de_ctx == NULL) {
 703        goto end;
 704    }
 705    de_ctx->mpm_matcher = MPM_B2G;
 706    de_ctx->flags |= DE_QUIET;
 707
 708    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 709                                   "(msg:\"Test pcre /U option\"; "
 710                                   "pcre:/(oneself)+/U; sid:1;)");
 711    if (s == NULL) {
 712        goto end;
 713    }
 714
 715    SigGroupBuild(de_ctx);
 716    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 717
 718    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 719    if (r != 0) {
 720        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 721        goto end;
 722    }
 723
 724    http_state = f.alstate;
 725    if (http_state == NULL) {
 726        printf("no http state: ");
 727        goto end;
 728    }
 729
 730    /* do detect */
 731    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 732
 733    if (PacketAlertCheck(p, 1)) {
 734        printf("sig 1 alerted, but it should not: ");
 735        goto end;
 736    }
 737
 738    DetectEngineStateReset(f.de_state);
 739
 740    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 741    if (r != 0) {
 742        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 743        goto end;
 744    }
 745
 746    http_state = f.alstate;
 747    if (http_state == NULL) {
 748        printf("no http state: ");
 749        goto end;
 750    }
 751
 752    /* do detect */
 753    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 754
 755    if (!PacketAlertCheck(p, 1)) {
 756        printf("sig 1 didnt alert on payload2, but it should: ");
 757        goto end;
 758    }
 759
 760    result = 1;
 761
 762end:
 763    if (det_ctx != NULL)
 764        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 765    if (de_ctx != NULL)
 766        SigGroupCleanup(de_ctx);
 767    if (de_ctx != NULL)
 768        DetectEngineCtxFree(de_ctx);
 769
 770    StreamTcpFreeConfig(TRUE);
 771    FLOW_DESTROY(&f);
 772    UTHFreePacket(p);
 773    return result;
 774}
 775
 776/** \test Test the pcre /U option in combination with urilen */
 777static int UriTestSig07(void)
 778{
 779    int result = 0;
 780    Flow f;
 781    HtpState *http_state = NULL;
 782    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
 783        "User-Agent: Mozilla/1.0\r\n"
 784        "Cookie: hellocatch\r\n\r\n";
 785    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 786    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
 787        "User-Agent: Mozilla/1.0\r\n"
 788        "Cookie: hellocatch\r\n\r\n";
 789    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 790    TcpSession ssn;
 791    Packet *p = NULL;
 792    Signature *s = NULL;
 793    ThreadVars tv;
 794    DetectEngineThreadCtx *det_ctx = NULL;
 795
 796    memset(&tv, 0, sizeof(ThreadVars));
 797    memset(&f, 0, sizeof(Flow));
 798    memset(&ssn, 0, sizeof(TcpSession));
 799
 800    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 801
 802    FLOW_INITIALIZE(&f);
 803    f.protoctx = (void *)&ssn;
 804    f.flags |= FLOW_IPV4;
 805
 806    p->flow = &f;
 807    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 808    p->flowflags |= FLOW_PKT_TOSERVER;
 809    p->flowflags |= FLOW_PKT_ESTABLISHED;
 810    f.alproto = ALPROTO_HTTP;
 811
 812    StreamTcpInitConfig(TRUE);
 813
 814    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 815    if (de_ctx == NULL) {
 816        goto end;
 817    }
 818    de_ctx->mpm_matcher = MPM_B2G;
 819    de_ctx->flags |= DE_QUIET;
 820
 821    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 822                                   "(msg:\"Test pcre /U option with urilen \"; "
 823                                   "pcre:/(one){2,}(self)?/U; urilen:3<>20; sid:1;)");
 824    if (s == NULL) {
 825        goto end;
 826    }
 827
 828    SigGroupBuild(de_ctx);
 829    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 830
 831    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 832    if (r != 0) {
 833        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 834        goto end;
 835    }
 836
 837    http_state = f.alstate;
 838    if (http_state == NULL) {
 839        printf("no http state: ");
 840        goto end;
 841    }
 842
 843    /* do detect */
 844    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 845
 846    if (!PacketAlertCheck(p, 1)) {
 847        printf("sig 1 didnt alert, but it should: ");
 848        goto end;
 849    }
 850
 851    DetectEngineStateReset(f.de_state);
 852
 853    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 854    if (r != 0) {
 855        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 856        goto end;
 857    }
 858
 859    http_state = f.alstate;
 860    if (http_state == NULL) {
 861        printf("no http state: ");
 862        goto end;
 863    }
 864
 865    /* do detect */
 866    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 867
 868    if (!PacketAlertCheck(p, 1)) {
 869        printf("sig 1 didnt alert with payload2, but it should: ");
 870        goto end;
 871    }
 872
 873    result = 1;
 874
 875end:
 876    if (det_ctx != NULL)
 877        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 878    if (de_ctx != NULL)
 879        SigGroupCleanup(de_ctx);
 880    if (de_ctx != NULL)
 881        DetectEngineCtxFree(de_ctx);
 882
 883    StreamTcpFreeConfig(TRUE);
 884    FLOW_DESTROY(&f);
 885    UTHFreePacket(p);
 886    return result;
 887}
 888
 889/** \test Test the pcre /U option in combination with urilen */
 890static int UriTestSig08(void)
 891{
 892    int result = 0;
 893    Flow f;
 894    HtpState *http_state = NULL;
 895    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
 896        "User-Agent: Mozilla/1.0\r\n"
 897        "Cookie: hellocatch\r\n\r\n";
 898    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
 899    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
 900        "User-Agent: Mozilla/1.0\r\n"
 901        "Cookie: hellocatch\r\n\r\n";
 902    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
 903    TcpSession ssn;
 904    Packet *p = NULL;
 905    Signature *s = NULL;
 906    ThreadVars tv;
 907    DetectEngineThreadCtx *det_ctx = NULL;
 908
 909    memset(&tv, 0, sizeof(ThreadVars));
 910    memset(&f, 0, sizeof(Flow));
 911    memset(&ssn, 0, sizeof(TcpSession));
 912
 913    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
 914
 915    FLOW_INITIALIZE(&f);
 916    f.protoctx = (void *)&ssn;
 917    f.flags |= FLOW_IPV4;
 918
 919    p->flow = &f;
 920    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 921    p->flowflags |= FLOW_PKT_TOSERVER;
 922    p->flowflags |= FLOW_PKT_ESTABLISHED;
 923    f.alproto = ALPROTO_HTTP;
 924
 925    StreamTcpInitConfig(TRUE);
 926
 927    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
 928    if (de_ctx == NULL) {
 929        goto end;
 930    }
 931    de_ctx->mpm_matcher = MPM_B2G;
 932    de_ctx->flags |= DE_QUIET;
 933
 934    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
 935                                   "(msg:\"Test pcre /U option with urilen\"; "
 936                                   "pcre:/(blabla){2,}(self)?/U; urilen:3<>20; sid:1;)");
 937    if (s == NULL) {
 938        goto end;
 939    }
 940
 941    SigGroupBuild(de_ctx);
 942    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
 943
 944    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
 945    if (r != 0) {
 946        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 947        goto end;
 948    }
 949
 950    http_state = f.alstate;
 951    if (http_state == NULL) {
 952        printf("no http state: ");
 953        goto end;
 954    }
 955
 956    /* do detect */
 957    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 958
 959    if (PacketAlertCheck(p, 1)) {
 960        printf("sig 1 alerted, but it should not: ");
 961        goto end;
 962    }
 963
 964    DetectEngineStateReset(f.de_state);
 965
 966    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
 967    if (r != 0) {
 968        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 969        goto end;
 970    }
 971
 972    http_state = f.alstate;
 973    if (http_state == NULL) {
 974        printf("no http state: ");
 975        goto end;
 976    }
 977
 978    /* do detect */
 979    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
 980
 981    if (PacketAlertCheck(p, 1)) {
 982        printf("sig 1 alerted, but it should not: ");
 983        goto end;
 984    }
 985
 986    result = 1;
 987
 988end:
 989    if (det_ctx != NULL)
 990        DetectEngineThreadCtxDeinit(&tv, det_ctx);
 991    if (de_ctx != NULL)
 992        SigGroupCleanup(de_ctx);
 993    if (de_ctx != NULL)
 994        DetectEngineCtxFree(de_ctx);
 995
 996    StreamTcpFreeConfig(TRUE);
 997    FLOW_DESTROY(&f);
 998    UTHFreePacket(p);
 999    return result;
1000}
1001
1002/** \test Test the pcre /U option in combination with urilen */
1003static int UriTestSig09(void)
1004{
1005    int result = 0;
1006    Flow f;
1007    HtpState *http_state = NULL;
1008    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
1009        "User-Agent: Mozilla/1.0\r\n"
1010        "Cookie: hellocatch\r\n\r\n";
1011    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1012    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
1013        "User-Agent: Mozilla/1.0\r\n"
1014        "Cookie: hellocatch\r\n\r\n";
1015    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1016    TcpSession ssn;
1017    Packet *p = NULL;
1018    Signature *s = NULL;
1019    ThreadVars tv;
1020    DetectEngineThreadCtx *det_ctx = NULL;
1021
1022    memset(&tv, 0, sizeof(ThreadVars));
1023    memset(&f, 0, sizeof(Flow));
1024    memset(&ssn, 0, sizeof(TcpSession));
1025
1026    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1027
1028    FLOW_INITIALIZE(&f);
1029    f.protoctx = (void *)&ssn;
1030    f.flags |= FLOW_IPV4;
1031
1032    p->flow = &f;
1033    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1034    p->flowflags |= FLOW_PKT_TOSERVER;
1035    p->flowflags |= FLOW_PKT_ESTABLISHED;
1036    f.alproto = ALPROTO_HTTP;
1037
1038    StreamTcpInitConfig(TRUE);
1039
1040    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1041    if (de_ctx == NULL) {
1042        goto end;
1043    }
1044    de_ctx->mpm_matcher = MPM_B2G;
1045    de_ctx->flags |= DE_QUIET;
1046
1047    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1048                                   "(msg:\"Test pcre /U option with urilen \"; "
1049                                   "pcre:/(one){2,}(self)?/U; urilen:<2; sid:1;)");
1050    if (s == NULL) {
1051        goto end;
1052    }
1053
1054    SigGroupBuild(de_ctx);
1055    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1056
1057    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1058    if (r != 0) {
1059        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1060        goto end;
1061    }
1062
1063    http_state = f.alstate;
1064    if (http_state == NULL) {
1065        printf("no http state: ");
1066        goto end;
1067    }
1068
1069    /* do detect */
1070    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1071
1072    if (PacketAlertCheck(p, 1)) {
1073        printf("sig 1 alerted, but it should not: ");
1074        goto end;
1075    }
1076
1077    DetectEngineStateReset(f.de_state);
1078
1079    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1080    if (r != 0) {
1081        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1082        goto end;
1083    }
1084
1085    http_state = f.alstate;
1086    if (http_state == NULL) {
1087        printf("no http state: ");
1088        goto end;
1089    }
1090
1091    /* do detect */
1092    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1093
1094    if (PacketAlertCheck(p, 1)) {
1095        printf("sig 1 alerted, but it should not: ");
1096        goto end;
1097    }
1098
1099    result = 1;
1100
1101end:
1102    if (det_ctx != NULL)
1103        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1104    if (de_ctx != NULL)
1105        SigGroupCleanup(de_ctx);
1106    if (de_ctx != NULL)
1107        DetectEngineCtxFree(de_ctx);
1108
1109    StreamTcpFreeConfig(TRUE);
1110    FLOW_DESTROY(&f);
1111    UTHFreePacket(p);
1112    return result;
1113}
1114
1115/** \test Test the uricontent option in combination with urilen */
1116static int UriTestSig10(void)
1117{
1118    int result = 0;
1119    Flow f;
1120    HtpState *http_state = NULL;
1121    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
1122        "User-Agent: Mozilla/1.0\r\n"
1123        "Cookie: hellocatch\r\n\r\n";
1124    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1125    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
1126        "User-Agent: Mozilla/1.0\r\n"
1127        "Cookie: hellocatch\r\n\r\n";
1128    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1129    TcpSession ssn;
1130    Packet *p = NULL;
1131    Signature *s = NULL;
1132    ThreadVars tv;
1133    DetectEngineThreadCtx *det_ctx = NULL;
1134
1135    memset(&tv, 0, sizeof(ThreadVars));
1136    memset(&f, 0, sizeof(Flow));
1137    memset(&ssn, 0, sizeof(TcpSession));
1138
1139    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1140
1141    FLOW_INITIALIZE(&f);
1142    f.protoctx = (void *)&ssn;
1143    f.flags |= FLOW_IPV4;
1144
1145    p->flow = &f;
1146    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1147    p->flowflags |= FLOW_PKT_TOSERVER;
1148    p->flowflags |= FLOW_PKT_ESTABLISHED;
1149    f.alproto = ALPROTO_HTTP;
1150
1151    StreamTcpInitConfig(TRUE);
1152
1153    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1154    if (de_ctx == NULL) {
1155        goto end;
1156    }
1157    de_ctx->mpm_matcher = MPM_B2G;
1158    de_ctx->flags |= DE_QUIET;
1159
1160    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1161                                   "(msg:\"Test uricontent with urilen option\"; "
1162                                   "uricontent:\"one\"; urilen:<2; sid:1;)");
1163    if (s == NULL) {
1164        goto end;
1165    }
1166
1167    SigGroupBuild(de_ctx);
1168    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1169
1170    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1171    if (r != 0) {
1172        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1173        goto end;
1174    }
1175
1176    http_state = f.alstate;
1177    if (http_state == NULL) {
1178        printf("no http state: ");
1179        goto end;
1180    }
1181
1182    /* do detect */
1183    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1184
1185    if (PacketAlertCheck(p, 1)) {
1186        printf("sig 1 alerted, but it should not: ");
1187        goto end;
1188    }
1189
1190    DetectEngineStateReset(f.de_state);
1191
1192    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1193    if (r != 0) {
1194        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1195        goto end;
1196    }
1197
1198    http_state = f.alstate;
1199    if (http_state == NULL) {
1200        printf("no http state: ");
1201        goto end;
1202    }
1203
1204    /* do detect */
1205    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1206
1207    if (PacketAlertCheck(p, 1)) {
1208        printf("sig 1 alerted, but it should not: ");
1209        goto end;
1210    }
1211
1212    result = 1;
1213
1214end:
1215    if (det_ctx != NULL)
1216        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1217    if (de_ctx != NULL)
1218        SigGroupCleanup(de_ctx);
1219    if (de_ctx != NULL)
1220        DetectEngineCtxFree(de_ctx);
1221
1222    StreamTcpFreeConfig(TRUE);
1223    FLOW_DESTROY(&f);
1224    UTHFreePacket(p);
1225    return result;
1226}
1227
1228/** \test Test content, uricontent, urilen, pcre /U options */
1229static int UriTestSig11(void)
1230{
1231    int result = 0;
1232    Flow f;
1233    HtpState *http_state = NULL;
1234    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
1235        "User-Agent: Mozilla/1.0\r\n"
1236        "Cookie: hellocatch\r\n\r\n";
1237    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1238    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
1239        "User-Agent: Mozilla/1.0\r\n"
1240        "Cookie: hellocatch\r\n\r\n";
1241    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1242    TcpSession ssn;
1243    Packet *p = NULL;
1244    Signature *s = NULL;
1245    ThreadVars tv;
1246    DetectEngineThreadCtx *det_ctx = NULL;
1247
1248    memset(&tv, 0, sizeof(ThreadVars));
1249    memset(&f, 0, sizeof(Flow));
1250    memset(&ssn, 0, sizeof(TcpSession));
1251
1252    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1253
1254    FLOW_INITIALIZE(&f);
1255    f.protoctx = (void *)&ssn;
1256    f.flags |= FLOW_IPV4;
1257
1258    p->flow = &f;
1259    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1260    p->flowflags |= FLOW_PKT_TOSERVER;
1261    p->flowflags |= FLOW_PKT_ESTABLISHED;
1262    f.alproto = ALPROTO_HTTP;
1263
1264    StreamTcpInitConfig(TRUE);
1265
1266    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1267    if (de_ctx == NULL) {
1268        goto end;
1269    }
1270    de_ctx->mpm_matcher = MPM_B2G;
1271    de_ctx->flags |= DE_QUIET;
1272
1273    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1274                                   "(msg:\"Test content, uricontent, pcre /U and urilen options\"; "
1275                                   "content:\"one\"; uricontent:\"one\"; pcre:/(one){2,}(self)?/U;"
1276                                   "urilen:<2; sid:1;)");
1277    if (s == NULL) {
1278        goto end;
1279    }
1280
1281    SigGroupBuild(de_ctx);
1282    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1283
1284    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1285    if (r != 0) {
1286        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1287        goto end;
1288    }
1289
1290    http_state = f.alstate;
1291    if (http_state == NULL) {
1292        printf("no http state: ");
1293        goto end;
1294    }
1295
1296    /* do detect */
1297    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1298
1299    if (PacketAlertCheck(p, 1)) {
1300        printf("sig 1 alerted, but it should not: ");
1301        goto end;
1302    }
1303
1304    DetectEngineStateReset(f.de_state);
1305
1306    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1307    if (r != 0) {
1308        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1309        goto end;
1310    }
1311
1312    http_state = f.alstate;
1313    if (http_state == NULL) {
1314        printf("no http state: ");
1315        goto end;
1316    }
1317
1318    /* do detect */
1319    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1320
1321    if (PacketAlertCheck(p, 1)) {
1322        printf("sig 1 alerted, but it should not: ");
1323        goto end;
1324    }
1325
1326    result = 1;
1327
1328end:
1329    if (det_ctx != NULL)
1330        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1331    if (de_ctx != NULL)
1332        SigGroupCleanup(de_ctx);
1333    if (de_ctx != NULL)
1334        DetectEngineCtxFree(de_ctx);
1335
1336    StreamTcpFreeConfig(TRUE);
1337    FLOW_DESTROY(&f);
1338    UTHFreePacket(p);
1339    return result;
1340}
1341
1342/** \test Test uricontent, urilen, pcre /U options */
1343static int UriTestSig12(void)
1344{
1345    int result = 0;
1346    Flow f;
1347    HtpState *http_state = NULL;
1348    uint8_t http_buf1[] = "POST /oneoneoneone HTTP/1.0\r\n"
1349        "User-Agent: Mozilla/1.0\r\n"
1350        "Cookie: hellocatch\r\n\r\n";
1351    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1352    uint8_t http_buf2[] = "POST /oneoneself HTTP/1.0\r\n"
1353        "User-Agent: Mozilla/1.0\r\n"
1354        "Cookie: hellocatch\r\n\r\n";
1355    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1356    TcpSession ssn;
1357    Packet *p = NULL;
1358    Signature *s = NULL;
1359    ThreadVars tv;
1360    DetectEngineThreadCtx *det_ctx = NULL;
1361
1362    memset(&tv, 0, sizeof(ThreadVars));
1363    memset(&f, 0, sizeof(Flow));
1364    memset(&ssn, 0, sizeof(TcpSession));
1365
1366    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1367
1368    FLOW_INITIALIZE(&f);
1369    f.protoctx = (void *)&ssn;
1370    f.flags |= FLOW_IPV4;
1371
1372    p->flow = &f;
1373    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1374    p->flowflags |= FLOW_PKT_TOSERVER;
1375    p->flowflags |= FLOW_PKT_ESTABLISHED;
1376    f.alproto = ALPROTO_HTTP;
1377
1378    StreamTcpInitConfig(TRUE);
1379
1380    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1381    if (de_ctx == NULL) {
1382        goto end;
1383    }
1384    de_ctx->mpm_matcher = MPM_B2G;
1385    de_ctx->flags |= DE_QUIET;
1386
1387    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1388                                   "(msg:\"Test pcre /U, uricontent and urilen option\"; "
1389                                   "uricontent:\"one\"; "
1390                                   "pcre:/(one)+self/U; urilen:>2; sid:1;)");
1391    if (s == NULL) {
1392        goto end;
1393    }
1394
1395    SigGroupBuild(de_ctx);
1396    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1397
1398    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1399    if (r != 0) {
1400        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1401        goto end;
1402    }
1403
1404    http_state = f.alstate;
1405    if (http_state == NULL) {
1406        printf("no http state: ");
1407        goto end;
1408    }
1409
1410    /* do detect */
1411    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1412
1413    if (PacketAlertCheck(p, 1)) {
1414        printf("sig 1 alerted, but it should not: ");
1415        goto end;
1416    }
1417
1418    DetectEngineStateReset(f.de_state);
1419
1420    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1421    if (r != 0) {
1422        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1423        goto end;
1424    }
1425
1426    http_state = f.alstate;
1427    if (http_state == NULL) {
1428        printf("no http state: ");
1429        goto end;
1430    }
1431
1432    /* do detect */
1433    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1434
1435    if (!PacketAlertCheck(p, 1)) {
1436        printf("sig 1 didnt alert with payload2, but it should: ");
1437        goto end;
1438    }
1439
1440    result = 1;
1441
1442end:
1443    if (det_ctx != NULL)
1444        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1445    if (de_ctx != NULL)
1446        SigGroupCleanup(de_ctx);
1447    if (de_ctx != NULL)
1448        DetectEngineCtxFree(de_ctx);
1449
1450    StreamTcpFreeConfig(TRUE);
1451    FLOW_DESTROY(&f);
1452    UTHFreePacket(p);
1453    return result;
1454}
1455
1456/** \test Test uricontent, urilen */
1457static int UriTestSig13(void)
1458{
1459    int result = 0;
1460    Flow f;
1461    HtpState *http_state = NULL;
1462    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
1463        "User-Agent: Mozilla/1.0\r\n"
1464        "Cookie: hellocatch\r\n\r\n";
1465    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1466    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
1467        "User-Agent: Mozilla/1.0\r\n"
1468        "Cookie: hellocatch\r\n\r\n";
1469    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1470    TcpSession ssn;
1471    Packet *p = NULL;
1472    Signature *s = NULL;
1473    ThreadVars tv;
1474    DetectEngineThreadCtx *det_ctx = NULL;
1475
1476    memset(&tv, 0, sizeof(ThreadVars));
1477    memset(&f, 0, sizeof(Flow));
1478    memset(&ssn, 0, sizeof(TcpSession));
1479
1480    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1481
1482    FLOW_INITIALIZE(&f);
1483    f.protoctx = (void *)&ssn;
1484    f.flags |= FLOW_IPV4;
1485
1486    p->flow = &f;
1487    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1488    p->flowflags |= FLOW_PKT_TOSERVER;
1489    p->flowflags |= FLOW_PKT_ESTABLISHED;
1490    f.alproto = ALPROTO_HTTP;
1491
1492    StreamTcpInitConfig(TRUE);
1493
1494    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1495    if (de_ctx == NULL) {
1496        goto end;
1497    }
1498    de_ctx->mpm_matcher = MPM_B2G;
1499    de_ctx->flags |= DE_QUIET;
1500
1501    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1502                                   "(msg:\"Test urilen option\"; "
1503                                   "urilen:>2; uricontent:\"one\"; sid:1;)");
1504    if (s == NULL) {
1505        goto end;
1506    }
1507
1508    SigGroupBuild(de_ctx);
1509    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1510
1511    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1512    if (r != 0) {
1513        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1514        goto end;
1515    }
1516
1517    http_state = f.alstate;
1518    if (http_state == NULL) {
1519        printf("no http state: ");
1520        goto end;
1521    }
1522
1523    /* do detect */
1524    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1525
1526    if (!PacketAlertCheck(p, 1)) {
1527        printf("sig 1 didnt alert with pkt, but it should: ");
1528        goto end;
1529    }
1530
1531    DetectEngineStateReset(f.de_state);
1532
1533    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1534    if (r != 0) {
1535        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1536        goto end;
1537    }
1538
1539    http_state = f.alstate;
1540    if (http_state == NULL) {
1541        printf("no http state: ");
1542        goto end;
1543    }
1544
1545    /* do detect */
1546    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1547
1548
1549    if (!PacketAlertCheck(p, 1)) {
1550        printf("sig 1 didnt alert with payload2, but it should: ");
1551        goto end;
1552    }
1553
1554    result = 1;
1555
1556end:
1557    if (det_ctx != NULL)
1558        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1559    if (de_ctx != NULL)
1560        SigGroupCleanup(de_ctx);
1561    if (de_ctx != NULL)
1562        DetectEngineCtxFree(de_ctx);
1563
1564    StreamTcpFreeConfig(TRUE);
1565    FLOW_DESTROY(&f);
1566    UTHFreePacket(p);
1567    return result;
1568}
1569
1570/** \test Test uricontent, pcre /U */
1571static int UriTestSig14(void)
1572{
1573    int result = 0;
1574    Flow f;
1575    HtpState *http_state = NULL;
1576    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
1577        "User-Agent: Mozilla/1.0\r\n"
1578        "Cookie: hellocatch\r\n\r\n";
1579    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1580    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
1581        "User-Agent: Mozilla/1.0\r\n"
1582        "Cookie: hellocatch\r\n\r\n";
1583    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1584    TcpSession ssn;
1585    Packet *p = NULL;
1586    Signature *s = NULL;
1587    ThreadVars tv;
1588    DetectEngineThreadCtx *det_ctx = NULL;
1589
1590    memset(&tv, 0, sizeof(ThreadVars));
1591    memset(&f, 0, sizeof(Flow));
1592    memset(&ssn, 0, sizeof(TcpSession));
1593
1594    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1595
1596    FLOW_INITIALIZE(&f);
1597    f.protoctx = (void *)&ssn;
1598    f.flags |= FLOW_IPV4;
1599
1600    p->flow = &f;
1601    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1602    p->flowflags |= FLOW_PKT_TOSERVER;
1603    p->flowflags |= FLOW_PKT_ESTABLISHED;
1604    f.alproto = ALPROTO_HTTP;
1605
1606    StreamTcpInitConfig(TRUE);
1607
1608    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1609    if (de_ctx == NULL) {
1610        goto end;
1611    }
1612    de_ctx->mpm_matcher = MPM_B2G;
1613    de_ctx->flags |= DE_QUIET;
1614
1615    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1616                                   "(msg:\"Test uricontent option\"; "
1617                                   "uricontent:\"one\"; pcre:/one(self)?/U;sid:1;)");
1618    if (s == NULL) {
1619        goto end;
1620    }
1621
1622    SigGroupBuild(de_ctx);
1623    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1624
1625    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1626    if (r != 0) {
1627        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1628        goto end;
1629    }
1630
1631    http_state = f.alstate;
1632    if (http_state == NULL) {
1633        printf("no http state: ");
1634        goto end;
1635    }
1636
1637    /* do detect */
1638    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1639
1640    if (!PacketAlertCheck(p, 1)) {
1641        printf("sig 1 didnt alert with pkt, but it should: ");
1642        goto end;
1643    }
1644
1645    DetectEngineStateReset(f.de_state);
1646
1647    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1648    if (r != 0) {
1649        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1650        goto end;
1651    }
1652
1653    http_state = f.alstate;
1654    if (http_state == NULL) {
1655        printf("no http state: ");
1656        goto end;
1657    }
1658
1659    /* do detect */
1660    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1661
1662
1663    if (!PacketAlertCheck(p, 1)) {
1664        printf("sig 1 didnt alert with payload2, but it should: ");
1665        goto end;
1666    }
1667
1668    result = 1;
1669
1670end:
1671    if (det_ctx != NULL)
1672        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1673    if (de_ctx != NULL)
1674        SigGroupCleanup(de_ctx);
1675    if (de_ctx != NULL)
1676        DetectEngineCtxFree(de_ctx);
1677
1678    StreamTcpFreeConfig(TRUE);
1679    FLOW_DESTROY(&f);
1680    UTHFreePacket(p);
1681    return result;
1682}
1683
1684/** \test Test pcre /U with anchored regex (bug 155) */
1685static int UriTestSig15(void)
1686{
1687    int result = 0;
1688    Flow f;
1689    HtpState *http_state = NULL;
1690    uint8_t http_buf1[] = "POST /one HTTP/1.0\r\n"
1691        "User-Agent: Mozilla/1.0\r\n"
1692        "Cookie: hellocatch\r\n\r\n";
1693    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1694    uint8_t http_buf2[] = "POST /oneself HTTP/1.0\r\n"
1695        "User-Agent: Mozilla/1.0\r\n"
1696        "Cookie: hellocatch\r\n\r\n";
1697    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1698    TcpSession ssn;
1699    Packet *p = NULL;
1700    Signature *s = NULL;
1701    ThreadVars tv;
1702    DetectEngineThreadCtx *det_ctx = NULL;
1703
1704    memset(&tv, 0, sizeof(ThreadVars));
1705    memset(&f, 0, sizeof(Flow));
1706    memset(&ssn, 0, sizeof(TcpSession));
1707
1708    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1709
1710    FLOW_INITIALIZE(&f);
1711    f.protoctx = (void *)&ssn;
1712    f.flags |= FLOW_IPV4;
1713
1714    p->flow = &f;
1715    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1716    p->flowflags |= FLOW_PKT_TOSERVER;
1717    p->flowflags |= FLOW_PKT_ESTABLISHED;
1718    f.alproto = ALPROTO_HTTP;
1719
1720    StreamTcpInitConfig(TRUE);
1721
1722    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1723    if (de_ctx == NULL) {
1724        goto end;
1725    }
1726    de_ctx->mpm_matcher = MPM_B2G;
1727    de_ctx->flags |= DE_QUIET;
1728
1729    s = de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1730                                   "(msg:\"Test uricontent option\"; "
1731                                   "uricontent:\"one\"; pcre:/^\\/one(self)?$/U;sid:1;)");
1732    if (s == NULL) {
1733        goto end;
1734    }
1735
1736    SigGroupBuild(de_ctx);
1737    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1738
1739    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1740    if (r != 0) {
1741        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1742        goto end;
1743    }
1744
1745    http_state = f.alstate;
1746    if (http_state == NULL) {
1747        printf("no http state: ");
1748        goto end;
1749    }
1750
1751    /* do detect */
1752    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1753
1754    if (!PacketAlertCheck(p, 1)) {
1755        printf("sig 1 didnt alert with pkt, but it should: ");
1756        goto end;
1757    }
1758
1759    DetectEngineStateReset(f.de_state);
1760
1761    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1762    if (r != 0) {
1763        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1764        goto end;
1765    }
1766
1767    http_state = f.alstate;
1768    if (http_state == NULL) {
1769        printf("no http state: ");
1770        goto end;
1771    }
1772
1773    /* do detect */
1774    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1775
1776
1777    if (!PacketAlertCheck(p, 1)) {
1778        printf("sig 1 didnt alert with payload2, but it should: ");
1779        goto end;
1780    }
1781
1782    result = 1;
1783
1784end:
1785    if (det_ctx != NULL)
1786        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1787    if (de_ctx != NULL)
1788        SigGroupCleanup(de_ctx);
1789    if (de_ctx != NULL)
1790        DetectEngineCtxFree(de_ctx);
1791
1792    StreamTcpFreeConfig(TRUE);
1793    FLOW_DESTROY(&f);
1794    UTHFreePacket(p);
1795    return result;
1796}
1797
1798/** \test Test pcre /U with anchored regex (bug 155) */
1799static int UriTestSig16(void)
1800{
1801    int result = 0;
1802    Flow f;
1803    HtpState *http_state = NULL;
1804    uint8_t http_buf1[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
1805        "User-Agent: Mozilla/1.0/\r\n"
1806        "Host: 1.2.3.4\r\n\r\n";
1807    uint32_t http_buf1_len = sizeof(http_buf1) - 1;
1808    uint8_t http_buf2[] = "POST /search?q=123&aq=7123abcee HTTP/1.0\r\n"
1809        "User-Agent: Mozilla/1.0\r\n"
1810        "Cookie: hellocatch\r\n\r\n";
1811    uint32_t http_buf2_len = sizeof(http_buf2) - 1;
1812    TcpSession ssn;
1813    Packet *p = NULL;
1814    Signature *s = NULL;
1815    ThreadVars tv;
1816    DetectEngineThreadCtx *det_ctx = NULL;
1817
1818    memset(&tv, 0, sizeof(ThreadVars));
1819    memset(&f, 0, sizeof(Flow));
1820    memset(&ssn, 0, sizeof(TcpSession));
1821
1822    p = UTHBuildPacket(http_buf1, http_buf1_len, IPPROTO_TCP);
1823
1824    FLOW_INITIALIZE(&f);
1825    f.protoctx = (void *)&ssn;
1826    f.flags |= FLOW_IPV4;
1827
1828    p->flow = &f;
1829    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1830    p->flowflags |= FLOW_PKT_TOSERVER;
1831    p->flowflags |= FLOW_PKT_ESTABLISHED;
1832    f.alproto = ALPROTO_HTTP;
1833
1834    StreamTcpInitConfig(TRUE);
1835
1836    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1837    if (de_ctx == NULL) {
1838        goto end;
1839    }
1840    de_ctx->mpm_matcher = MPM_B2G;
1841    de_ctx->flags |= DE_QUIET;
1842
1843    s = de_ctx->sig_list = SigInit(de_ctx, "drop tcp any any -> any any (msg:\"ET TROJAN Downadup/Conficker A or B Worm reporting\"; flow:to_server,established; uricontent:\"/search?q=\"; pcre:\"/^\\/search\\?q=[0-9]{1,3}(&aq=7(\\?[0-9a-f]{8})?)?/U\"; pcre:\"/\\x0d\\x0aHost\\: \\d+\\.\\d+\\.\\d+\\.\\d+\\x0d\\x0a/\"; sid:2009024; rev:9;)");
1844    if (s == NULL) {
1845        goto end;
1846    }
1847
1848    SigGroupBuild(de_ctx);
1849    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1850
1851    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf1, http_buf1_len);
1852    if (r != 0) {
1853        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1854        goto end;
1855    }
1856
1857    http_state = f.alstate;
1858    if (http_state == NULL) {
1859        printf("no http state: ");
1860        goto end;
1861    }
1862
1863    /* do detect */
1864    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1865
1866    if (!PacketAlertCheck(p, 2009024)) {
1867        printf("sig 1 didnt alert with pkt, but it should: ");
1868        goto end;
1869    }
1870    p->alerts.cnt = 0;
1871
1872    DetectEngineStateReset(f.de_state);
1873    p->payload = http_buf2;
1874    p->payload_len = http_buf2_len;
1875
1876    r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf2, http_buf2_len);
1877    if (r != 0) {
1878        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1879        goto end;
1880    }
1881
1882    http_state = f.alstate;
1883    if (http_state == NULL) {
1884        printf("no http state: ");
1885        goto end;
1886    }
1887
1888    /* do detect */
1889    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1890
1891    if (PacketAlertCheck(p, 2009024)) {
1892        printf("sig 1 alerted, but it should not (host should not match): ");
1893        goto end;
1894    }
1895
1896    result = 1;
1897
1898end:
1899    if (det_ctx != NULL)
1900        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1901    if (de_ctx != NULL)
1902        SigGroupCleanup(de_ctx);
1903    if (de_ctx != NULL)
1904        DetectEngineCtxFree(de_ctx);
1905
1906    StreamTcpFreeConfig(TRUE);
1907    FLOW_DESTROY(&f);
1908    UTHFreePacket(p);
1909    return result;
1910}
1911
1912/**
1913 * \test Test multiple relative contents
1914 */
1915static int UriTestSig17(void)
1916{
1917    int result = 0;
1918    uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_big_big_string_now HTTP/1.0\r\n"
1919        "User-Agent: Mozilla/1.0\r\n";
1920    uint32_t http_buf_len = strlen((char *)http_buf);
1921    Flow f;
1922    TcpSession ssn;
1923    HtpState *http_state = NULL;
1924    Packet *p = NULL;
1925    ThreadVars tv;
1926    DetectEngineThreadCtx *det_ctx = NULL;
1927
1928    memset(&tv, 0, sizeof(ThreadVars));
1929    memset(&f, 0, sizeof(Flow));
1930    memset(&ssn, 0, sizeof(TcpSession));
1931
1932    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
1933
1934    FLOW_INITIALIZE(&f);
1935    f.protoctx = (void *)&ssn;
1936    f.flags |= FLOW_IPV4;
1937
1938    p->flow = &f;
1939    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1940    p->flowflags |= FLOW_PKT_TOSERVER;
1941    p->flowflags |= FLOW_PKT_ESTABLISHED;
1942    f.alproto = ALPROTO_HTTP;
1943
1944    StreamTcpInitConfig(TRUE);
1945
1946    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
1947    if (de_ctx == NULL) {
1948        goto end;
1949    }
1950    de_ctx->mpm_matcher = MPM_B2G;
1951    de_ctx->flags |= DE_QUIET;
1952
1953    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
1954                               "(msg:\"test multiple relative uricontents\"; "
1955                               "uricontent:\"this\"; uricontent:\"is\"; within:6; "
1956                               "uricontent:\"big\"; within:8; "
1957                               "uricontent:\"string\"; within:8; sid:1;)");
1958    if (de_ctx->sig_list == NULL) {
1959        goto end;
1960    }
1961
1962    SigGroupBuild(de_ctx);
1963    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
1964
1965    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
1966    if (r != 0) {
1967        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1968        goto end;
1969    }
1970
1971    http_state = f.alstate;
1972    if (http_state == NULL) {
1973        printf("no http state: ");
1974        goto end;
1975    }
1976
1977    /* do detect */
1978    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
1979
1980    if (!PacketAlertCheck(p, 1)) {
1981        printf("sig 1 alerted, but it should not: ");
1982        goto end;
1983    }
1984
1985    result = 1;
1986
1987end:
1988    if (det_ctx != NULL)
1989        DetectEngineThreadCtxDeinit(&tv, det_ctx);
1990    if (de_ctx != NULL)
1991        SigGroupCleanup(de_ctx);
1992    if (de_ctx != NULL)
1993        DetectEngineCtxFree(de_ctx);
1994
1995    StreamTcpFreeConfig(TRUE);
1996    FLOW_DESTROY(&f);
1997    UTHFreePacket(p);
1998    return result;
1999}
2000
2001/**
2002 * \test Test multiple relative contents
2003 */
2004static int UriTestSig18(void)
2005{
2006    int result = 0;
2007    uint8_t *http_buf = (uint8_t *)"POST /now_this_is_is_is_big_big_big_string_now HTTP/1.0\r\n"
2008        "User-Agent: Mozilla/1.0\r\n";
2009    uint32_t http_buf_len = strlen((char *)http_buf);
2010    Flow f;
2011    TcpSession ssn;
2012    HtpState *http_state = NULL;
2013    Packet *p = NULL;
2014    ThreadVars tv;
2015    DetectEngineThreadCtx *det_ctx = NULL;
2016
2017    memset(&tv, 0, sizeof(ThreadVars));
2018    memset(&f, 0, sizeof(Flow));
2019    memset(&ssn, 0, sizeof(TcpSession));
2020
2021    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2022
2023    FLOW_INITIALIZE(&f);
2024    f.protoctx = (void *)&ssn;
2025    f.flags |= FLOW_IPV4;
2026
2027    p->flow = &f;
2028    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2029    p->flowflags |= FLOW_PKT_TOSERVER;
2030    p->flowflags |= FLOW_PKT_ESTABLISHED;
2031    f.alproto = ALPROTO_HTTP;
2032
2033    StreamTcpInitConfig(TRUE);
2034
2035    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2036    if (de_ctx == NULL) {
2037        goto end;
2038    }
2039    de_ctx->mpm_matcher = MPM_B2G;
2040    de_ctx->flags |= DE_QUIET;
2041
2042    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2043                               "(msg:\"test multiple relative uricontents\"; "
2044                               "uricontent:\"this\"; uricontent:\"is\"; within:9; "
2045                               "uricontent:\"big\"; within:12; "
2046                               "uricontent:\"string\"; within:8; sid:1;)");
2047    if (de_ctx->sig_list == NULL) {
2048        goto end;
2049    }
2050
2051    SigGroupBuild(de_ctx);
2052    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2053
2054    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2055    if (r != 0) {
2056        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2057        goto end;
2058    }
2059
2060    http_state = f.alstate;
2061    if (http_state == NULL) {
2062        printf("no http state: ");
2063        goto end;
2064    }
2065
2066    /* do detect */
2067    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2068
2069    if (!PacketAlertCheck(p, 1)) {
2070        printf("sig 1 alerted, but it should not: ");
2071        goto end;
2072    }
2073
2074    result = 1;
2075
2076end:
2077    if (det_ctx != NULL)
2078        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2079    if (de_ctx != NULL)
2080        SigGroupCleanup(de_ctx);
2081    if (de_ctx != NULL)
2082        DetectEngineCtxFree(de_ctx);
2083
2084    StreamTcpFreeConfig(TRUE);
2085    FLOW_DESTROY(&f);
2086    UTHFreePacket(p);
2087    return result;
2088}
2089
2090/**
2091 * \test Test multiple relative contents
2092 */
2093static int UriTestSig19(void)
2094{
2095    int result = 0;
2096    uint8_t *http_buf = (uint8_t *)"POST /this_this_now_is_is_____big_string_now HTTP/1.0\r\n"
2097        "User-Agent: Mozilla/1.0\r\n";
2098    uint32_t http_buf_len = strlen((char *)http_buf);
2099    Flow f;
2100    TcpSession ssn;
2101    HtpState *http_state = NULL;
2102    Packet *p = NULL;
2103    ThreadVars tv;
2104    DetectEngineThreadCtx *det_ctx = NULL;
2105
2106    memset(&tv, 0, sizeof(ThreadVars));
2107    memset(&f, 0, sizeof(Flow));
2108    memset(&ssn, 0, sizeof(TcpSession));
2109
2110    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2111
2112    FLOW_INITIALIZE(&f);
2113    f.protoctx = (void *)&ssn;
2114    f.flags |= FLOW_IPV4;
2115
2116    p->flow = &f;
2117    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2118    p->flowflags |= FLOW_PKT_TOSERVER;
2119    p->flowflags |= FLOW_PKT_ESTABLISHED;
2120    f.alproto = ALPROTO_HTTP;
2121
2122    StreamTcpInitConfig(TRUE);
2123
2124    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2125    if (de_ctx == NULL) {
2126        goto end;
2127    }
2128    de_ctx->mpm_matcher = MPM_B2G;
2129    de_ctx->flags |= DE_QUIET;
2130
2131    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2132                               "(msg:\"test multiple relative uricontents\"; "
2133                               "uricontent:\"now\"; uricontent:\"this\"; "
2134                               "uricontent:\"is\"; within:12; "
2135                               "uricontent:\"big\"; within:8; "
2136                               "uricontent:\"string\"; within:8; sid:1;)");
2137    if (de_ctx->sig_list == NULL) {
2138        goto end;
2139    }
2140
2141    SigGroupBuild(de_ctx);
2142    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2143
2144    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2145    if (r != 0) {
2146        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2147        goto end;
2148    }
2149
2150    http_state = f.alstate;
2151    if (http_state == NULL) {
2152        printf("no http state: ");
2153        goto end;
2154    }
2155
2156    /* do detect */
2157    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2158
2159    if (!PacketAlertCheck(p, 1)) {
2160        printf("sig 1 alerted, but it should not: ");
2161        goto end;
2162    }
2163
2164    result = 1;
2165
2166end:
2167    if (det_ctx != NULL)
2168        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2169    if (de_ctx != NULL)
2170        SigGroupCleanup(de_ctx);
2171    if (de_ctx != NULL)
2172        DetectEngineCtxFree(de_ctx);
2173
2174    StreamTcpFreeConfig(TRUE);
2175    FLOW_DESTROY(&f);
2176    UTHFreePacket(p);
2177    return result;
2178}
2179
2180/**
2181 * \test Test multiple relative contents with offset
2182 */
2183static int UriTestSig20(void)
2184{
2185    int result = 0;
2186    uint8_t *http_buf = (uint8_t *)"POST /_________thus_thus_is_a_big HTTP/1.0\r\n"
2187        "User-Agent: Mozilla/1.0\r\n";
2188    uint32_t http_buf_len = strlen((char *)http_buf);
2189    Flow f;
2190    TcpSession ssn;
2191    HtpState *http_state = NULL;
2192    Packet *p = NULL;
2193    ThreadVars tv;
2194    DetectEngineThreadCtx *det_ctx = NULL;
2195
2196    memset(&tv, 0, sizeof(ThreadVars));
2197    memset(&f, 0, sizeof(Flow));
2198    memset(&ssn, 0, sizeof(TcpSession));
2199
2200    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2201
2202    FLOW_INITIALIZE(&f);
2203    f.protoctx = (void *)&ssn;
2204    f.flags |= FLOW_IPV4;
2205
2206    p->flow = &f;
2207    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2208    p->flowflags |= FLOW_PKT_TOSERVER;
2209    p->flowflags |= FLOW_PKT_ESTABLISHED;
2210    f.alproto = ALPROTO_HTTP;
2211
2212    StreamTcpInitConfig(TRUE);
2213
2214    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2215    if (de_ctx == NULL) {
2216        goto end;
2217    }
2218    de_ctx->mpm_matcher = MPM_B2G;
2219    de_ctx->flags |= DE_QUIET;
2220
2221    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2222                               "(msg:\"test multiple relative uricontents\"; "
2223                               "uricontent:\"thus\"; offset:8; "
2224                               "uricontent:\"is\"; within:6; "
2225                               "uricontent:\"big\"; within:8; sid:1;)");
2226    if (de_ctx->sig_list == NULL) {
2227        goto end;
2228    }
2229
2230    SigGroupBuild(de_ctx);
2231    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2232
2233    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2234    if (r != 0) {
2235        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2236        goto end;
2237    }
2238
2239    http_state = f.alstate;
2240    if (http_state == NULL) {
2241        printf("no http state: ");
2242        goto end;
2243    }
2244
2245    /* do detect */
2246    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2247
2248    if (!PacketAlertCheck(p, 1)) {
2249        printf("sig 1 alerted, but it should not: ");
2250        goto end;
2251    }
2252
2253    result = 1;
2254
2255end:
2256    if (det_ctx != NULL)
2257        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2258    if (de_ctx != NULL)
2259        SigGroupCleanup(de_ctx);
2260    if (de_ctx != NULL)
2261        DetectEngineCtxFree(de_ctx);
2262
2263    StreamTcpFreeConfig(TRUE);
2264    FLOW_DESTROY(&f);
2265    UTHFreePacket(p);
2266    return result;
2267}
2268
2269/**
2270 * \test Test multiple relative contents with a negated content.
2271 */
2272static int UriTestSig21(void)
2273{
2274    int result = 0;
2275    uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
2276        "User-Agent: Mozilla/1.0\r\n";
2277    uint32_t http_buf_len = strlen((char *)http_buf);
2278    Flow f;
2279    TcpSession ssn;
2280    HtpState *http_state = NULL;
2281    Packet *p = NULL;
2282    ThreadVars tv;
2283    DetectEngineThreadCtx *det_ctx = NULL;
2284
2285    memset(&tv, 0, sizeof(ThreadVars));
2286    memset(&f, 0, sizeof(Flow));
2287    memset(&ssn, 0, sizeof(TcpSession));
2288
2289    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2290
2291    FLOW_INITIALIZE(&f);
2292    f.protoctx = (void *)&ssn;
2293    f.flags |= FLOW_IPV4;
2294
2295    p->flow = &f;
2296    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2297    p->flowflags |= FLOW_PKT_TOSERVER;
2298    p->flowflags |= FLOW_PKT_ESTABLISHED;
2299    f.alproto = ALPROTO_HTTP;
2300
2301    StreamTcpInitConfig(TRUE);
2302
2303    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2304    if (de_ctx == NULL) {
2305        goto end;
2306    }
2307    de_ctx->mpm_matcher = MPM_B2G;
2308    de_ctx->flags |= DE_QUIET;
2309
2310    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2311                               "(msg:\"test multiple relative uricontents\"; "
2312                               "uricontent:\"fix\"; uricontent:\"this\"; within:6; "
2313                               "uricontent:!\"and\"; distance:0; sid:1;)");
2314    if (de_ctx->sig_list == NULL) {
2315        goto end;
2316    }
2317
2318    SigGroupBuild(de_ctx);
2319    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2320
2321    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2322    if (r != 0) {
2323        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2324        goto end;
2325    }
2326
2327    http_state = f.alstate;
2328    if (http_state == NULL) {
2329        printf("no http state: ");
2330        goto end;
2331    }
2332
2333    /* do detect */
2334    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2335
2336    if (PacketAlertCheck(p, 1)) {
2337        printf("sig 1 alerted, but it should not: ");
2338        goto end;
2339    }
2340
2341    result = 1;
2342
2343end:
2344    if (det_ctx != NULL)
2345        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2346    if (de_ctx != NULL)
2347        SigGroupCleanup(de_ctx);
2348    if (de_ctx != NULL)
2349        DetectEngineCtxFree(de_ctx);
2350
2351    StreamTcpFreeConfig(TRUE);
2352    FLOW_DESTROY(&f);
2353    UTHFreePacket(p);
2354    return result;
2355}
2356
2357/**
2358 * \test Test relative pcre.
2359 */
2360static int UriTestSig22(void)
2361{
2362    int result = 0;
2363    uint8_t *http_buf = (uint8_t *)"POST /this_is_a_super_duper_"
2364        "nova_in_super_nova_now HTTP/1.0\r\n"
2365        "User-Agent: Mozilla/1.0\r\n";
2366    uint32_t http_buf_len = strlen((char *)http_buf);
2367    Flow f;
2368    TcpSession ssn;
2369    HtpState *http_state = NULL;
2370    Packet *p = NULL;
2371    ThreadVars tv;
2372    DetectEngineThreadCtx *det_ctx = NULL;
2373
2374    memset(&tv, 0, sizeof(ThreadVars));
2375    memset(&f, 0, sizeof(Flow));
2376    memset(&ssn, 0, sizeof(TcpSession));
2377
2378    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2379
2380    FLOW_INITIALIZE(&f);
2381    f.protoctx = (void *)&ssn;
2382    f.flags |= FLOW_IPV4;
2383
2384    p->flow = &f;
2385    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2386    p->flowflags |= FLOW_PKT_TOSERVER;
2387    p->flowflags |= FLOW_PKT_ESTABLISHED;
2388    f.alproto = ALPROTO_HTTP;
2389
2390    StreamTcpInitConfig(TRUE);
2391
2392    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2393    if (de_ctx == NULL) {
2394        goto end;
2395    }
2396    de_ctx->mpm_matcher = MPM_B2G;
2397    de_ctx->flags |= DE_QUIET;
2398
2399    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2400                               "(msg:\"test multiple relative uricontents\"; "
2401                               "pcre:/super/U; uricontent:\"nova\"; within:7; sid:1;)");
2402    if (de_ctx->sig_list == NULL) {
2403        goto end;
2404    }
2405
2406    SigGroupBuild(de_ctx);
2407    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2408
2409    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2410    if (r != 0) {
2411        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2412        goto end;
2413    }
2414
2415    http_state = f.alstate;
2416    if (http_state == NULL) {
2417        printf("no http state: ");
2418        goto end;
2419    }
2420
2421    /* do detect */
2422    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2423
2424    if (!PacketAlertCheck(p, 1)) {
2425        printf("sig 1 didn't alert, but it should have: ");
2426        goto end;
2427    }
2428
2429    result = 1;
2430
2431end:
2432    if (det_ctx != NULL)
2433        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2434    if (de_ctx != NULL)
2435        SigGroupCleanup(de_ctx);
2436    if (de_ctx != NULL)
2437        DetectEngineCtxFree(de_ctx);
2438
2439    StreamTcpFreeConfig(TRUE);
2440    FLOW_DESTROY(&f);
2441    UTHFreePacket(p);
2442    return result;
2443}
2444
2445/**
2446 * \test Test multiple relative contents with a negated content.
2447 */
2448static int UriTestSig23(void)
2449{
2450    int result = 0;
2451    uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
2452        "User-Agent: Mozilla/1.0\r\n";
2453    uint32_t http_buf_len = strlen((char *)http_buf);
2454    Flow f;
2455    TcpSession ssn;
2456    HtpState *http_state = NULL;
2457    Packet *p = NULL;
2458    ThreadVars tv;
2459    DetectEngineThreadCtx *det_ctx = NULL;
2460
2461    memset(&tv, 0, sizeof(ThreadVars));
2462    memset(&f, 0, sizeof(Flow));
2463    memset(&ssn, 0, sizeof(TcpSession));
2464
2465    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2466
2467    FLOW_INITIALIZE(&f);
2468    f.protoctx = (void *)&ssn;
2469    f.flags |= FLOW_IPV4;
2470
2471    p->flow = &f;
2472    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2473    p->flowflags |= FLOW_PKT_TOSERVER;
2474    p->flowflags |= FLOW_PKT_ESTABLISHED;
2475    f.alproto = ALPROTO_HTTP;
2476
2477    StreamTcpInitConfig(TRUE);
2478
2479    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2480    if (de_ctx == NULL) {
2481        goto end;
2482    }
2483    de_ctx->mpm_matcher = MPM_B2G;
2484    de_ctx->flags |= DE_QUIET;
2485
2486    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2487                               "(msg:\"test multiple relative uricontents\"; "
2488                               "uricontent:!\"fix_this_now\"; sid:1;)");
2489    if (de_ctx->sig_list == NULL) {
2490        goto end;
2491    }
2492
2493    SigGroupBuild(de_ctx);
2494    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2495
2496    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2497    if (r != 0) {
2498        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2499        goto end;
2500    }
2501
2502    http_state = f.alstate;
2503    if (http_state == NULL) {
2504        printf("no http state: ");
2505        goto end;
2506    }
2507
2508    /* do detect */
2509    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2510
2511    if (PacketAlertCheck(p, 1)) {
2512        printf("sig 1 alerted, but it should not: ");
2513        goto end;
2514    }
2515
2516    result = 1;
2517
2518end:
2519    if (det_ctx != NULL)
2520        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2521    if (de_ctx != NULL)
2522        SigGroupCleanup(de_ctx);
2523    if (de_ctx != NULL)
2524        DetectEngineCtxFree(de_ctx);
2525
2526    StreamTcpFreeConfig(TRUE);
2527    FLOW_DESTROY(&f);
2528    UTHFreePacket(p);
2529    return result;
2530}
2531
2532/**
2533 * \test Test multiple relative contents with a negated content.
2534 */
2535static int UriTestSig24(void)
2536{
2537    int result = 0;
2538    uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
2539        "User-Agent: Mozilla/1.0\r\n";
2540    uint32_t http_buf_len = strlen((char *)http_buf);
2541    Flow f;
2542    TcpSession ssn;
2543    HtpState *http_state = NULL;
2544    Packet *p = NULL;
2545    ThreadVars tv;
2546    DetectEngineThreadCtx *det_ctx = NULL;
2547
2548    memset(&tv, 0, sizeof(ThreadVars));
2549    memset(&f, 0, sizeof(Flow));
2550    memset(&ssn, 0, sizeof(TcpSession));
2551
2552    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2553
2554    FLOW_INITIALIZE(&f);
2555    f.protoctx = (void *)&ssn;
2556    f.flags |= FLOW_IPV4;
2557
2558    p->flow = &f;
2559    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2560    p->flowflags |= FLOW_PKT_TOSERVER;
2561    p->flowflags |= FLOW_PKT_ESTABLISHED;
2562    f.alproto = ALPROTO_HTTP;
2563
2564    StreamTcpInitConfig(TRUE);
2565
2566    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2567    if (de_ctx == NULL) {
2568        goto end;
2569    }
2570    de_ctx->mpm_matcher = MPM_B2G;
2571    de_ctx->flags |= DE_QUIET;
2572
2573    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2574                               "(msg:\"test multiple relative uricontents\"; "
2575                               "uricontent:\"we_need_to\"; uricontent:!\"fix_this_now\"; sid:1;)");
2576    if (de_ctx->sig_list == NULL) {
2577        goto end;
2578    }
2579
2580    SigGroupBuild(de_ctx);
2581    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2582
2583    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2584    if (r != 0) {
2585        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2586        goto end;
2587    }
2588
2589    http_state = f.alstate;
2590    if (http_state == NULL) {
2591        printf("no http state: ");
2592        goto end;
2593    }
2594
2595    /* do detect */
2596    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2597
2598    if (PacketAlertCheck(p, 1)) {
2599        printf("sig 1 alerted, but it should not: ");
2600        goto end;
2601    }
2602
2603    result = 1;
2604
2605end:
2606    if (det_ctx != NULL)
2607        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2608    if (de_ctx != NULL)
2609        SigGroupCleanup(de_ctx);
2610    if (de_ctx != NULL)
2611        DetectEngineCtxFree(de_ctx);
2612
2613    StreamTcpFreeConfig(TRUE);
2614    FLOW_DESTROY(&f);
2615    UTHFreePacket(p);
2616    return result;
2617}
2618
2619/**
2620 * \test Test normalized uricontents.
2621 */
2622static int UriTestSig25(void)
2623{
2624    int result = 0;
2625    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
2626        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
2627    uint32_t http_buf_len = strlen((char *)http_buf);
2628    Flow f;
2629    TcpSession ssn;
2630    HtpState *http_state = NULL;
2631    Packet *p = NULL;
2632    ThreadVars tv;
2633    DetectEngineThreadCtx *det_ctx = NULL;
2634
2635    memset(&tv, 0, sizeof(ThreadVars));
2636    memset(&f, 0, sizeof(Flow));
2637    memset(&ssn, 0, sizeof(TcpSession));
2638
2639    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2640
2641    FLOW_INITIALIZE(&f);
2642    f.protoctx = (void *)&ssn;
2643    f.flags |= FLOW_IPV4;
2644
2645    p->flow = &f;
2646    p->flowflags |= FLOW_PKT_TOSERVER;
2647    p->flowflags |= FLOW_PKT_ESTABLISHED;
2648    f.alproto = ALPROTO_HTTP;
2649    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2650
2651    StreamTcpInitConfig(TRUE);
2652
2653    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2654    if (de_ctx == NULL) {
2655        goto end;
2656    }
2657    de_ctx->mpm_matcher = MPM_B2G;
2658    de_ctx->flags |= DE_QUIET;
2659
2660    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2661                               "(msg:\"test multiple relative uricontents\"; "
2662                               "pcre:/normalized/U; uricontent:\"normalized uri\"; sid:1;)");
2663    if (de_ctx->sig_list == NULL) {
2664        goto end;
2665    }
2666
2667    SigGroupBuild(de_ctx);
2668    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2669
2670    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2671    if (r != 0) {
2672        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2673        goto end;
2674    }
2675
2676    http_state = f.alstate;
2677    if (http_state == NULL) {
2678        printf("no http state: ");
2679        goto end;
2680    }
2681
2682    /* do detect */
2683    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2684
2685    if (!PacketAlertCheck(p, 1)) {
2686        printf("sig 1 didn't alert, but it should have: ");
2687        goto end;
2688    }
2689
2690    result = 1;
2691
2692end:
2693    if (det_ctx != NULL)
2694        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2695    if (de_ctx != NULL)
2696        SigGroupCleanup(de_ctx);
2697    if (de_ctx != NULL)
2698        DetectEngineCtxFree(de_ctx);
2699
2700    StreamTcpFreeConfig(TRUE);
2701    FLOW_DESTROY(&f);
2702    UTHFreePacket(p);
2703    return result;
2704}
2705
2706/**
2707 * \test Test multiple relative contents with a negated content.
2708 */
2709static int UriTestSig26(void)
2710{
2711    int result = 0;
2712    uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
2713        "User-Agent: Mozilla/1.0\r\n";
2714    uint32_t http_buf_len = strlen((char *)http_buf);
2715    Flow f;
2716    TcpSession ssn;
2717    HtpState *http_state = NULL;
2718    Packet *p = NULL;
2719    ThreadVars tv;
2720    DetectEngineThreadCtx *det_ctx = NULL;
2721
2722    memset(&tv, 0, sizeof(ThreadVars));
2723    memset(&f, 0, sizeof(Flow));
2724    memset(&ssn, 0, sizeof(TcpSession));
2725
2726    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2727
2728    FLOW_INITIALIZE(&f);
2729    f.protoctx = (void *)&ssn;
2730    f.flags |= FLOW_IPV4;
2731
2732    p->flow = &f;
2733    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2734    p->flowflags |= FLOW_PKT_TOSERVER;
2735    p->flowflags |= FLOW_PKT_ESTABLISHED;
2736    f.alproto = ALPROTO_HTTP;
2737
2738    StreamTcpInitConfig(TRUE);
2739
2740    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2741    if (de_ctx == NULL) {
2742        goto end;
2743    }
2744    de_ctx->mpm_matcher = MPM_B2G;
2745    de_ctx->flags |= DE_QUIET;
2746
2747    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2748                               "(msg:\"test multiple relative uricontents\"; "
2749                               "uricontent:\"fix_this\"; isdataat:4,relative; sid:1;)");
2750    if (de_ctx->sig_list == NULL) {
2751        goto end;
2752    }
2753
2754    SigGroupBuild(de_ctx);
2755    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2756
2757    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2758    if (r != 0) {
2759        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2760        goto end;
2761    }
2762
2763    http_state = f.alstate;
2764    if (http_state == NULL) {
2765        printf("no http state: ");
2766        goto end;
2767    }
2768
2769    /* do detect */
2770    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2771
2772    if (!PacketAlertCheck(p, 1)) {
2773        printf("sig 1 didn't alert, but it should have: ");
2774        goto end;
2775    }
2776
2777    result = 1;
2778
2779end:
2780    if (det_ctx != NULL)
2781        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2782    if (de_ctx != NULL)
2783        SigGroupCleanup(de_ctx);
2784    if (de_ctx != NULL)
2785        DetectEngineCtxFree(de_ctx);
2786
2787    StreamTcpFreeConfig(TRUE);
2788    FLOW_DESTROY(&f);
2789    UTHFreePacket(p);
2790    return result;
2791}
2792
2793/**
2794 * \test Test multiple relative contents with a negated content.
2795 */
2796static int UriTestSig27(void)
2797{
2798    int result = 0;
2799    uint8_t *http_buf = (uint8_t *)"POST /we_need_to_fix_this_and_yes_fix_this_now HTTP/1.0\r\n"
2800        "User-Agent: Mozilla/1.0\r\n";
2801    uint32_t http_buf_len = strlen((char *)http_buf);
2802    Flow f;
2803    TcpSession ssn;
2804    HtpState *http_state = NULL;
2805    Packet *p = NULL;
2806    ThreadVars tv;
2807    DetectEngineThreadCtx *det_ctx = NULL;
2808
2809    memset(&tv, 0, sizeof(ThreadVars));
2810    memset(&f, 0, sizeof(Flow));
2811    memset(&ssn, 0, sizeof(TcpSession));
2812
2813    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2814
2815    FLOW_INITIALIZE(&f);
2816    f.protoctx = (void *)&ssn;
2817    f.flags |= FLOW_IPV4;
2818
2819    p->flow = &f;
2820    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2821    p->flowflags |= FLOW_PKT_TOSERVER;
2822    p->flowflags |= FLOW_PKT_ESTABLISHED;
2823    f.alproto = ALPROTO_HTTP;
2824
2825    StreamTcpInitConfig(TRUE);
2826
2827    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2828    if (de_ctx == NULL) {
2829        goto end;
2830    }
2831    de_ctx->mpm_matcher = MPM_B2G;
2832    de_ctx->flags |= DE_QUIET;
2833
2834    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
2835                               "(msg:\"test multiple relative uricontents\"; "
2836                               "uricontent:\"fix_this\"; isdataat:!10,relative; sid:1;)");
2837    if (de_ctx->sig_list == NULL) {
2838        goto end;
2839    }
2840
2841    SigGroupBuild(de_ctx);
2842    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2843
2844    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2845    if (r != 0) {
2846        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2847        goto end;
2848    }
2849
2850    http_state = f.alstate;
2851    if (http_state == NULL) {
2852        printf("no http state: ");
2853        goto end;
2854    }
2855
2856    /* do detect */
2857    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2858
2859    if (!PacketAlertCheck(p, 1)) {
2860        printf("sig 1 didn't alert, but it should have: ");
2861        goto end;
2862    }
2863
2864    result = 1;
2865
2866end:
2867    if (det_ctx != NULL)
2868        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2869    if (de_ctx != NULL)
2870        SigGroupCleanup(de_ctx);
2871    if (de_ctx != NULL)
2872        DetectEngineCtxFree(de_ctx);
2873
2874    StreamTcpFreeConfig(TRUE);
2875    FLOW_DESTROY(&f);
2876    UTHFreePacket(p);
2877    return result;
2878}
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915static int UriTestSig28(void)
2916{
2917    int result = 0;
2918    uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
2919        "User-Agent: Mozilla/1.0\r\n";
2920    uint32_t http_buf_len = strlen((char *)http_buf);
2921    Flow f;
2922    TcpSession ssn;
2923    HtpState *http_state = NULL;
2924    Packet *p = NULL;
2925    ThreadVars tv;
2926    DetectEngineThreadCtx *det_ctx = NULL;
2927
2928    memset(&tv, 0, sizeof(ThreadVars));
2929    memset(&f, 0, sizeof(Flow));
2930    memset(&ssn, 0, sizeof(TcpSession));
2931
2932    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
2933
2934    FLOW_INITIALIZE(&f);
2935    f.protoctx = (void *)&ssn;
2936    f.flags |= FLOW_IPV4;
2937
2938    p->flow = &f;
2939    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
2940    p->flowflags |= FLOW_PKT_TOSERVER;
2941    p->flowflags |= FLOW_PKT_ESTABLISHED;
2942    f.alproto = ALPROTO_HTTP;
2943
2944    StreamTcpInitConfig(TRUE);
2945
2946    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
2947    if (de_ctx == NULL) {
2948        goto end;
2949    }
2950    de_ctx->mpm_matcher = MPM_B2G;
2951    de_ctx->flags |= DE_QUIET;
2952
2953    de_ctx->sig_list = SigInit(de_ctx,
2954                               "alert tcp any any -> any any (msg:\"dummy\"; "
2955                               "uricontent:\"this\"; "
2956                               "byte_extract:1,2,one,string,dec,relative; "
2957                               "uricontent:\"ring\"; distance:one; sid:1;)");
2958    if (de_ctx->sig_list == NULL) {
2959        goto end;
2960    }
2961
2962    SigGroupBuild(de_ctx);
2963    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
2964
2965    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
2966    if (r != 0) {
2967        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
2968        goto end;
2969    }
2970
2971    http_state = f.alstate;
2972    if (http_state == NULL) {
2973        printf("no http state: ");
2974        goto end;
2975    }
2976
2977    /* do detect */
2978    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
2979
2980    if (!PacketAlertCheck(p, 1)) {
2981        printf("sig 1 didn't alert, but should have: ");
2982        goto end;
2983    }
2984
2985    result = 1;
2986
2987end:
2988    if (det_ctx != NULL)
2989        DetectEngineThreadCtxDeinit(&tv, det_ctx);
2990    if (de_ctx != NULL)
2991        SigGroupCleanup(de_ctx);
2992    if (de_ctx != NULL)
2993        DetectEngineCtxFree(de_ctx);
2994
2995    StreamTcpFreeConfig(TRUE);
2996    FLOW_DESTROY(&f);
2997    UTHFreePacket(p);
2998    return result;
2999}
3000
3001static int UriTestSig29(void)
3002{
3003    int result = 0;
3004    uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
3005        "User-Agent: Mozilla/1.0\r\n";
3006    uint32_t http_buf_len = strlen((char *)http_buf);
3007    Flow f;
3008    TcpSession ssn;
3009    HtpState *http_state = NULL;
3010    Packet *p = NULL;
3011    ThreadVars tv;
3012    DetectEngineThreadCtx *det_ctx = NULL;
3013
3014    memset(&tv, 0, sizeof(ThreadVars));
3015    memset(&f, 0, sizeof(Flow));
3016    memset(&ssn, 0, sizeof(TcpSession));
3017
3018    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3019
3020    FLOW_INITIALIZE(&f);
3021    f.protoctx = (void *)&ssn;
3022    f.flags |= FLOW_IPV4;
3023
3024    p->flow = &f;
3025    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3026    p->flowflags |= FLOW_PKT_TOSERVER;
3027    p->flowflags |= FLOW_PKT_ESTABLISHED;
3028    f.alproto = ALPROTO_HTTP;
3029
3030    StreamTcpInitConfig(TRUE);
3031
3032    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3033    if (de_ctx == NULL) {
3034        goto end;
3035    }
3036    de_ctx->mpm_matcher = MPM_B2G;
3037    de_ctx->flags |= DE_QUIET;
3038
3039    de_ctx->sig_list = SigInit(de_ctx,
3040                               "alert tcp any any -> any any (msg:\"dummy\"; "
3041                               "uricontent:\"this\"; "
3042                               "byte_extract:1,2,one,string,dec,relative; "
3043                               "uricontent:\"ring\"; distance:one; sid:1;)");
3044    if (de_ctx->sig_list == NULL) {
3045        goto end;
3046    }
3047
3048    SigGroupBuild(de_ctx);
3049    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3050
3051    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3052    if (r != 0) {
3053        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3054        goto end;
3055    }
3056
3057    http_state = f.alstate;
3058    if (http_state == NULL) {
3059        printf("no http state: ");
3060        goto end;
3061    }
3062
3063    /* do detect */
3064    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3065
3066    if (!PacketAlertCheck(p, 1)) {
3067        printf("sig 1 didn't alert, but should have: ");
3068        goto end;
3069    }
3070
3071    result = 1;
3072
3073end:
3074    if (det_ctx != NULL)
3075        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3076    if (de_ctx != NULL)
3077        SigGroupCleanup(de_ctx);
3078    if (de_ctx != NULL)
3079        DetectEngineCtxFree(de_ctx);
3080
3081    StreamTcpFreeConfig(TRUE);
3082    FLOW_DESTROY(&f);
3083    UTHFreePacket(p);
3084    return result;
3085}
3086
3087static int UriTestSig30(void)
3088{
3089    int result = 0;
3090    uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
3091        "User-Agent: Mozilla/1.0\r\n";
3092    uint32_t http_buf_len = strlen((char *)http_buf);
3093    Flow f;
3094    TcpSession ssn;
3095    HtpState *http_state = NULL;
3096    Packet *p = NULL;
3097    ThreadVars tv;
3098    DetectEngineThreadCtx *det_ctx = NULL;
3099
3100    memset(&tv, 0, sizeof(ThreadVars));
3101    memset(&f, 0, sizeof(Flow));
3102    memset(&ssn, 0, sizeof(TcpSession));
3103
3104    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3105
3106    FLOW_INITIALIZE(&f);
3107    f.protoctx = (void *)&ssn;
3108    f.flags |= FLOW_IPV4;
3109
3110    p->flow = &f;
3111    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3112    p->flowflags |= FLOW_PKT_TOSERVER;
3113    p->flowflags |= FLOW_PKT_ESTABLISHED;
3114    f.alproto = ALPROTO_HTTP;
3115
3116    StreamTcpInitConfig(TRUE);
3117
3118    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3119    if (de_ctx == NULL) {
3120        goto end;
3121    }
3122    de_ctx->mpm_matcher = MPM_B2G;
3123    de_ctx->flags |= DE_QUIET;
3124
3125    de_ctx->sig_list = SigInit(de_ctx,
3126                               "alert tcp any any -> any any (msg:\"dummy\"; "
3127                               "uricontent:\"this\"; "
3128                               "byte_extract:1,2,one,string,dec,relative; "
3129                               "uricontent:\"_b5ig\"; offset:one; sid:1;)");
3130    if (de_ctx->sig_list == NULL) {
3131        goto end;
3132    }
3133
3134    SigGroupBuild(de_ctx);
3135    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3136
3137    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3138    if (r != 0) {
3139        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3140        goto end;
3141    }
3142
3143    http_state = f.alstate;
3144    if (http_state == NULL) {
3145        printf("no http state: ");
3146        goto end;
3147    }
3148
3149    /* do detect */
3150    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3151
3152    if (!PacketAlertCheck(p, 1)) {
3153        printf("sig 1 didn't alert, but should have: ");
3154        goto end;
3155    }
3156
3157    result = 1;
3158
3159end:
3160    if (det_ctx != NULL)
3161        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3162    if (de_ctx != NULL)
3163        SigGroupCleanup(de_ctx);
3164    if (de_ctx != NULL)
3165        DetectEngineCtxFree(de_ctx);
3166
3167    StreamTcpFreeConfig(TRUE);
3168    FLOW_DESTROY(&f);
3169    UTHFreePacket(p);
3170    return result;
3171}
3172
3173static int UriTestSig31(void)
3174{
3175    int result = 0;
3176    uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
3177        "User-Agent: Mozilla/1.0\r\n";
3178    uint32_t http_buf_len = strlen((char *)http_buf);
3179    Flow f;
3180    TcpSession ssn;
3181    HtpState *http_state = NULL;
3182    Packet *p = NULL;
3183    ThreadVars tv;
3184    DetectEngineThreadCtx *det_ctx = NULL;
3185
3186    memset(&tv, 0, sizeof(ThreadVars));
3187    memset(&f, 0, sizeof(Flow));
3188    memset(&ssn, 0, sizeof(TcpSession));
3189
3190    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3191
3192    FLOW_INITIALIZE(&f);
3193    f.protoctx = (void *)&ssn;
3194    f.flags |= FLOW_IPV4;
3195
3196    p->flow = &f;
3197    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3198    p->flowflags |= FLOW_PKT_TOSERVER;
3199    p->flowflags |= FLOW_PKT_ESTABLISHED;
3200    f.alproto = ALPROTO_HTTP;
3201
3202    StreamTcpInitConfig(TRUE);
3203
3204    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3205    if (de_ctx == NULL) {
3206        goto end;
3207    }
3208    de_ctx->mpm_matcher = MPM_B2G;
3209    de_ctx->flags |= DE_QUIET;
3210
3211    de_ctx->sig_list = SigInit(de_ctx,
3212                               "alert tcp any any -> any any (msg:\"dummy\"; "
3213                               "uricontent:\"this\"; "
3214                               "byte_extract:1,2,one,string,dec,relative; "
3215                               "uricontent:\"his\"; depth:one; sid:1;)");
3216    if (de_ctx->sig_list == NULL) {
3217        goto end;
3218    }
3219
3220    SigGroupBuild(de_ctx);
3221    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3222
3223    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3224    if (r != 0) {
3225        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3226        goto end;
3227    }
3228
3229    http_state = f.alstate;
3230    if (http_state == NULL) {
3231        printf("no http state: ");
3232        goto end;
3233    }
3234
3235    /* do detect */
3236    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3237
3238    if (!PacketAlertCheck(p, 1)) {
3239        printf("sig 1 didn't alert, but should have: ");
3240        goto end;
3241    }
3242
3243    result = 1;
3244
3245end:
3246    if (det_ctx != NULL)
3247        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3248    if (de_ctx != NULL)
3249        SigGroupCleanup(de_ctx);
3250    if (de_ctx != NULL)
3251        DetectEngineCtxFree(de_ctx);
3252
3253    StreamTcpFreeConfig(TRUE);
3254    FLOW_DESTROY(&f);
3255    UTHFreePacket(p);
3256    return result;
3257}
3258
3259static int UriTestSig32(void)
3260{
3261    int result = 0;
3262    uint8_t *http_buf = (uint8_t *)"POST /this_b5ig_string_now_in_http HTTP/1.0\r\n"
3263        "User-Agent: Mozilla/1.0\r\n";
3264    uint32_t http_buf_len = strlen((char *)http_buf);
3265    Flow f;
3266    TcpSession ssn;
3267    HtpState *http_state = NULL;
3268    Packet *p = NULL;
3269    ThreadVars tv;
3270    DetectEngineThreadCtx *det_ctx = NULL;
3271
3272    memset(&tv, 0, sizeof(ThreadVars));
3273    memset(&f, 0, sizeof(Flow));
3274    memset(&ssn, 0, sizeof(TcpSession));
3275
3276    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3277
3278    FLOW_INITIALIZE(&f);
3279    f.protoctx = (void *)&ssn;
3280    f.flags |= FLOW_IPV4;
3281
3282    p->flow = &f;
3283    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3284    p->flowflags |= FLOW_PKT_TOSERVER;
3285    p->flowflags |= FLOW_PKT_ESTABLISHED;
3286    f.alproto = ALPROTO_HTTP;
3287
3288    StreamTcpInitConfig(TRUE);
3289
3290    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3291    if (de_ctx == NULL) {
3292        goto end;
3293    }
3294    de_ctx->mpm_matcher = MPM_B2G;
3295    de_ctx->flags |= DE_QUIET;
3296
3297    de_ctx->sig_list = SigInit(de_ctx,
3298                               "alert tcp any any -> any any (msg:\"dummy\"; "
3299                               "uricontent:\"this\"; "
3300                               "byte_extract:1,2,one,string,dec,relative; "
3301                               "uricontent:\"g_st\"; within:one; sid:1;)");
3302    if (de_ctx->sig_list == NULL) {
3303        goto end;
3304    }
3305
3306    SigGroupBuild(de_ctx);
3307    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3308
3309    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3310    if (r != 0) {
3311        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3312        goto end;
3313    }
3314
3315    http_state = f.alstate;
3316    if (http_state == NULL) {
3317        printf("no http state: ");
3318        goto end;
3319    }
3320
3321    /* do detect */
3322    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3323
3324    if (!PacketAlertCheck(p, 1)) {
3325        printf("sig 1 didn't alert, but should have: ");
3326        goto end;
3327    }
3328
3329    result = 1;
3330
3331end:
3332    if (det_ctx != NULL)
3333        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3334    if (de_ctx != NULL)
3335        SigGroupCleanup(de_ctx);
3336    if (de_ctx != NULL)
3337        DetectEngineCtxFree(de_ctx);
3338
3339    StreamTcpFreeConfig(TRUE);
3340    FLOW_DESTROY(&f);
3341    UTHFreePacket(p);
3342    return result;
3343}
3344
3345static int UriTestSig33(void)
3346{
3347    int result = 0;
3348    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3349        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3350    uint32_t http_buf_len = strlen((char *)http_buf);
3351    Flow f;
3352    TcpSession ssn;
3353    HtpState *http_state = NULL;
3354    Packet *p = NULL;
3355    ThreadVars tv;
3356    DetectEngineThreadCtx *det_ctx = NULL;
3357
3358    memset(&tv, 0, sizeof(ThreadVars));
3359    memset(&f, 0, sizeof(Flow));
3360    memset(&ssn, 0, sizeof(TcpSession));
3361
3362    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3363
3364    FLOW_INITIALIZE(&f);
3365    f.protoctx = (void *)&ssn;
3366    f.flags |= FLOW_IPV4;
3367
3368    p->flow = &f;
3369    p->flowflags |= FLOW_PKT_TOSERVER;
3370    p->flowflags |= FLOW_PKT_ESTABLISHED;
3371    f.alproto = ALPROTO_HTTP;
3372    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3373
3374    StreamTcpInitConfig(TRUE);
3375
3376    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3377    if (de_ctx == NULL) {
3378        goto end;
3379    }
3380    de_ctx->mpm_matcher = MPM_B2G;
3381    de_ctx->flags |= DE_QUIET;
3382
3383    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3384                               "(msg:\"test multiple relative uricontents\"; "
3385                               "urilen:15; sid:1;)");
3386    if (de_ctx->sig_list == NULL) {
3387        goto end;
3388    }
3389
3390    SigGroupBuild(de_ctx);
3391    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3392
3393    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3394    if (r != 0) {
3395        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3396        goto end;
3397    }
3398
3399    http_state = f.alstate;
3400    if (http_state == NULL) {
3401        printf("no http state: ");
3402        goto end;
3403    }
3404
3405    /* do detect */
3406    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3407
3408    if (!PacketAlertCheck(p, 1)) {
3409        printf("sig 1 didn't alert, but it should have: ");
3410        goto end;
3411    }
3412
3413    result = 1;
3414
3415end:
3416    if (det_ctx != NULL)
3417        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3418    if (de_ctx != NULL)
3419        SigGroupCleanup(de_ctx);
3420    if (de_ctx != NULL)
3421        DetectEngineCtxFree(de_ctx);
3422
3423    StreamTcpFreeConfig(TRUE);
3424    FLOW_DESTROY(&f);
3425    UTHFreePacket(p);
3426    return result;
3427}
3428
3429static int UriTestSig34(void)
3430{
3431    int result = 0;
3432    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3433        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3434    uint32_t http_buf_len = strlen((char *)http_buf);
3435    Flow f;
3436    TcpSession ssn;
3437    HtpState *http_state = NULL;
3438    Packet *p = NULL;
3439    ThreadVars tv;
3440    DetectEngineThreadCtx *det_ctx = NULL;
3441
3442    memset(&tv, 0, sizeof(ThreadVars));
3443    memset(&f, 0, sizeof(Flow));
3444    memset(&ssn, 0, sizeof(TcpSession));
3445
3446    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3447
3448    FLOW_INITIALIZE(&f);
3449    f.protoctx = (void *)&ssn;
3450    f.flags |= FLOW_IPV4;
3451
3452    p->flow = &f;
3453    p->flowflags |= FLOW_PKT_TOSERVER;
3454    p->flowflags |= FLOW_PKT_ESTABLISHED;
3455    f.alproto = ALPROTO_HTTP;
3456    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3457
3458    StreamTcpInitConfig(TRUE);
3459
3460    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3461    if (de_ctx == NULL) {
3462        goto end;
3463    }
3464    de_ctx->mpm_matcher = MPM_B2G;
3465    de_ctx->flags |= DE_QUIET;
3466
3467    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3468                               "(msg:\"test multiple relative uricontents\"; "
3469                               "urilen:15, norm; sid:1;)");
3470    if (de_ctx->sig_list == NULL) {
3471        goto end;
3472    }
3473
3474    SigGroupBuild(de_ctx);
3475    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3476
3477    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3478    if (r != 0) {
3479        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3480        goto end;
3481    }
3482
3483    http_state = f.alstate;
3484    if (http_state == NULL) {
3485        printf("no http state: ");
3486        goto end;
3487    }
3488
3489    /* do detect */
3490    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3491
3492    if (!PacketAlertCheck(p, 1)) {
3493        printf("sig 1 didn't alert, but it should have: ");
3494        goto end;
3495    }
3496
3497    result = 1;
3498
3499end:
3500    if (det_ctx != NULL)
3501        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3502    if (de_ctx != NULL)
3503        SigGroupCleanup(de_ctx);
3504    if (de_ctx != NULL)
3505        DetectEngineCtxFree(de_ctx);
3506
3507    StreamTcpFreeConfig(TRUE);
3508    FLOW_DESTROY(&f);
3509    UTHFreePacket(p);
3510    return result;
3511}
3512
3513static int UriTestSig35(void)
3514{
3515    int result = 0;
3516    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3517        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3518    uint32_t http_buf_len = strlen((char *)http_buf);
3519    Flow f;
3520    TcpSession ssn;
3521    HtpState *http_state = NULL;
3522    Packet *p = NULL;
3523    ThreadVars tv;
3524    DetectEngineThreadCtx *det_ctx = NULL;
3525
3526    memset(&tv, 0, sizeof(ThreadVars));
3527    memset(&f, 0, sizeof(Flow));
3528    memset(&ssn, 0, sizeof(TcpSession));
3529
3530    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3531
3532    FLOW_INITIALIZE(&f);
3533    f.protoctx = (void *)&ssn;
3534    f.flags |= FLOW_IPV4;
3535
3536    p->flow = &f;
3537    p->flowflags |= FLOW_PKT_TOSERVER;
3538    p->flowflags |= FLOW_PKT_ESTABLISHED;
3539    f.alproto = ALPROTO_HTTP;
3540    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3541
3542    StreamTcpInitConfig(TRUE);
3543
3544    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3545    if (de_ctx == NULL) {
3546        goto end;
3547    }
3548    de_ctx->mpm_matcher = MPM_B2G;
3549    de_ctx->flags |= DE_QUIET;
3550
3551    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3552                               "(msg:\"test multiple relative uricontents\"; "
3553                               "urilen:16; sid:1;)");
3554    if (de_ctx->sig_list == NULL) {
3555        goto end;
3556    }
3557
3558    SigGroupBuild(de_ctx);
3559    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3560
3561    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3562    if (r != 0) {
3563        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3564        goto end;
3565    }
3566
3567    http_state = f.alstate;
3568    if (http_state == NULL) {
3569        printf("no http state: ");
3570        goto end;
3571    }
3572
3573    /* do detect */
3574    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3575
3576    if (PacketAlertCheck(p, 1)) {
3577        printf("sig 1 alerted, but it shouldn't have: ");
3578        goto end;
3579    }
3580
3581    result = 1;
3582
3583end:
3584    if (det_ctx != NULL)
3585        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3586    if (de_ctx != NULL)
3587        SigGroupCleanup(de_ctx);
3588    if (de_ctx != NULL)
3589        DetectEngineCtxFree(de_ctx);
3590
3591    StreamTcpFreeConfig(TRUE);
3592    FLOW_DESTROY(&f);
3593    UTHFreePacket(p);
3594    return result;
3595}
3596
3597static int UriTestSig36(void)
3598{
3599    int result = 0;
3600    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3601        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3602    uint32_t http_buf_len = strlen((char *)http_buf);
3603    Flow f;
3604    TcpSession ssn;
3605    HtpState *http_state = NULL;
3606    Packet *p = NULL;
3607    ThreadVars tv;
3608    DetectEngineThreadCtx *det_ctx = NULL;
3609
3610    memset(&tv, 0, sizeof(ThreadVars));
3611    memset(&f, 0, sizeof(Flow));
3612    memset(&ssn, 0, sizeof(TcpSession));
3613
3614    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3615
3616    FLOW_INITIALIZE(&f);
3617    f.protoctx = (void *)&ssn;
3618    f.flags |= FLOW_IPV4;
3619
3620    p->flow = &f;
3621    p->flowflags |= FLOW_PKT_TOSERVER;
3622    p->flowflags |= FLOW_PKT_ESTABLISHED;
3623    f.alproto = ALPROTO_HTTP;
3624    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3625
3626    StreamTcpInitConfig(TRUE);
3627
3628    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3629    if (de_ctx == NULL) {
3630        goto end;
3631    }
3632    de_ctx->mpm_matcher = MPM_B2G;
3633    de_ctx->flags |= DE_QUIET;
3634
3635    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3636                               "(msg:\"test multiple relative uricontents\"; "
3637                               "urilen:16, norm; sid:1;)");
3638    if (de_ctx->sig_list == NULL) {
3639        goto end;
3640    }
3641
3642    SigGroupBuild(de_ctx);
3643    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3644
3645    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3646    if (r != 0) {
3647        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3648        goto end;
3649    }
3650
3651    http_state = f.alstate;
3652    if (http_state == NULL) {
3653        printf("no http state: ");
3654        goto end;
3655    }
3656
3657    /* do detect */
3658    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3659
3660    if (PacketAlertCheck(p, 1)) {
3661        printf("sig 1 alerted, but it shouldn't have: ");
3662        goto end;
3663    }
3664
3665    result = 1;
3666
3667end:
3668    if (det_ctx != NULL)
3669        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3670    if (de_ctx != NULL)
3671        SigGroupCleanup(de_ctx);
3672    if (de_ctx != NULL)
3673        DetectEngineCtxFree(de_ctx);
3674
3675    StreamTcpFreeConfig(TRUE);
3676    FLOW_DESTROY(&f);
3677    UTHFreePacket(p);
3678    return result;
3679}
3680
3681static int UriTestSig37(void)
3682{
3683    int result = 0;
3684    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3685        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3686    uint32_t http_buf_len = strlen((char *)http_buf);
3687    Flow f;
3688    TcpSession ssn;
3689    HtpState *http_state = NULL;
3690    Packet *p = NULL;
3691    ThreadVars tv;
3692    DetectEngineThreadCtx *det_ctx = NULL;
3693
3694    memset(&tv, 0, sizeof(ThreadVars));
3695    memset(&f, 0, sizeof(Flow));
3696    memset(&ssn, 0, sizeof(TcpSession));
3697
3698    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3699
3700    FLOW_INITIALIZE(&f);
3701    f.protoctx = (void *)&ssn;
3702    f.flags |= FLOW_IPV4;
3703
3704    p->flow = &f;
3705    p->flowflags |= FLOW_PKT_TOSERVER;
3706    p->flowflags |= FLOW_PKT_ESTABLISHED;
3707    f.alproto = ALPROTO_HTTP;
3708    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3709
3710    StreamTcpInitConfig(TRUE);
3711
3712    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3713    if (de_ctx == NULL) {
3714        goto end;
3715    }
3716    de_ctx->mpm_matcher = MPM_B2G;
3717    de_ctx->flags |= DE_QUIET;
3718
3719    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3720                               "(msg:\"test multiple relative uricontents\"; "
3721                               "urilen:17, raw; sid:1;)");
3722    if (de_ctx->sig_list == NULL) {
3723        goto end;
3724    }
3725
3726    SigGroupBuild(de_ctx);
3727    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3728
3729    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3730    if (r != 0) {
3731        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3732        goto end;
3733    }
3734
3735    http_state = f.alstate;
3736    if (http_state == NULL) {
3737        printf("no http state: ");
3738        goto end;
3739    }
3740
3741    /* do detect */
3742    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3743
3744    if (!PacketAlertCheck(p, 1)) {
3745        printf("sig 1 didn't alert, but it should have: ");
3746        goto end;
3747    }
3748
3749    result = 1;
3750
3751end:
3752    if (det_ctx != NULL)
3753        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3754    if (de_ctx != NULL)
3755        SigGroupCleanup(de_ctx);
3756    if (de_ctx != NULL)
3757        DetectEngineCtxFree(de_ctx);
3758
3759    StreamTcpFreeConfig(TRUE);
3760    FLOW_DESTROY(&f);
3761    UTHFreePacket(p);
3762    return result;
3763}
3764
3765static int UriTestSig38(void)
3766{
3767    int result = 0;
3768    uint8_t *http_buf = (uint8_t *)"POST /normalized%20uri "
3769        "HTTP/1.0\r\nUser-Agent: Mozilla/1.0\r\n";
3770    uint32_t http_buf_len = strlen((char *)http_buf);
3771    Flow f;
3772    TcpSession ssn;
3773    HtpState *http_state = NULL;
3774    Packet *p = NULL;
3775    ThreadVars tv;
3776    DetectEngineThreadCtx *det_ctx = NULL;
3777
3778    memset(&tv, 0, sizeof(ThreadVars));
3779    memset(&f, 0, sizeof(Flow));
3780    memset(&ssn, 0, sizeof(TcpSession));
3781
3782    p = UTHBuildPacket(http_buf, http_buf_len, IPPROTO_TCP);
3783
3784    FLOW_INITIALIZE(&f);
3785    f.protoctx = (void *)&ssn;
3786    f.flags |= FLOW_IPV4;
3787
3788    p->flow = &f;
3789    p->flowflags |= FLOW_PKT_TOSERVER;
3790    p->flowflags |= FLOW_PKT_ESTABLISHED;
3791    f.alproto = ALPROTO_HTTP;
3792    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
3793
3794    StreamTcpInitConfig(TRUE);
3795
3796    DetectEngineCtx *de_ctx = DetectEngineCtxInit();
3797    if (de_ctx == NULL) {
3798        goto end;
3799    }
3800    de_ctx->mpm_matcher = MPM_B2G;
3801    de_ctx->flags |= DE_QUIET;
3802
3803    de_ctx->sig_list = SigInit(de_ctx, "alert tcp any any -> any any "
3804                               "(msg:\"test multiple relative uricontents\"; "
3805                               "urilen:18, raw; sid:1;)");
3806    if (de_ctx->sig_list == NULL) {
3807        goto end;
3808    }
3809
3810    SigGroupBuild(de_ctx);
3811    DetectEngineThreadCtxInit(&tv, (void *)de_ctx, (void *)&det_ctx);
3812
3813    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_buf_len);
3814    if (r != 0) {
3815        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
3816        goto end;
3817    }
3818
3819    http_state = f.alstate;
3820    if (http_state == NULL) {
3821        printf("no http state: ");
3822        goto end;
3823    }
3824
3825    /* do detect */
3826    SigMatchSignatures(&tv, de_ctx, det_ctx, p);
3827
3828    if (PacketAlertCheck(p, 1)) {
3829        printf("sig 1 alerted, but it shouldn't have: ");
3830        goto end;
3831    }
3832
3833    result = 1;
3834
3835end:
3836    if (det_ctx != NULL)
3837        DetectEngineThreadCtxDeinit(&tv, det_ctx);
3838    if (de_ctx != NULL)
3839        SigGroupCleanup(de_ctx);
3840    if (de_ctx != NULL)
3841        DetectEngineCtxFree(de_ctx);
3842
3843    StreamTcpFreeConfig(TRUE);
3844    FLOW_DESTROY(&f);
3845    UTHFreePacket(p);
3846    return result;
3847}
3848
3849#endif /* UNITTESTS */
3850
3851void UriRegisterTests(void)
3852{
3853
3854#ifdef UNITTESTS
3855    UtRegisterTest("UriTestSig01", UriTestSig01, 1);
3856    UtRegisterTest("UriTestSig02", UriTestSig02, 1);
3857    UtRegisterTest("UriTestSig03", UriTestSig03, 1);
3858    UtRegisterTest("UriTestSig04", UriTestSig04, 1);
3859    UtRegisterTest("UriTestSig05", UriTestSig05, 1);
3860    UtRegisterTest("UriTestSig06", UriTestSig06, 1);
3861    UtRegisterTest("UriTestSig07", UriTestSig07, 1);
3862    UtRegisterTest("UriTestSig08", UriTestSig08, 1);
3863    UtRegisterTest("UriTestSig09", UriTestSig09, 1);
3864    UtRegisterTest("UriTestSig10", UriTestSig10, 1);
3865    UtRegisterTest("UriTestSig11", UriTestSig11, 1);
3866    UtRegisterTest("UriTestSig12", UriTestSig12, 1);
3867    UtRegisterTest("UriTestSig13", UriTestSig13, 1);
3868    UtRegisterTest("UriTestSig14", UriTestSig14, 1);
3869    UtRegisterTest("UriTestSig15", UriTestSig15, 1);
3870    UtRegisterTest("UriTestSig16", UriTestSig16, 1);
3871    UtRegisterTest("UriTestSig17", UriTestSig17, 1);
3872    UtRegisterTest("UriTestSig18", UriTestSig18, 1);
3873    UtRegisterTest("UriTestSig19", UriTestSig19, 1);
3874    UtRegisterTest("UriTestSig20", UriTestSig20, 1);
3875    UtRegisterTest("UriTestSig21", UriTestSig21, 1);
3876    UtRegisterTest("UriTestSig22", UriTestSig22, 1);
3877    UtRegisterTest("UriTestSig23", UriTestSig23, 1);
3878    UtRegisterTest("UriTestSig24", UriTestSig24, 1);
3879    UtRegisterTest("UriTestSig25", UriTestSig25, 1);
3880    UtRegisterTest("UriTestSig26", UriTestSig26, 1);
3881    UtRegisterTest("UriTestSig27", UriTestSig27, 1);
3882
3883    UtRegisterTest("UriTestSig28", UriTestSig28, 1);
3884    UtRegisterTest("UriTestSig29", UriTestSig29, 1);
3885    UtRegisterTest("UriTestSig30", UriTestSig30, 1);
3886    UtRegisterTest("UriTestSig31", UriTestSig31, 1);
3887    UtRegisterTest("UriTestSig32", UriTestSig32, 1);
3888    UtRegisterTest("UriTestSig33", UriTestSig33, 1);
3889    UtRegisterTest("UriTestSig34", UriTestSig34, 1);
3890    UtRegisterTest("UriTestSig35", UriTestSig35, 1);
3891    UtRegisterTest("UriTestSig36", UriTestSig36, 1);
3892    UtRegisterTest("UriTestSig37", UriTestSig37, 1);
3893    UtRegisterTest("UriTestSig38", UriTestSig38, 1);
3894#endif /* UNITTESTS */
3895
3896    return;
3897}