Skip to content

Commit 30ffc30

Browse files
committed
jsch action is implemented.
1 parent 930ba7d commit 30ffc30

File tree

8 files changed

+129
-56
lines changed

8 files changed

+129
-56
lines changed

fw/http.c

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ static struct {
150150
* here, because it refers to HTTP layer.
151151
*/
152152
unsigned int max_header_list_size = 0;
153+
bool is_jsch_global = true;
153154

154155
#define S_CRLFCRLF "\r\n\r\n"
155156
#define S_HTTP "http://"
@@ -6034,6 +6035,15 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
60346035
"request has been filtered out via http table",
60356036
HTTP2_ECODE_PROTO);
60366037
}
6038+
if (res.type == TFW_HTTP_RES_JSCH) {
6039+
req->need_jsch = true;
6040+
req->vhost = res.vhost;
6041+
pr_notice("req->need_jsch = true\n");
6042+
}
6043+
else {
6044+
req->need_jsch = is_jsch_global;
6045+
pr_notice("req->need_jsch = false\n");
6046+
}
60376047
if (res.type == TFW_HTTP_RES_VHOST) {
60386048
req->vhost = res.vhost;
60396049
}
@@ -6139,37 +6149,39 @@ tfw_http_req_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
61396149
* to GET. We should send js challenge to the client because the real
61406150
* method, expected by the client is GET.
61416151
*/
6142-
switch (tfw_http_sess_obtain(req)) {
6143-
case TFW_HTTP_SESS_SUCCESS:
6144-
break;
6152+
if (req->need_jsch) {
6153+
switch (tfw_http_sess_obtain(req)) {
6154+
case TFW_HTTP_SESS_SUCCESS:
6155+
break;
61456156

6146-
case TFW_HTTP_SESS_REDIRECT_NEED:
6147-
/* Response is built and stored in @req->resp. */
6148-
break;
6157+
case TFW_HTTP_SESS_REDIRECT_NEED:
6158+
/* Response is built and stored in @req->resp. */
6159+
break;
61496160

6150-
case TFW_HTTP_SESS_VIOLATE:
6151-
TFW_INC_STAT_BH(clnt.msgs_filtout);
6152-
return tfw_http_req_parse_block(req, 403, NULL,
6153-
HTTP2_ECODE_PROTO);
6161+
case TFW_HTTP_SESS_VIOLATE:
6162+
TFW_INC_STAT_BH(clnt.msgs_filtout);
6163+
return tfw_http_req_parse_block(req, 403, NULL,
6164+
HTTP2_ECODE_PROTO);
61546165

6155-
case TFW_HTTP_SESS_JS_NOT_SUPPORTED:
6156-
/*
6157-
* Requested resource can't be challenged, try service it
6158-
* from cache.
6159-
*/
6160-
T_DBG("Can't send JS challenge for request since a "
6161-
"non-challengeable resource (e.g. image) was requested");
6162-
__set_bit(TFW_HTTP_B_JS_NOT_SUPPORTED, req->flags);
6163-
break;
6166+
case TFW_HTTP_SESS_JS_NOT_SUPPORTED:
6167+
/*
6168+
* Requested resource can't be challenged, try service it
6169+
* from cache.
6170+
*/
6171+
T_DBG("Can't send JS challenge for request since a "
6172+
"non-challengeable resource (e.g. image) was requested");
6173+
__set_bit(TFW_HTTP_B_JS_NOT_SUPPORTED, req->flags);
6174+
break;
61646175

6165-
case TFW_HTTP_SESS_FAILURE:
6166-
TFW_INC_STAT_BH(clnt.msgs_otherr);
6167-
return tfw_http_req_parse_drop_with_fin(req, 500,
6168-
"request dropped: internal error"
6169-
" in Sticky module",
6170-
HTTP2_ECODE_PROTO);
6171-
default:
6172-
BUG();
6176+
case TFW_HTTP_SESS_FAILURE:
6177+
TFW_INC_STAT_BH(clnt.msgs_otherr);
6178+
return tfw_http_req_parse_drop_with_fin(req, 500,
6179+
"request dropped: internal error"
6180+
" in Sticky module",
6181+
HTTP2_ECODE_PROTO);
6182+
default:
6183+
BUG();
6184+
}
61736185
}
61746186

61756187
if (TFW_MSG_H2(req))

fw/http.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ struct tfw_http_req_t {
400400
unsigned char method_override;
401401
unsigned int header_list_sz;
402402
unsigned int headers_cnt;
403+
bool need_jsch;
403404
};
404405

405406
#define TFW_IDX_BITS 24
@@ -722,6 +723,7 @@ typedef void (*tfw_http_cache_cb_t)(TfwHttpMsg *);
722723
(TFW_MSG_H2(hmmsg) ? HTTP2_EXTRA_HDR_OVERHEAD : 0)
723724

724725
extern unsigned int max_header_list_size;
726+
extern bool is_jsch_global;
725727

726728
/* External HTTP functions. */
727729
int tfw_http_msg_process(TfwConn *conn, struct sk_buff *skb,

fw/http_match.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,9 @@ do_eval(TfwHttpReq *req, const TfwHttpMatchRule *rule)
483483
match_fn match_fn;
484484
tfw_http_match_fld_t field;
485485

486+
pr_notice("rule: %p, field: %#x, op: %#x, arg:%d:%d'%.*s'\n",
487+
rule, rule->field, rule->op, rule->arg.type, rule->arg.len,
488+
rule->arg.len, rule->arg.str);
486489
T_DBG2("rule: %p, field: %#x, op: %#x, arg:%d:%d'%.*s'\n",
487490
rule, rule->field, rule->op, rule->arg.type, rule->arg.len,
488491
rule->arg.len, rule->arg.str);
@@ -558,7 +561,7 @@ TfwHttpMatchRule *
558561
tfw_http_match_req(TfwHttpReq *req, struct list_head *mlst)
559562
{
560563
TfwHttpMatchRule *rule;
561-
564+
pr_notice("Matching request: %p, list: %p\n", req, mlst);
562565
T_DBG2("Matching request: %p, list: %p\n", req, mlst);
563566

564567
list_for_each_entry(rule, mlst, list) {

fw/http_match.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef enum {
7676
TFW_HTTP_MATCH_ACT_BLOCK,
7777
TFW_HTTP_MATCH_ACT_FLAG,
7878
TFW_HTTP_MATCH_ACT_CACHE_TTL,
79+
TFW_HTTP_MATCH_ACT_JSCH,
7980
_TFW_HTTP_MATCH_ACT_COUNT
8081
} tfw_http_rule_act_t;
8182

fw/http_sess.c

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ tfw_http_sticky_get_req(TfwHttpReq *req, TfwStr *cookie_val)
207207
TfwStr *hdr, *end, *dup;
208208
int r = 0;
209209

210+
pr_notice("tfw_http_sticky_get_req\n");
210211
/*
211212
* Find a 'Cookie:' header field in the request. Then search for
212213
* Tempesta sticky cookie within the field. In HTTP/1.x requests
@@ -498,6 +499,7 @@ tfw_http_sticky_verify(TfwHttpReq *req, TfwStr *value, StickyVal *sv)
498499
TfwStr *c, *end;
499500
TfwStickyCookie *sticky = req->vhost->cookie;
500501

502+
pr_notice("tfw_http_sticky_verify\n");
501503
T_DBG("Sticky cookie found: \"%.*s\" = \"%.*s\"%s\n",
502504
PR_TFW_STR(&sticky->name),
503505
TFW_STR_PLAIN(value) ?
@@ -508,8 +510,10 @@ tfw_http_sticky_verify(TfwHttpReq *req, TfwStr *value, StickyVal *sv)
508510
value->chunks->data,
509511
TFW_STR_PLAIN(value) ? "" : "<truncated>");
510512

511-
if (sticky->learn)
513+
if (sticky->learn) {
514+
pr_notice("sticky->learn\n");
512515
return TFW_HTTP_SESS_SUCCESS;
516+
}
513517

514518
if (value->len != sizeof(StickyVal) * 2) {
515519
sess_warn("bad sticky cookie length", addr, " %lu(%lu)\n",
@@ -530,6 +534,11 @@ tfw_http_sticky_verify(TfwHttpReq *req, TfwStr *value, StickyVal *sv)
530534
return r;
531535

532536
/* The cookie is valid but already expired, reject it. */
537+
pr_notice("jiffies=%lu sv->ts=%lu sticky->sess_lifetime * HZ=%lu sticky->sess_lifetime=%i",
538+
jiffies,
539+
sv->ts,
540+
(unsigned long)sticky->sess_lifetime * HZ, sticky->sess_lifetime);
541+
533542
if (jiffies > sv->ts + (unsigned long)sticky->sess_lifetime * HZ) {
534543
sess_warn("sticky cookie value expired", addr,
535544
" (issued=%lu lifetime=%lu now=%lu)\n", sv->ts,
@@ -539,6 +548,7 @@ tfw_http_sticky_verify(TfwHttpReq *req, TfwStr *value, StickyVal *sv)
539548

540549
/* Sticky cookie is found and verified, now we can set the flag. */
541550
__set_bit(TFW_HTTP_B_HAS_STICKY, req->flags);
551+
pr_notice("TFW_HTTP_B_HAS_STICKY\n");
542552

543553
return r;
544554
}
@@ -551,20 +561,25 @@ tfw_http_sticky_req_process(TfwHttpReq *req, StickyVal *sv, TfwStr *cookie_val)
551561
{
552562
int r;
553563

564+
pr_notice("tfw_http_sticky_req_process\n");
554565
/*
555566
* See if the Tempesta sticky cookie is present in the request,
556567
* and act depending on the result.
557568
*/
558569
r = tfw_http_sticky_get_req(req, cookie_val);
570+
571+
pr_notice("tfw_http_sticky_get_req result =%i\n", r);
559572
if (r < 0)
560573
return r;
561574
if (r == 0) {
562575
return !req->vhost->cookie->enforce ?
563576
TFW_HTTP_SESS_SUCCESS : TFW_HTTP_SESS_COOKIE_NOT_FOUND;
564577
}
565578
if (r == 1) {
566-
if ((r = tfw_http_sticky_verify(req, cookie_val, sv)))
579+
if ((r = tfw_http_sticky_verify(req, cookie_val, sv))) {
580+
pr_notice("tfw_http_sticky_verify result =%i\n", r);
567581
return r;
582+
}
568583

569584
return TFW_HTTP_SESS_SUCCESS;
570585
}
@@ -590,17 +605,20 @@ tfw_http_sess_resp_process(TfwHttpResp *resp, bool cache,
590605
{
591606
return 0;
592607
}
593-
BUG_ON(!req->sess);
608+
if (req->need_jsch) {
609+
BUG_ON(!req->sess);
594610

595-
/*
596-
* RFC 6265 4.1.1 and 4.1.2 says that we should not set session cookie
597-
* if it's not necessary. Since client didn't send up the cookie and
598-
* it seems that we don't enforce them, we can just set the cookie in
599-
* each response forwarded to the client.
600-
*/
601-
if (test_bit(TFW_HTTP_B_HAS_STICKY, req->flags))
602-
return 0;
603-
return tfw_http_sticky_add(resp, cache, stream_id);
611+
/*
612+
* RFC 6265 4.1.1 and 4.1.2 says that we should not set session cookie
613+
* if it's not necessary. Since client didn't send up the cookie and
614+
* it seems that we don't enforce them, we can just set the cookie in
615+
* each response forwarded to the client.
616+
*/
617+
if (test_bit(TFW_HTTP_B_HAS_STICKY, req->flags))
618+
return 0;
619+
return tfw_http_sticky_add(resp, cache, stream_id);
620+
}
621+
return 0;
604622
}
605623

606624
/**
@@ -623,6 +641,7 @@ tfw_http_sess_unpin_srv(TfwHttpSess *sess)
623641
static inline void
624642
tfw_http_sess_set_expired(TfwHttpSess *sess)
625643
{
644+
pr_notice("tfw_http_sess_set_expired\n");
626645
atomic64_set(&sess->expires, 0);
627646
}
628647

@@ -631,6 +650,7 @@ tfw_http_sess_prolong(TfwHttpSess *sess, TfwStickyCookie *sticky)
631650
{
632651
if (!sticky->learn)
633652
return;
653+
pr_notice("tfw_http_sess_prolong\n");
634654
atomic64_set(&sess->expires,
635655
jiffies + (unsigned long)sticky->sess_lifetime * HZ);
636656
}
@@ -668,6 +688,8 @@ tfw_http_sess_check_jsch(StickyVal *sv, TfwHttpReq* req)
668688
{
669689
unsigned long min_time;
670690
TfwCfgJsCh *js_ch = req->vhost->cookie->js_challenge;
691+
if (!req->need_jsch)
692+
return 0;
671693

672694
if (!js_ch)
673695
return 0;
@@ -701,6 +723,7 @@ tfw_http_sess_eq(TdbRec *rec, void *data)
701723
* Expired or invalid session is not usable, leave it for garbage
702724
* collector.
703725
*/
726+
pr_notice("tfw_http_sess_eq\n");
704727
if (((unsigned long)atomic64_read(&sess->expires) < jiffies)
705728
|| !sess->vhost)
706729
{
@@ -793,6 +816,7 @@ tfw_sess_ent_init(TdbRec *rec, void *data)
793816
sess->ts = ctx->sv.ts;
794817
}
795818

819+
pr_notice("tfw_sess_ent_init\n");
796820
atomic_set(&sess->users, 1);
797821
atomic64_set(&sess->expires,
798822
sess->ts + (unsigned long)sticky->sess_lifetime * HZ);
@@ -825,6 +849,7 @@ tfw_http_sess_obtain(TfwHttpReq *req)
825849
TdbRec *rec;
826850
TdbGetAllocCtx tdb_ctx = { 0 };
827851

852+
pr_notice("tfw_http_sess_obtain\n");
828853
/*
829854
* If vhost is not known, then request is to be dropped. Don't save the
830855
* session even if the client has passed a cookie challenge.
@@ -845,20 +870,22 @@ tfw_http_sess_obtain(TfwHttpReq *req)
845870
* We leave this for administrator decision or more progressive DDoS
846871
* mitigation techniques.
847872
*/
848-
r = tfw_http_sticky_req_process(req, sv, c_val);
849-
switch (r) {
850-
case TFW_HTTP_SESS_SUCCESS:
851-
break;
852-
case TFW_HTTP_SESS_FAILURE:
853-
return r;
854-
default:
855-
/*
856-
* Any js challenge processing error: cookie not found
857-
* or invalid or request comes not in time. We increment
858-
* max_misses and restart js challenge.
859-
*/
860-
BUG_ON(r < __TFW_HTTP_SESS_PUB_CODE_MAX);
861-
return tfw_http_sticky_challenge_start(req);
873+
if (req->need_jsch) {
874+
r = tfw_http_sticky_req_process(req, sv, c_val);
875+
switch (r) {
876+
case TFW_HTTP_SESS_SUCCESS:
877+
break;
878+
case TFW_HTTP_SESS_FAILURE:
879+
return r;
880+
default:
881+
/*
882+
* Any js challenge processing error: cookie not found
883+
* or invalid or request comes not in time. We increment
884+
* max_misses and restart js challenge.
885+
*/
886+
BUG_ON(r < __TFW_HTTP_SESS_PUB_CODE_MAX);
887+
return tfw_http_sticky_challenge_start(req);
888+
}
862889
}
863890

864891
if (req->vhost->cookie->learn) {

0 commit comments

Comments
 (0)