PageRenderTime 100ms CodeModel.GetById 12ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 0ms

/src/detect-engine-hmd.c

https://github.com/decanio/suricata-tilera
C | 1728 lines | 1298 code | 298 blank | 132 comment | 274 complexity | b9caeee6f55de83ba9a4e023e9577604 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/**
  19 * \ingroup httplayer
  20 *
  21 * @{
  22 */
  23
  24
  25/** \file
  26 *
  27 * \author Anoop Saldanha <anoopsaldanha@gmail.com>
  28 *
  29 * \brief Handle HTTP method match
  30 *
  31 */
  32
  33#include "suricata-common.h"
  34#include "suricata.h"
  35#include "decode.h"
  36
  37#include "detect.h"
  38#include "detect-engine.h"
  39#include "detect-engine-hmd.h"
  40#include "detect-engine-mpm.h"
  41#include "detect-parse.h"
  42#include "detect-engine-state.h"
  43#include "detect-engine-content-inspection.h"
  44
  45#include "flow-util.h"
  46#include "util-debug.h"
  47#include "util-print.h"
  48#include "flow.h"
  49
  50#include "app-layer-parser.h"
  51
  52#include "util-unittest.h"
  53#include "util-unittest-helper.h"
  54#include "app-layer.h"
  55#include "app-layer-htp.h"
  56#include "app-layer-protos.h"
  57
  58int DetectEngineRunHttpMethodMpm(DetectEngineThreadCtx *det_ctx, Flow *f,
  59                                 HtpState *htp_state, uint8_t flags)
  60{
  61    htp_tx_t *tx = NULL;
  62    uint32_t cnt = 0;
  63    int idx;
  64
  65    /* we need to lock because the buffers are not actually true buffers
  66     * but are ones that point to a buffer given by libhtp */
  67    FLOWLOCK_RDLOCK(f);
  68
  69    if (htp_state == NULL) {
  70        SCLogDebug("no HTTP state");
  71        goto end;
  72    }
  73
  74    if (htp_state->connp == NULL || htp_state->connp->conn == NULL) {
  75        SCLogDebug("HTP state has no conn(p)");
  76        goto end;
  77    }
  78
  79    idx = AppLayerTransactionGetInspectId(f);
  80    if (idx == -1) {
  81        goto end;
  82    }
  83
  84    int size = (int)list_size(htp_state->connp->conn->transactions);
  85    for (; idx < size; idx++) {
  86
  87        tx = list_get(htp_state->connp->conn->transactions, idx);
  88        if (tx == NULL || tx->request_method == NULL)
  89            continue;
  90
  91        cnt += HttpMethodPatternSearch(det_ctx,
  92                                       (uint8_t *)bstr_ptr(tx->request_method),
  93                                       bstr_len(tx->request_method),
  94                                       flags);
  95    }
  96
  97 end:
  98    FLOWLOCK_UNLOCK(f);
  99    return cnt;
 100}
 101
 102/**
 103 * \brief Do the http_method content inspection for a signature.
 104 *
 105 * \param de_ctx  Detection engine context.
 106 * \param det_ctx Detection engine thread context.
 107 * \param s       Signature to inspect.
 108 * \param f       Flow.
 109 * \param flags   App layer flags.
 110 * \param state   App layer state.
 111 *
 112 * \retval 0 No match.
 113 * \retval 1 Match.
 114 */
 115int DetectEngineInspectHttpMethod(ThreadVars *tv,
 116                                  DetectEngineCtx *de_ctx,
 117                                  DetectEngineThreadCtx *det_ctx,
 118                                  Signature *s, Flow *f, uint8_t flags,
 119                                  void *alstate, int tx_id)
 120{
 121    HtpState *htp_state = (HtpState *)alstate;
 122    htp_tx_t *tx = list_get(htp_state->connp->conn->transactions, tx_id);
 123    if (tx == NULL || tx->request_method == NULL)
 124        return 0;
 125
 126    det_ctx->buffer_offset = 0;
 127    det_ctx->discontinue_matching = 0;
 128    det_ctx->inspection_recursion_counter = 0;
 129    int r = DetectEngineContentInspection(de_ctx, det_ctx, s, s->sm_lists[DETECT_SM_LIST_HMDMATCH],
 130                                          f,
 131                                          (uint8_t *)bstr_ptr(tx->request_method),
 132                                          bstr_len(tx->request_method),
 133                                          DETECT_ENGINE_CONTENT_INSPECTION_MODE_HMD, NULL);
 134    if (r == 1)
 135        return 1;
 136
 137    return 0;
 138}
 139
 140/***********************************Unittests**********************************/
 141
 142#ifdef UNITTESTS
 143
 144/**
 145 * \test Test that the http_method content matches against a http request
 146 *       which holds the content.
 147 */
 148static int DetectEngineHttpMethodTest01(void)
 149{
 150    TcpSession ssn;
 151    Packet *p = NULL;
 152    ThreadVars th_v;
 153    DetectEngineCtx *de_ctx = NULL;
 154    DetectEngineThreadCtx *det_ctx = NULL;
 155    HtpState *http_state = NULL;
 156    Flow f;
 157    uint8_t http_buf[] =
 158        "GET /index.html HTTP/1.0\r\n"
 159        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 160    uint32_t http_len = sizeof(http_buf) - 1;
 161    int result = 0;
 162
 163    memset(&th_v, 0, sizeof(th_v));
 164    memset(&f, 0, sizeof(f));
 165    memset(&ssn, 0, sizeof(ssn));
 166
 167    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 168
 169    FLOW_INITIALIZE(&f);
 170    f.protoctx = (void *)&ssn;
 171    f.flags |= FLOW_IPV4;
 172    p->flow = &f;
 173    p->flowflags |= FLOW_PKT_TOSERVER;
 174    p->flowflags |= FLOW_PKT_ESTABLISHED;
 175    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 176    f.alproto = ALPROTO_HTTP;
 177
 178    StreamTcpInitConfig(TRUE);
 179
 180    de_ctx = DetectEngineCtxInit();
 181    if (de_ctx == NULL)
 182        goto end;
 183
 184    de_ctx->flags |= DE_QUIET;
 185
 186    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 187                               "(msg:\"http header test\"; "
 188                               "content:\"GET\"; http_method; "
 189                               "sid:1;)");
 190    if (de_ctx->sig_list == NULL)
 191        goto end;
 192
 193    SigGroupBuild(de_ctx);
 194    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 195
 196    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 197    if (r != 0) {
 198        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 199        result = 0;
 200        goto end;
 201    }
 202
 203    http_state = f.alstate;
 204    if (http_state == NULL) {
 205        printf("no http state: ");
 206        result = 0;
 207        goto end;
 208    }
 209
 210    /* do detect */
 211    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 212
 213    if (!(PacketAlertCheck(p, 1))) {
 214        printf("sid 1 didn't match but should have: ");
 215        goto end;
 216    }
 217
 218    result = 1;
 219
 220end:
 221    if (de_ctx != NULL)
 222        SigGroupCleanup(de_ctx);
 223    if (de_ctx != NULL)
 224        SigCleanSignatures(de_ctx);
 225    if (de_ctx != NULL)
 226        DetectEngineCtxFree(de_ctx);
 227
 228    StreamTcpFreeConfig(TRUE);
 229    FLOW_DESTROY(&f);
 230    UTHFreePackets(&p, 1);
 231    return result;
 232}
 233
 234/**
 235 * \test Test that the http_method content matches against a http request
 236 *       which holds the content.
 237 */
 238static int DetectEngineHttpMethodTest02(void)
 239{
 240    TcpSession ssn;
 241    Packet *p = NULL;
 242    ThreadVars th_v;
 243    DetectEngineCtx *de_ctx = NULL;
 244    DetectEngineThreadCtx *det_ctx = NULL;
 245    HtpState *http_state = NULL;
 246    Flow f;
 247    uint8_t http_buf[] =
 248        "CONNECT /index.html HTTP/1.0\r\n"
 249        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 250    uint32_t http_len = sizeof(http_buf) - 1;
 251    int result = 0;
 252
 253    memset(&th_v, 0, sizeof(th_v));
 254    memset(&f, 0, sizeof(f));
 255    memset(&ssn, 0, sizeof(ssn));
 256
 257    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 258
 259    FLOW_INITIALIZE(&f);
 260    f.protoctx = (void *)&ssn;
 261    f.flags |= FLOW_IPV4;
 262    p->flow = &f;
 263    p->flowflags |= FLOW_PKT_TOSERVER;
 264    p->flowflags |= FLOW_PKT_ESTABLISHED;
 265    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 266    f.alproto = ALPROTO_HTTP;
 267
 268    StreamTcpInitConfig(TRUE);
 269
 270    de_ctx = DetectEngineCtxInit();
 271    if (de_ctx == NULL)
 272        goto end;
 273
 274    de_ctx->flags |= DE_QUIET;
 275
 276    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 277                               "(msg:\"http header test\"; "
 278                               "content:\"CO\"; depth:4; http_method; "
 279                               "sid:1;)");
 280    if (de_ctx->sig_list == NULL)
 281        goto end;
 282
 283    SigGroupBuild(de_ctx);
 284    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 285
 286    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 287    if (r != 0) {
 288        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 289        result = 0;
 290        goto end;
 291    }
 292
 293    http_state = f.alstate;
 294    if (http_state == NULL) {
 295        printf("no http state: ");
 296        result = 0;
 297        goto end;
 298    }
 299
 300    /* do detect */
 301    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 302
 303    if (!(PacketAlertCheck(p, 1))) {
 304        printf("sid 1 didn't match but should have: ");
 305        goto end;
 306    }
 307
 308    result = 1;
 309
 310end:
 311    if (de_ctx != NULL)
 312        SigGroupCleanup(de_ctx);
 313    if (de_ctx != NULL)
 314        SigCleanSignatures(de_ctx);
 315    if (de_ctx != NULL)
 316        DetectEngineCtxFree(de_ctx);
 317
 318    StreamTcpFreeConfig(TRUE);
 319    FLOW_DESTROY(&f);
 320    UTHFreePackets(&p, 1);
 321    return result;
 322}
 323
 324/**
 325 * \test Test that the http_method content matches against a http request
 326 *       which holds the content.
 327 */
 328static int DetectEngineHttpMethodTest03(void)
 329{
 330    TcpSession ssn;
 331    Packet *p = NULL;
 332    ThreadVars th_v;
 333    DetectEngineCtx *de_ctx = NULL;
 334    DetectEngineThreadCtx *det_ctx = NULL;
 335    HtpState *http_state = NULL;
 336    Flow f;
 337    uint8_t http_buf[] =
 338        "CONNECT /index.html HTTP/1.0\r\n"
 339        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 340    uint32_t http_len = sizeof(http_buf) - 1;
 341    int result = 0;
 342
 343    memset(&th_v, 0, sizeof(th_v));
 344    memset(&f, 0, sizeof(f));
 345    memset(&ssn, 0, sizeof(ssn));
 346
 347    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 348
 349    FLOW_INITIALIZE(&f);
 350    f.protoctx = (void *)&ssn;
 351    f.flags |= FLOW_IPV4;
 352    p->flow = &f;
 353    p->flowflags |= FLOW_PKT_TOSERVER;
 354    p->flowflags |= FLOW_PKT_ESTABLISHED;
 355    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 356    f.alproto = ALPROTO_HTTP;
 357
 358    StreamTcpInitConfig(TRUE);
 359
 360    de_ctx = DetectEngineCtxInit();
 361    if (de_ctx == NULL)
 362        goto end;
 363
 364    de_ctx->flags |= DE_QUIET;
 365
 366    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 367                               "(msg:\"http header test\"; "
 368                               "content:!\"ECT\"; depth:4; http_method; "
 369                               "sid:1;)");
 370    if (de_ctx->sig_list == NULL)
 371        goto end;
 372
 373    SigGroupBuild(de_ctx);
 374    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 375
 376    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 377    if (r != 0) {
 378        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 379        result = 0;
 380        goto end;
 381    }
 382
 383    http_state = f.alstate;
 384    if (http_state == NULL) {
 385        printf("no http state: ");
 386        result = 0;
 387        goto end;
 388    }
 389
 390    /* do detect */
 391    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 392
 393    if (!(PacketAlertCheck(p, 1))) {
 394        printf("sid 1 didn't match but should have: ");
 395        goto end;
 396    }
 397
 398    result = 1;
 399
 400end:
 401    if (de_ctx != NULL)
 402        SigGroupCleanup(de_ctx);
 403    if (de_ctx != NULL)
 404        SigCleanSignatures(de_ctx);
 405    if (de_ctx != NULL)
 406        DetectEngineCtxFree(de_ctx);
 407
 408    StreamTcpFreeConfig(TRUE);
 409    FLOW_DESTROY(&f);
 410    UTHFreePackets(&p, 1);
 411    return result;
 412}
 413
 414/**
 415 * \test Test that the http_method content matches against a http request
 416 *       which holds the content.
 417 */
 418static int DetectEngineHttpMethodTest04(void)
 419{
 420    TcpSession ssn;
 421    Packet *p = NULL;
 422    ThreadVars th_v;
 423    DetectEngineCtx *de_ctx = NULL;
 424    DetectEngineThreadCtx *det_ctx = NULL;
 425    HtpState *http_state = NULL;
 426    Flow f;
 427    uint8_t http_buf[] =
 428        "CONNECT /index.html HTTP/1.0\r\n"
 429        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 430    uint32_t http_len = sizeof(http_buf) - 1;
 431    int result = 0;
 432
 433    memset(&th_v, 0, sizeof(th_v));
 434    memset(&f, 0, sizeof(f));
 435    memset(&ssn, 0, sizeof(ssn));
 436
 437    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 438
 439    FLOW_INITIALIZE(&f);
 440    f.protoctx = (void *)&ssn;
 441    f.flags |= FLOW_IPV4;
 442    p->flow = &f;
 443    p->flowflags |= FLOW_PKT_TOSERVER;
 444    p->flowflags |= FLOW_PKT_ESTABLISHED;
 445    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 446    f.alproto = ALPROTO_HTTP;
 447
 448    StreamTcpInitConfig(TRUE);
 449
 450    de_ctx = DetectEngineCtxInit();
 451    if (de_ctx == NULL)
 452        goto end;
 453
 454    de_ctx->flags |= DE_QUIET;
 455
 456    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 457                               "(msg:\"http header test\"; "
 458                               "content:\"ECT\"; depth:4; http_method; "
 459                               "sid:1;)");
 460    if (de_ctx->sig_list == NULL)
 461        goto end;
 462
 463    SigGroupBuild(de_ctx);
 464    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 465
 466    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 467    if (r != 0) {
 468        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 469        result = 0;
 470        goto end;
 471    }
 472
 473    http_state = f.alstate;
 474    if (http_state == NULL) {
 475        printf("no http state: ");
 476        result = 0;
 477        goto end;
 478    }
 479
 480    /* do detect */
 481    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 482
 483    if (PacketAlertCheck(p, 1)) {
 484        printf("sid 1 matched but shouldn't have: ");
 485        goto end;
 486    }
 487
 488    result = 1;
 489
 490end:
 491    if (de_ctx != NULL)
 492        SigGroupCleanup(de_ctx);
 493    if (de_ctx != NULL)
 494        SigCleanSignatures(de_ctx);
 495    if (de_ctx != NULL)
 496        DetectEngineCtxFree(de_ctx);
 497
 498    StreamTcpFreeConfig(TRUE);
 499    FLOW_DESTROY(&f);
 500    UTHFreePackets(&p, 1);
 501    return result;
 502}
 503
 504/**
 505 * \test Test that the http_method content matches against a http request
 506 *       which holds the content.
 507 */
 508static int DetectEngineHttpMethodTest05(void)
 509{
 510    TcpSession ssn;
 511    Packet *p = NULL;
 512    ThreadVars th_v;
 513    DetectEngineCtx *de_ctx = NULL;
 514    DetectEngineThreadCtx *det_ctx = NULL;
 515    HtpState *http_state = NULL;
 516    Flow f;
 517    uint8_t http_buf[] =
 518        "CONNECT /index.html HTTP/1.0\r\n"
 519        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 520    uint32_t http_len = sizeof(http_buf) - 1;
 521    int result = 0;
 522
 523    memset(&th_v, 0, sizeof(th_v));
 524    memset(&f, 0, sizeof(f));
 525    memset(&ssn, 0, sizeof(ssn));
 526
 527    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 528
 529    FLOW_INITIALIZE(&f);
 530    f.protoctx = (void *)&ssn;
 531    f.flags |= FLOW_IPV4;
 532    p->flow = &f;
 533    p->flowflags |= FLOW_PKT_TOSERVER;
 534    p->flowflags |= FLOW_PKT_ESTABLISHED;
 535    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 536    f.alproto = ALPROTO_HTTP;
 537
 538    StreamTcpInitConfig(TRUE);
 539
 540    de_ctx = DetectEngineCtxInit();
 541    if (de_ctx == NULL)
 542        goto end;
 543
 544    de_ctx->flags |= DE_QUIET;
 545
 546    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 547                               "(msg:\"http header test\"; "
 548                               "content:!\"CON\"; depth:4; http_method; "
 549                               "sid:1;)");
 550    if (de_ctx->sig_list == NULL)
 551        goto end;
 552
 553    SigGroupBuild(de_ctx);
 554    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 555
 556    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 557    if (r != 0) {
 558        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 559        result = 0;
 560        goto end;
 561    }
 562
 563    http_state = f.alstate;
 564    if (http_state == NULL) {
 565        printf("no http state: ");
 566        result = 0;
 567        goto end;
 568    }
 569
 570    /* do detect */
 571    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 572
 573    if (PacketAlertCheck(p, 1)) {
 574        printf("sid 1 matched but shouldn't have: ");
 575        goto end;
 576    }
 577
 578    result = 1;
 579
 580end:
 581    if (de_ctx != NULL)
 582        SigGroupCleanup(de_ctx);
 583    if (de_ctx != NULL)
 584        SigCleanSignatures(de_ctx);
 585    if (de_ctx != NULL)
 586        DetectEngineCtxFree(de_ctx);
 587
 588    StreamTcpFreeConfig(TRUE);
 589    FLOW_DESTROY(&f);
 590    UTHFreePackets(&p, 1);
 591    return result;
 592}
 593
 594/**
 595 * \test Test that the http_method content matches against a http request
 596 *       which holds the content.
 597 */
 598static int DetectEngineHttpMethodTest06(void)
 599{
 600    TcpSession ssn;
 601    Packet *p = NULL;
 602    ThreadVars th_v;
 603    DetectEngineCtx *de_ctx = NULL;
 604    DetectEngineThreadCtx *det_ctx = NULL;
 605    HtpState *http_state = NULL;
 606    Flow f;
 607    uint8_t http_buf[] =
 608        "CONNECT /index.html HTTP/1.0\r\n"
 609        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 610    uint32_t http_len = sizeof(http_buf) - 1;
 611    int result = 0;
 612
 613    memset(&th_v, 0, sizeof(th_v));
 614    memset(&f, 0, sizeof(f));
 615    memset(&ssn, 0, sizeof(ssn));
 616
 617    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 618
 619    FLOW_INITIALIZE(&f);
 620    f.protoctx = (void *)&ssn;
 621    f.flags |= FLOW_IPV4;
 622    p->flow = &f;
 623    p->flowflags |= FLOW_PKT_TOSERVER;
 624    p->flowflags |= FLOW_PKT_ESTABLISHED;
 625    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 626    f.alproto = ALPROTO_HTTP;
 627
 628    StreamTcpInitConfig(TRUE);
 629
 630    de_ctx = DetectEngineCtxInit();
 631    if (de_ctx == NULL)
 632        goto end;
 633
 634    de_ctx->flags |= DE_QUIET;
 635
 636    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 637                               "(msg:\"http header test\"; "
 638                               "content:\"ECT\"; offset:3; http_method; "
 639                               "sid:1;)");
 640    if (de_ctx->sig_list == NULL)
 641        goto end;
 642
 643    SigGroupBuild(de_ctx);
 644    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 645
 646    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 647    if (r != 0) {
 648        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 649        result = 0;
 650        goto end;
 651    }
 652
 653    http_state = f.alstate;
 654    if (http_state == NULL) {
 655        printf("no http state: ");
 656        result = 0;
 657        goto end;
 658    }
 659
 660    /* do detect */
 661    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 662
 663    if (!(PacketAlertCheck(p, 1))) {
 664        printf("sid 1 didn't match but should have: ");
 665        goto end;
 666    }
 667
 668    result = 1;
 669
 670end:
 671    if (de_ctx != NULL)
 672        SigGroupCleanup(de_ctx);
 673    if (de_ctx != NULL)
 674        SigCleanSignatures(de_ctx);
 675    if (de_ctx != NULL)
 676        DetectEngineCtxFree(de_ctx);
 677
 678    StreamTcpFreeConfig(TRUE);
 679    FLOW_DESTROY(&f);
 680    UTHFreePackets(&p, 1);
 681    return result;
 682}
 683
 684/**
 685 * \test Test that the http_method content matches against a http request
 686 *       which holds the content.
 687 */
 688static int DetectEngineHttpMethodTest07(void)
 689{
 690    TcpSession ssn;
 691    Packet *p = NULL;
 692    ThreadVars th_v;
 693    DetectEngineCtx *de_ctx = NULL;
 694    DetectEngineThreadCtx *det_ctx = NULL;
 695    HtpState *http_state = NULL;
 696    Flow f;
 697    uint8_t http_buf[] =
 698        "CONNECT /index.html HTTP/1.0\r\n"
 699        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 700    uint32_t http_len = sizeof(http_buf) - 1;
 701    int result = 0;
 702
 703    memset(&th_v, 0, sizeof(th_v));
 704    memset(&f, 0, sizeof(f));
 705    memset(&ssn, 0, sizeof(ssn));
 706
 707    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 708
 709    FLOW_INITIALIZE(&f);
 710    f.protoctx = (void *)&ssn;
 711    f.flags |= FLOW_IPV4;
 712    p->flow = &f;
 713    p->flowflags |= FLOW_PKT_TOSERVER;
 714    p->flowflags |= FLOW_PKT_ESTABLISHED;
 715    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 716    f.alproto = ALPROTO_HTTP;
 717
 718    StreamTcpInitConfig(TRUE);
 719
 720    de_ctx = DetectEngineCtxInit();
 721    if (de_ctx == NULL)
 722        goto end;
 723
 724    de_ctx->flags |= DE_QUIET;
 725
 726    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 727                               "(msg:\"http header test\"; "
 728                               "content:!\"CO\"; offset:3; http_method; "
 729                               "sid:1;)");
 730    if (de_ctx->sig_list == NULL)
 731        goto end;
 732
 733    SigGroupBuild(de_ctx);
 734    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 735
 736    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 737    if (r != 0) {
 738        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 739        result = 0;
 740        goto end;
 741    }
 742
 743    http_state = f.alstate;
 744    if (http_state == NULL) {
 745        printf("no http state: ");
 746        result = 0;
 747        goto end;
 748    }
 749
 750    /* do detect */
 751    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 752
 753    if (!(PacketAlertCheck(p, 1))) {
 754        printf("sid 1 didn't match but should have: ");
 755        goto end;
 756    }
 757
 758    result = 1;
 759
 760end:
 761    if (de_ctx != NULL)
 762        SigGroupCleanup(de_ctx);
 763    if (de_ctx != NULL)
 764        SigCleanSignatures(de_ctx);
 765    if (de_ctx != NULL)
 766        DetectEngineCtxFree(de_ctx);
 767
 768    StreamTcpFreeConfig(TRUE);
 769    FLOW_DESTROY(&f);
 770    UTHFreePackets(&p, 1);
 771    return result;
 772}
 773
 774/**
 775 * \test Test that the http_method content matches against a http request
 776 *       which holds the content.
 777 */
 778static int DetectEngineHttpMethodTest08(void)
 779{
 780    TcpSession ssn;
 781    Packet *p = NULL;
 782    ThreadVars th_v;
 783    DetectEngineCtx *de_ctx = NULL;
 784    DetectEngineThreadCtx *det_ctx = NULL;
 785    HtpState *http_state = NULL;
 786    Flow f;
 787    uint8_t http_buf[] =
 788        "CONNECT /index.html HTTP/1.0\r\n"
 789        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 790    uint32_t http_len = sizeof(http_buf) - 1;
 791    int result = 0;
 792
 793    memset(&th_v, 0, sizeof(th_v));
 794    memset(&f, 0, sizeof(f));
 795    memset(&ssn, 0, sizeof(ssn));
 796
 797    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 798
 799    FLOW_INITIALIZE(&f);
 800    f.protoctx = (void *)&ssn;
 801    f.flags |= FLOW_IPV4;
 802    p->flow = &f;
 803    p->flowflags |= FLOW_PKT_TOSERVER;
 804    p->flowflags |= FLOW_PKT_ESTABLISHED;
 805    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 806    f.alproto = ALPROTO_HTTP;
 807
 808    StreamTcpInitConfig(TRUE);
 809
 810    de_ctx = DetectEngineCtxInit();
 811    if (de_ctx == NULL)
 812        goto end;
 813
 814    de_ctx->flags |= DE_QUIET;
 815
 816    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 817                               "(msg:\"http header test\"; "
 818                               "content:!\"ECT\"; offset:3; http_method; "
 819                               "sid:1;)");
 820    if (de_ctx->sig_list == NULL)
 821        goto end;
 822
 823    SigGroupBuild(de_ctx);
 824    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 825
 826    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 827    if (r != 0) {
 828        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 829        result = 0;
 830        goto end;
 831    }
 832
 833    http_state = f.alstate;
 834    if (http_state == NULL) {
 835        printf("no http state: ");
 836        result = 0;
 837        goto end;
 838    }
 839
 840    /* do detect */
 841    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 842
 843    if (PacketAlertCheck(p, 1)) {
 844        printf("sid 1 matched but shouldn't have: ");
 845        goto end;
 846    }
 847
 848    result = 1;
 849
 850end:
 851    if (de_ctx != NULL)
 852        SigGroupCleanup(de_ctx);
 853    if (de_ctx != NULL)
 854        SigCleanSignatures(de_ctx);
 855    if (de_ctx != NULL)
 856        DetectEngineCtxFree(de_ctx);
 857
 858    StreamTcpFreeConfig(TRUE);
 859    FLOW_DESTROY(&f);
 860    UTHFreePackets(&p, 1);
 861    return result;
 862}
 863
 864/**
 865 * \test Test that the http_method content matches against a http request
 866 *       which holds the content.
 867 */
 868static int DetectEngineHttpMethodTest09(void)
 869{
 870    TcpSession ssn;
 871    Packet *p = NULL;
 872    ThreadVars th_v;
 873    DetectEngineCtx *de_ctx = NULL;
 874    DetectEngineThreadCtx *det_ctx = NULL;
 875    HtpState *http_state = NULL;
 876    Flow f;
 877    uint8_t http_buf[] =
 878        "CONNECT /index.html HTTP/1.0\r\n"
 879        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 880    uint32_t http_len = sizeof(http_buf) - 1;
 881    int result = 0;
 882
 883    memset(&th_v, 0, sizeof(th_v));
 884    memset(&f, 0, sizeof(f));
 885    memset(&ssn, 0, sizeof(ssn));
 886
 887    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 888
 889    FLOW_INITIALIZE(&f);
 890    f.protoctx = (void *)&ssn;
 891    f.flags |= FLOW_IPV4;
 892    p->flow = &f;
 893    p->flowflags |= FLOW_PKT_TOSERVER;
 894    p->flowflags |= FLOW_PKT_ESTABLISHED;
 895    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 896    f.alproto = ALPROTO_HTTP;
 897
 898    StreamTcpInitConfig(TRUE);
 899
 900    de_ctx = DetectEngineCtxInit();
 901    if (de_ctx == NULL)
 902        goto end;
 903
 904    de_ctx->flags |= DE_QUIET;
 905
 906    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 907                               "(msg:\"http header test\"; "
 908                               "content:\"CON\"; offset:3; http_method; "
 909                               "sid:1;)");
 910    if (de_ctx->sig_list == NULL)
 911        goto end;
 912
 913    SigGroupBuild(de_ctx);
 914    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
 915
 916    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
 917    if (r != 0) {
 918        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
 919        result = 0;
 920        goto end;
 921    }
 922
 923    http_state = f.alstate;
 924    if (http_state == NULL) {
 925        printf("no http state: ");
 926        result = 0;
 927        goto end;
 928    }
 929
 930    /* do detect */
 931    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
 932
 933    if (PacketAlertCheck(p, 1)) {
 934        printf("sid 1 matched but shouldn't have: ");
 935        goto end;
 936    }
 937
 938    result = 1;
 939
 940end:
 941    if (de_ctx != NULL)
 942        SigGroupCleanup(de_ctx);
 943    if (de_ctx != NULL)
 944        SigCleanSignatures(de_ctx);
 945    if (de_ctx != NULL)
 946        DetectEngineCtxFree(de_ctx);
 947
 948    StreamTcpFreeConfig(TRUE);
 949    FLOW_DESTROY(&f);
 950    UTHFreePackets(&p, 1);
 951    return result;
 952}
 953
 954/**
 955 * \test Test that the http_method content matches against a http request
 956 *       which holds the content.
 957 */
 958static int DetectEngineHttpMethodTest10(void)
 959{
 960    TcpSession ssn;
 961    Packet *p = NULL;
 962    ThreadVars th_v;
 963    DetectEngineCtx *de_ctx = NULL;
 964    DetectEngineThreadCtx *det_ctx = NULL;
 965    HtpState *http_state = NULL;
 966    Flow f;
 967    uint8_t http_buf[] =
 968        "CONNECT /index.html HTTP/1.0\r\n"
 969        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
 970    uint32_t http_len = sizeof(http_buf) - 1;
 971    int result = 0;
 972
 973    memset(&th_v, 0, sizeof(th_v));
 974    memset(&f, 0, sizeof(f));
 975    memset(&ssn, 0, sizeof(ssn));
 976
 977    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
 978
 979    FLOW_INITIALIZE(&f);
 980    f.protoctx = (void *)&ssn;
 981    f.flags |= FLOW_IPV4;
 982    p->flow = &f;
 983    p->flowflags |= FLOW_PKT_TOSERVER;
 984    p->flowflags |= FLOW_PKT_ESTABLISHED;
 985    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
 986    f.alproto = ALPROTO_HTTP;
 987
 988    StreamTcpInitConfig(TRUE);
 989
 990    de_ctx = DetectEngineCtxInit();
 991    if (de_ctx == NULL)
 992        goto end;
 993
 994    de_ctx->flags |= DE_QUIET;
 995
 996    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
 997                               "(msg:\"http header test\"; "
 998                               "content:\"CO\"; http_method; "
 999                               "content:\"EC\"; within:4; http_method; "
1000                               "sid:1;)");
1001    if (de_ctx->sig_list == NULL)
1002        goto end;
1003
1004    SigGroupBuild(de_ctx);
1005    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1006
1007    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1008    if (r != 0) {
1009        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1010        result = 0;
1011        goto end;
1012    }
1013
1014    http_state = f.alstate;
1015    if (http_state == NULL) {
1016        printf("no http state: ");
1017        result = 0;
1018        goto end;
1019    }
1020
1021    /* do detect */
1022    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1023
1024    if (!PacketAlertCheck(p, 1)) {
1025        printf("sid 1 didn't match but should have: ");
1026        goto end;
1027    }
1028
1029    result = 1;
1030
1031end:
1032    if (de_ctx != NULL)
1033        SigGroupCleanup(de_ctx);
1034    if (de_ctx != NULL)
1035        SigCleanSignatures(de_ctx);
1036    if (de_ctx != NULL)
1037        DetectEngineCtxFree(de_ctx);
1038
1039    StreamTcpFreeConfig(TRUE);
1040    FLOW_DESTROY(&f);
1041    UTHFreePackets(&p, 1);
1042    return result;
1043}
1044
1045/**
1046 * \test Test that the http_method content matches against a http request
1047 *       which holds the content.
1048 */
1049static int DetectEngineHttpMethodTest11(void)
1050{
1051    TcpSession ssn;
1052    Packet *p = NULL;
1053    ThreadVars th_v;
1054    DetectEngineCtx *de_ctx = NULL;
1055    DetectEngineThreadCtx *det_ctx = NULL;
1056    HtpState *http_state = NULL;
1057    Flow f;
1058    uint8_t http_buf[] =
1059        "CONNECT /index.html HTTP/1.0\r\n"
1060        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1061    uint32_t http_len = sizeof(http_buf) - 1;
1062    int result = 0;
1063
1064    memset(&th_v, 0, sizeof(th_v));
1065    memset(&f, 0, sizeof(f));
1066    memset(&ssn, 0, sizeof(ssn));
1067
1068    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1069
1070    FLOW_INITIALIZE(&f);
1071    f.protoctx = (void *)&ssn;
1072    f.flags |= FLOW_IPV4;
1073    p->flow = &f;
1074    p->flowflags |= FLOW_PKT_TOSERVER;
1075    p->flowflags |= FLOW_PKT_ESTABLISHED;
1076    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1077    f.alproto = ALPROTO_HTTP;
1078
1079    StreamTcpInitConfig(TRUE);
1080
1081    de_ctx = DetectEngineCtxInit();
1082    if (de_ctx == NULL)
1083        goto end;
1084
1085    de_ctx->flags |= DE_QUIET;
1086
1087    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1088                               "(msg:\"http header test\"; "
1089                               "content:\"CO\"; http_method; "
1090                               "content:!\"EC\"; within:3; http_method; "
1091                               "sid:1;)");
1092    if (de_ctx->sig_list == NULL)
1093        goto end;
1094
1095    SigGroupBuild(de_ctx);
1096    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1097
1098    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1099    if (r != 0) {
1100        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1101        result = 0;
1102        goto end;
1103    }
1104
1105    http_state = f.alstate;
1106    if (http_state == NULL) {
1107        printf("no http state: ");
1108        result = 0;
1109        goto end;
1110    }
1111
1112    /* do detect */
1113    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1114
1115    if (!PacketAlertCheck(p, 1)) {
1116        printf("sid 1 didn't match but should have: ");
1117        goto end;
1118    }
1119
1120    result = 1;
1121
1122end:
1123    if (de_ctx != NULL)
1124        SigGroupCleanup(de_ctx);
1125    if (de_ctx != NULL)
1126        SigCleanSignatures(de_ctx);
1127    if (de_ctx != NULL)
1128        DetectEngineCtxFree(de_ctx);
1129
1130    StreamTcpFreeConfig(TRUE);
1131    FLOW_DESTROY(&f);
1132    UTHFreePackets(&p, 1);
1133    return result;
1134}
1135
1136/**
1137 * \test Test that the http_method content matches against a http request
1138 *       which holds the content.
1139 */
1140static int DetectEngineHttpMethodTest12(void)
1141{
1142    TcpSession ssn;
1143    Packet *p = NULL;
1144    ThreadVars th_v;
1145    DetectEngineCtx *de_ctx = NULL;
1146    DetectEngineThreadCtx *det_ctx = NULL;
1147    HtpState *http_state = NULL;
1148    Flow f;
1149    uint8_t http_buf[] =
1150        "CONNECT /index.html HTTP/1.0\r\n"
1151        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1152    uint32_t http_len = sizeof(http_buf) - 1;
1153    int result = 0;
1154
1155    memset(&th_v, 0, sizeof(th_v));
1156    memset(&f, 0, sizeof(f));
1157    memset(&ssn, 0, sizeof(ssn));
1158
1159    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1160
1161    FLOW_INITIALIZE(&f);
1162    f.protoctx = (void *)&ssn;
1163    f.flags |= FLOW_IPV4;
1164    p->flow = &f;
1165    p->flowflags |= FLOW_PKT_TOSERVER;
1166    p->flowflags |= FLOW_PKT_ESTABLISHED;
1167    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1168    f.alproto = ALPROTO_HTTP;
1169
1170    StreamTcpInitConfig(TRUE);
1171
1172    de_ctx = DetectEngineCtxInit();
1173    if (de_ctx == NULL)
1174        goto end;
1175
1176    de_ctx->flags |= DE_QUIET;
1177
1178    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1179                               "(msg:\"http header test\"; "
1180                               "content:\"CO\"; http_method; "
1181                               "content:\"EC\"; within:3; http_method; "
1182                               "sid:1;)");
1183    if (de_ctx->sig_list == NULL)
1184        goto end;
1185
1186    SigGroupBuild(de_ctx);
1187    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1188
1189    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1190    if (r != 0) {
1191        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1192        result = 0;
1193        goto end;
1194    }
1195
1196    http_state = f.alstate;
1197    if (http_state == NULL) {
1198        printf("no http state: ");
1199        result = 0;
1200        goto end;
1201    }
1202
1203    /* do detect */
1204    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1205
1206    if (PacketAlertCheck(p, 1)) {
1207        printf("sid 1 matched but shouldn't have: ");
1208        goto end;
1209    }
1210
1211    result = 1;
1212
1213end:
1214    if (de_ctx != NULL)
1215        SigGroupCleanup(de_ctx);
1216    if (de_ctx != NULL)
1217        SigCleanSignatures(de_ctx);
1218    if (de_ctx != NULL)
1219        DetectEngineCtxFree(de_ctx);
1220
1221    StreamTcpFreeConfig(TRUE);
1222    FLOW_DESTROY(&f);
1223    UTHFreePackets(&p, 1);
1224    return result;
1225}
1226
1227/**
1228 * \test Test that the http_method content matches against a http request
1229 *       which holds the content.
1230 */
1231static int DetectEngineHttpMethodTest13(void)
1232{
1233    TcpSession ssn;
1234    Packet *p = NULL;
1235    ThreadVars th_v;
1236    DetectEngineCtx *de_ctx = NULL;
1237    DetectEngineThreadCtx *det_ctx = NULL;
1238    HtpState *http_state = NULL;
1239    Flow f;
1240    uint8_t http_buf[] =
1241        "CONNECT /index.html HTTP/1.0\r\n"
1242        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1243    uint32_t http_len = sizeof(http_buf) - 1;
1244    int result = 0;
1245
1246    memset(&th_v, 0, sizeof(th_v));
1247    memset(&f, 0, sizeof(f));
1248    memset(&ssn, 0, sizeof(ssn));
1249
1250    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1251
1252    FLOW_INITIALIZE(&f);
1253    f.protoctx = (void *)&ssn;
1254    f.flags |= FLOW_IPV4;
1255    p->flow = &f;
1256    p->flowflags |= FLOW_PKT_TOSERVER;
1257    p->flowflags |= FLOW_PKT_ESTABLISHED;
1258    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1259    f.alproto = ALPROTO_HTTP;
1260
1261    StreamTcpInitConfig(TRUE);
1262
1263    de_ctx = DetectEngineCtxInit();
1264    if (de_ctx == NULL)
1265        goto end;
1266
1267    de_ctx->flags |= DE_QUIET;
1268
1269    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1270                               "(msg:\"http header test\"; "
1271                               "content:\"CO\"; http_method; "
1272                               "content:!\"EC\"; within:4; http_method; "
1273                               "sid:1;)");
1274    if (de_ctx->sig_list == NULL)
1275        goto end;
1276
1277    SigGroupBuild(de_ctx);
1278    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1279
1280    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1281    if (r != 0) {
1282        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1283        result = 0;
1284        goto end;
1285    }
1286
1287    http_state = f.alstate;
1288    if (http_state == NULL) {
1289        printf("no http state: ");
1290        result = 0;
1291        goto end;
1292    }
1293
1294    /* do detect */
1295    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1296
1297    if (PacketAlertCheck(p, 1)) {
1298        printf("sid 1 matched but shouldn't have: ");
1299        goto end;
1300    }
1301
1302    result = 1;
1303
1304end:
1305    if (de_ctx != NULL)
1306        SigGroupCleanup(de_ctx);
1307    if (de_ctx != NULL)
1308        SigCleanSignatures(de_ctx);
1309    if (de_ctx != NULL)
1310        DetectEngineCtxFree(de_ctx);
1311
1312    StreamTcpFreeConfig(TRUE);
1313    FLOW_DESTROY(&f);
1314    UTHFreePackets(&p, 1);
1315    return result;
1316}
1317
1318/**
1319 * \test Test that the http_method content matches against a http request
1320 *       which holds the content.
1321 */
1322static int DetectEngineHttpMethodTest14(void)
1323{
1324    TcpSession ssn;
1325    Packet *p = NULL;
1326    ThreadVars th_v;
1327    DetectEngineCtx *de_ctx = NULL;
1328    DetectEngineThreadCtx *det_ctx = NULL;
1329    HtpState *http_state = NULL;
1330    Flow f;
1331    uint8_t http_buf[] =
1332        "CONNECT /index.html HTTP/1.0\r\n"
1333        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1334    uint32_t http_len = sizeof(http_buf) - 1;
1335    int result = 0;
1336
1337    memset(&th_v, 0, sizeof(th_v));
1338    memset(&f, 0, sizeof(f));
1339    memset(&ssn, 0, sizeof(ssn));
1340
1341    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1342
1343    FLOW_INITIALIZE(&f);
1344    f.protoctx = (void *)&ssn;
1345    f.flags |= FLOW_IPV4;
1346    p->flow = &f;
1347    p->flowflags |= FLOW_PKT_TOSERVER;
1348    p->flowflags |= FLOW_PKT_ESTABLISHED;
1349    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1350    f.alproto = ALPROTO_HTTP;
1351
1352    StreamTcpInitConfig(TRUE);
1353
1354    de_ctx = DetectEngineCtxInit();
1355    if (de_ctx == NULL)
1356        goto end;
1357
1358    de_ctx->flags |= DE_QUIET;
1359
1360    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1361                               "(msg:\"http header test\"; "
1362                               "content:\"CO\"; http_method; "
1363                               "content:\"EC\"; distance:2; http_method; "
1364                               "sid:1;)");
1365    if (de_ctx->sig_list == NULL)
1366        goto end;
1367
1368    SigGroupBuild(de_ctx);
1369    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1370
1371    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1372    if (r != 0) {
1373        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1374        result = 0;
1375        goto end;
1376    }
1377
1378    http_state = f.alstate;
1379    if (http_state == NULL) {
1380        printf("no http state: ");
1381        result = 0;
1382        goto end;
1383    }
1384
1385    /* do detect */
1386    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1387
1388    if (!PacketAlertCheck(p, 1)) {
1389        printf("sid 1 didn't match but should have: ");
1390        goto end;
1391    }
1392
1393    result = 1;
1394
1395end:
1396    if (de_ctx != NULL)
1397        SigGroupCleanup(de_ctx);
1398    if (de_ctx != NULL)
1399        SigCleanSignatures(de_ctx);
1400    if (de_ctx != NULL)
1401        DetectEngineCtxFree(de_ctx);
1402
1403    StreamTcpFreeConfig(TRUE);
1404    FLOW_DESTROY(&f);
1405    UTHFreePackets(&p, 1);
1406    return result;
1407}
1408
1409/**
1410 * \test Test that the http_method content matches against a http request
1411 *       which holds the content.
1412 */
1413static int DetectEngineHttpMethodTest15(void)
1414{
1415    TcpSession ssn;
1416    Packet *p = NULL;
1417    ThreadVars th_v;
1418    DetectEngineCtx *de_ctx = NULL;
1419    DetectEngineThreadCtx *det_ctx = NULL;
1420    HtpState *http_state = NULL;
1421    Flow f;
1422    uint8_t http_buf[] =
1423        "CONNECT /index.html HTTP/1.0\r\n"
1424        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1425    uint32_t http_len = sizeof(http_buf) - 1;
1426    int result = 0;
1427
1428    memset(&th_v, 0, sizeof(th_v));
1429    memset(&f, 0, sizeof(f));
1430    memset(&ssn, 0, sizeof(ssn));
1431
1432    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1433
1434    FLOW_INITIALIZE(&f);
1435    f.protoctx = (void *)&ssn;
1436    f.flags |= FLOW_IPV4;
1437    p->flow = &f;
1438    p->flowflags |= FLOW_PKT_TOSERVER;
1439    p->flowflags |= FLOW_PKT_ESTABLISHED;
1440    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1441    f.alproto = ALPROTO_HTTP;
1442
1443    StreamTcpInitConfig(TRUE);
1444
1445    de_ctx = DetectEngineCtxInit();
1446    if (de_ctx == NULL)
1447        goto end;
1448
1449    de_ctx->flags |= DE_QUIET;
1450
1451    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1452                               "(msg:\"http header test\"; "
1453                               "content:\"CO\"; http_method; "
1454                               "content:!\"EC\"; distance:3; http_method; "
1455                               "sid:1;)");
1456    if (de_ctx->sig_list == NULL)
1457        goto end;
1458
1459    SigGroupBuild(de_ctx);
1460    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1461
1462    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1463    if (r != 0) {
1464        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1465        result = 0;
1466        goto end;
1467    }
1468
1469    http_state = f.alstate;
1470    if (http_state == NULL) {
1471        printf("no http state: ");
1472        result = 0;
1473        goto end;
1474    }
1475
1476    /* do detect */
1477    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1478
1479    if (!PacketAlertCheck(p, 1)) {
1480        printf("sid 1 didn't match but should have: ");
1481        goto end;
1482    }
1483
1484    result = 1;
1485
1486end:
1487    if (de_ctx != NULL)
1488        SigGroupCleanup(de_ctx);
1489    if (de_ctx != NULL)
1490        SigCleanSignatures(de_ctx);
1491    if (de_ctx != NULL)
1492        DetectEngineCtxFree(de_ctx);
1493
1494    StreamTcpFreeConfig(TRUE);
1495    FLOW_DESTROY(&f);
1496    UTHFreePackets(&p, 1);
1497    return result;
1498}
1499
1500/**
1501 * \test Test that the http_method content matches against a http request
1502 *       which holds the content.
1503 */
1504static int DetectEngineHttpMethodTest16(void)
1505{
1506    TcpSession ssn;
1507    Packet *p = NULL;
1508    ThreadVars th_v;
1509    DetectEngineCtx *de_ctx = NULL;
1510    DetectEngineThreadCtx *det_ctx = NULL;
1511    HtpState *http_state = NULL;
1512    Flow f;
1513    uint8_t http_buf[] =
1514        "CONNECT /index.html HTTP/1.0\r\n"
1515        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1516    uint32_t http_len = sizeof(http_buf) - 1;
1517    int result = 0;
1518
1519    memset(&th_v, 0, sizeof(th_v));
1520    memset(&f, 0, sizeof(f));
1521    memset(&ssn, 0, sizeof(ssn));
1522
1523    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1524
1525    FLOW_INITIALIZE(&f);
1526    f.protoctx = (void *)&ssn;
1527    f.flags |= FLOW_IPV4;
1528    p->flow = &f;
1529    p->flowflags |= FLOW_PKT_TOSERVER;
1530    p->flowflags |= FLOW_PKT_ESTABLISHED;
1531    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1532    f.alproto = ALPROTO_HTTP;
1533
1534    StreamTcpInitConfig(TRUE);
1535
1536    de_ctx = DetectEngineCtxInit();
1537    if (de_ctx == NULL)
1538        goto end;
1539
1540    de_ctx->flags |= DE_QUIET;
1541
1542    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1543                               "(msg:\"http header test\"; "
1544                               "content:\"CO\"; http_method; "
1545                               "content:\"EC\"; distance:3; http_method; "
1546                               "sid:1;)");
1547    if (de_ctx->sig_list == NULL)
1548        goto end;
1549
1550    SigGroupBuild(de_ctx);
1551    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1552
1553    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1554    if (r != 0) {
1555        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1556        result = 0;
1557        goto end;
1558    }
1559
1560    http_state = f.alstate;
1561    if (http_state == NULL) {
1562        printf("no http state: ");
1563        result = 0;
1564        goto end;
1565    }
1566
1567    /* do detect */
1568    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1569
1570    if (PacketAlertCheck(p, 1)) {
1571        printf("sid 1 matched but shouldn't have: ");
1572        goto end;
1573    }
1574
1575    result = 1;
1576
1577end:
1578    if (de_ctx != NULL)
1579        SigGroupCleanup(de_ctx);
1580    if (de_ctx != NULL)
1581        SigCleanSignatures(de_ctx);
1582    if (de_ctx != NULL)
1583        DetectEngineCtxFree(de_ctx);
1584
1585    StreamTcpFreeConfig(TRUE);
1586    FLOW_DESTROY(&f);
1587    UTHFreePackets(&p, 1);
1588    return result;
1589}
1590
1591/**
1592 * \test Test that the http_method content matches against a http request
1593 *       which holds the content.
1594 */
1595static int DetectEngineHttpMethodTest17(void)
1596{
1597    TcpSession ssn;
1598    Packet *p = NULL;
1599    ThreadVars th_v;
1600    DetectEngineCtx *de_ctx = NULL;
1601    DetectEngineThreadCtx *det_ctx = NULL;
1602    HtpState *http_state = NULL;
1603    Flow f;
1604    uint8_t http_buf[] =
1605        "CONNECT /index.html HTTP/1.0\r\n"
1606        "Host: www.onetwothreefourfivesixseven.org\r\n\r\n";
1607    uint32_t http_len = sizeof(http_buf) - 1;
1608    int result = 0;
1609
1610    memset(&th_v, 0, sizeof(th_v));
1611    memset(&f, 0, sizeof(f));
1612    memset(&ssn, 0, sizeof(ssn));
1613
1614    p = UTHBuildPacket(NULL, 0, IPPROTO_TCP);
1615
1616    FLOW_INITIALIZE(&f);
1617    f.protoctx = (void *)&ssn;
1618    f.flags |= FLOW_IPV4;
1619    p->flow = &f;
1620    p->flowflags |= FLOW_PKT_TOSERVER;
1621    p->flowflags |= FLOW_PKT_ESTABLISHED;
1622    p->flags |= PKT_HAS_FLOW|PKT_STREAM_EST;
1623    f.alproto = ALPROTO_HTTP;
1624
1625    StreamTcpInitConfig(TRUE);
1626
1627    de_ctx = DetectEngineCtxInit();
1628    if (de_ctx == NULL)
1629        goto end;
1630
1631    de_ctx->flags |= DE_QUIET;
1632
1633    de_ctx->sig_list = SigInit(de_ctx,"alert http any any -> any any "
1634                               "(msg:\"http header test\"; "
1635                               "content:\"CO\"; http_method; "
1636                               "content:!\"EC\"; distance:2; http_method; "
1637                               "sid:1;)");
1638    if (de_ctx->sig_list == NULL)
1639        goto end;
1640
1641    SigGroupBuild(de_ctx);
1642    DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
1643
1644    int r = AppLayerParse(NULL, &f, ALPROTO_HTTP, STREAM_TOSERVER, http_buf, http_len);
1645    if (r != 0) {
1646        printf("toserver chunk 1 returned %" PRId32 ", expected 0: ", r);
1647        result = 0;
1648        goto end;
1649    }
1650
1651    http_state = f.alstate;
1652    if (http_state == NULL) {
1653        printf("no http state: ");
1654        result = 0;
1655        goto end;
1656    }
1657
1658    /* do detect */
1659    SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
1660
1661    if (PacketAlertCheck(p, 1)) {
1662        printf("sid 1 matched but shouldn't have: ");
1663        goto end;
1664    }
1665
1666    result = 1;
1667
1668end:
1669    if (de_ctx != NULL)
1670        SigGroupCleanup(de_ctx);
1671    if (de_ctx != NULL)
1672        SigCleanSignatures(de_ctx);
1673    if (de_ctx != NULL)
1674        DetectEngineCtxFree(de_ctx);
1675
1676    StreamTcpFreeConfig(TRUE);
1677    FLOW_DESTROY(&f);
1678    UTHFreePackets(&p, 1);
1679    return result;
1680}
1681
1682#endif /* UNITTESTS */
1683
1684void DetectEngineHttpMethodRegisterTests(void)
1685{
1686
1687#ifdef UNITTESTS
1688    UtRegisterTest("DetectEngineHttpMethodTest01",
1689                   DetectEngineHttpMethodTest01, 1);
1690    UtRegisterTest("DetectEngineHttpMethodTest02",
1691                   DetectEngineHttpMethodTest02, 1);
1692    UtRegisterTest("DetectEngineHttpMethodTest03",
1693                   DetectEngineHttpMethodTest03, 1);
1694    UtRegisterTest("DetectEngineHttpMethodTest04",
1695                   DetectEngineHttpMethodTest04, 1);
1696    UtRegisterTest("DetectEngineHttpMethodTest05",
1697                   DetectEngineHttpMethodTest05, 1);
1698    UtRegisterTest("DetectEngineHttpMethodTest06",
1699                   DetectEngineHttpMethodTest06, 1);
1700    UtRegisterTest("DetectEngineHttpMethodTest07",
1701                   DetectEngineHttpMethodTest07, 1);
1702    UtRegisterTest("DetectEngineHttpMethodTest08",
1703                   DetectEngineHttpMethodTest08, 1);
1704    UtRegisterTest("DetectEngineHttpMethodTest09",
1705                   DetectEngineHttpMethodTest09, 1);
1706    UtRegisterTest("DetectEngineHttpMethodTest10",
1707                   DetectEngineHttpMethodTest10, 1);
1708    UtRegisterTest("DetectEngineHttpMethodTest11",
1709                   DetectEngineHttpMethodTest11, 1);
1710    UtRegisterTest("DetectEngineHttpMethodTest12",
1711                   DetectEngineHttpMethodTest12, 1);
1712    UtRegisterTest("DetectEngineHttpMethodTest13",
1713                   DetectEngineHttpMethodTest13, 1);
1714    UtRegisterTest("DetectEngineHttpMethodTest14",
1715                   DetectEngineHttpMethodTest14, 1);
1716    UtRegisterTest("DetectEngineHttpMethodTest15",
1717                   DetectEngineHttpMethodTest15, 1);
1718    UtRegisterTest("DetectEngineHttpMethodTest16",
1719                   DetectEngineHttpMethodTest16, 1);
1720    UtRegisterTest("DetectEngineHttpMethodTest17",
1721                   DetectEngineHttpMethodTest17, 1);
1722#endif /* UNITTESTS */
1723
1724    return;
1725}
1726/**
1727 * @}
1728 */