Skip to content

Commit

Permalink
detect/lua: use rule hook instead of init() 'needs' table
Browse files Browse the repository at this point in the history
For registration of app-layer inspection, no longer use the 'needs'
table from the script, but instead use the rule hook setting.

Ticket: OISF#4783.
  • Loading branch information
victorjulien committed Jan 20, 2025
1 parent 4998b97 commit f06cdb3
Showing 1 changed file with 17 additions and 229 deletions.
246 changes: 17 additions & 229 deletions src/detect-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,6 @@ void DetectLuaRegister(void)
#define FLAG_DATATYPE_PACKET BIT_U32(0)
#define FLAG_DATATYPE_PAYLOAD BIT_U32(1)
#define FLAG_DATATYPE_STREAM BIT_U32(2)
#define FLAG_DATATYPE_HTTP_URI BIT_U32(3)
#define FLAG_DATATYPE_HTTP_URI_RAW BIT_U32(4)
#define FLAG_DATATYPE_HTTP_REQUEST_HEADERS BIT_U32(5)
#define FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW BIT_U32(6)
#define FLAG_DATATYPE_HTTP_REQUEST_COOKIE BIT_U32(7)
#define FLAG_DATATYPE_HTTP_REQUEST_UA BIT_U32(8)
#define FLAG_DATATYPE_HTTP_REQUEST_LINE BIT_U32(9)
#define FLAG_DATATYPE_HTTP_REQUEST_BODY BIT_U32(10)
#define FLAG_DATATYPE_HTTP_RESPONSE_COOKIE BIT_U32(11)
#define FLAG_DATATYPE_HTTP_RESPONSE_BODY BIT_U32(12)
#define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS BIT_U32(13)
#define FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW BIT_U32(14)
#define FLAG_DATATYPE_DNS_RRNAME BIT_U32(15)
#define FLAG_DATATYPE_DNS_REQUEST BIT_U32(16)
#define FLAG_DATATYPE_DNS_RESPONSE BIT_U32(17)
#define FLAG_DATATYPE_SSH BIT_U32(19)
#define FLAG_DATATYPE_SMTP BIT_U32(20)
#define FLAG_DATATYPE_DNP3 BIT_U32(21)
#define FLAG_DATATYPE_BUFFER BIT_U32(22)
#define FLAG_ERROR_LOGGED BIT_U32(23)
#define FLAG_BLOCKED_FUNCTION_LOGGED BIT_U32(24)
Expand Down Expand Up @@ -363,30 +345,6 @@ static int DetectLuaMatch (DetectEngineThreadCtx *det_ctx,
LuaPushStringBuffer (tlua->luastate, (const uint8_t *)GET_PKT_DATA(p), (size_t)GET_PKT_LEN(p)); /* stack at -3 */
lua_settable(tlua->luastate, -3);
}
if (tlua->alproto == ALPROTO_HTTP1) {
HtpState *htp_state = p->flow->alstate;
if (htp_state != NULL && htp_state->connp != NULL) {
htp_tx_t *tx = NULL;
uint64_t idx = AppLayerParserGetTransactionInspectId(p->flow->alparser,
STREAM_TOSERVER);
uint64_t total_txs= AppLayerParserGetTxCnt(p->flow, htp_state);
for ( ; idx < total_txs; idx++) {
tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, idx);
if (tx == NULL)
continue;

if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL &&
bstr_len(tx->request_line) > 0) {
lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
LuaPushStringBuffer(tlua->luastate,
(const uint8_t *)bstr_ptr(tx->request_line),
bstr_len(tx->request_line));
lua_settable(tlua->luastate, -3);
}
}
}
}

SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
}

Expand Down Expand Up @@ -415,24 +373,6 @@ static int DetectLuaAppMatchCommon (DetectEngineThreadCtx *det_ctx,
lua_getglobal(tlua->luastate, "match");
lua_newtable(tlua->luastate); /* stack at -1 */

if (tlua->alproto == ALPROTO_HTTP1) {
HtpState *htp_state = state;
if (htp_state != NULL && htp_state->connp != NULL) {
htp_tx_t *tx = NULL;
tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, det_ctx->tx_id);
if (tx != NULL) {
if ((tlua->flags & FLAG_DATATYPE_HTTP_REQUEST_LINE) && tx->request_line != NULL &&
bstr_len(tx->request_line) > 0) {
lua_pushliteral(tlua->luastate, "http.request_line"); /* stack at -2 */
LuaPushStringBuffer(tlua->luastate,
(const uint8_t *)bstr_ptr(tx->request_line),
bstr_len(tx->request_line));
lua_settable(tlua->luastate, -3);
}
}
}
}

SCReturnInt(DetectLuaRunMatch(det_ctx, lua, tlua));
}

Expand Down Expand Up @@ -767,108 +707,12 @@ static int DetectLuaSetupPrime(DetectEngineCtx *de_ctx, DetectLuaData *ld, const
SCLogError("alloc error");
goto error;
}

} else if (strncmp(k, "http", 4) == 0 && strcmp(v, "true") == 0) {
if (ld->alproto != ALPROTO_UNKNOWN && ld->alproto != ALPROTO_HTTP1) {
SCLogError(
"can just inspect script against one app layer proto like HTTP at a time");
goto error;
}
if (ld->flags != 0) {
SCLogError("when inspecting HTTP buffers only a single buffer can be inspected");
goto error;
}

/* http types */
ld->alproto = ALPROTO_HTTP1;

if (strcmp(k, "http.uri") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_URI;

else if (strcmp(k, "http.uri.raw") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_URI_RAW;

else if (strcmp(k, "http.request_line") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_LINE;

else if (strcmp(k, "http.request_headers") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_HEADERS;

else if (strcmp(k, "http.request_headers.raw") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW;

else if (strcmp(k, "http.request_cookie") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_COOKIE;

else if (strcmp(k, "http.request_user_agent") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_UA;

else if (strcmp(k, "http.request_body") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_REQUEST_BODY;

else if (strcmp(k, "http.response_body") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_RESPONSE_BODY;

else if (strcmp(k, "http.response_cookie") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_RESPONSE_COOKIE;

else if (strcmp(k, "http.response_headers") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_RESPONSE_HEADERS;

else if (strcmp(k, "http.response_headers.raw") == 0)
ld->flags |= FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW;

else {
SCLogError("unsupported http data type %s", k);
goto error;
}

ld->buffername = SCStrdup(k);
if (ld->buffername == NULL) {
SCLogError("alloc error");
goto error;
}
} else if (strncmp(k, "dns", 3) == 0 && strcmp(v, "true") == 0) {

ld->alproto = ALPROTO_DNS;

if (strcmp(k, "dns.rrname") == 0)
ld->flags |= FLAG_DATATYPE_DNS_RRNAME;
else if (strcmp(k, "dns.request") == 0)
ld->flags |= FLAG_DATATYPE_DNS_REQUEST;
else if (strcmp(k, "dns.response") == 0)
ld->flags |= FLAG_DATATYPE_DNS_RESPONSE;

else {
SCLogError("unsupported dns data type %s", k);
goto error;
}
ld->buffername = SCStrdup(k);
if (ld->buffername == NULL) {
SCLogError("alloc error");
goto error;
}
} else if (strncmp(k, "tls", 3) == 0 && strcmp(v, "true") == 0) {

ld->alproto = ALPROTO_TLS;

} else if (strncmp(k, "ssh", 3) == 0 && strcmp(v, "true") == 0) {

ld->alproto = ALPROTO_SSH;

ld->flags |= FLAG_DATATYPE_SSH;

} else if (strncmp(k, "smtp", 4) == 0 && strcmp(v, "true") == 0) {

ld->alproto = ALPROTO_SMTP;

ld->flags |= FLAG_DATATYPE_SMTP;

} else if (strncmp(k, "dnp3", 4) == 0 && strcmp(v, "true") == 0) {

ld->alproto = ALPROTO_DNP3;

ld->flags |= FLAG_DATATYPE_DNP3;
/* old options no longer supported */
} else if (strncmp(k, "http", 4) == 0 || strncmp(k, "dns", 3) == 0 ||
strncmp(k, "tls", 3) == 0 || strncmp(k, "ssh", 3) == 0 ||
strncmp(k, "smtp", 4) == 0 || strncmp(k, "dnp3", 4) == 0) {
SCLogError("data type %s no longer supported, use rule hooks", k);
goto error;

} else {
SCLogError("unsupported data type %s", k);
Expand Down Expand Up @@ -933,74 +777,18 @@ static int DetectLuaSetup (DetectEngineCtx *de_ctx, Signature *s, const char *st
if (lua->thread_ctx_id == -1)
goto error;

if (lua->alproto != ALPROTO_UNKNOWN) {
if (s->alproto != ALPROTO_UNKNOWN && !AppProtoEquals(s->alproto, lua->alproto)) {
goto error;
int list = DetectBufferGetActiveList(de_ctx, s);
SCLogNotice("buffer list %d -> %d", list, s->init_data->list);
if (list == -1 || (list == 0 && s->init_data->list == INT_MAX)) {
/* what needs to happen here is: we register to the rule hook, so e.g.
* http1.request_complete. This means we need a list.
*
* This includes each pkt, payload, stream, etc. */

if (s->init_data->hook.type != SIGNATURE_HOOK_TYPE_NOT_SET) {
list = s->init_data->hook.sm_list;
SCLogNotice("setting list %d", list);
}
s->alproto = lua->alproto;
}

/* Okay so far so good, lets get this into a SigMatch
* and put it in the Signature. */

int list = -1;
if (lua->alproto == ALPROTO_UNKNOWN) {
if (lua->flags & FLAG_DATATYPE_STREAM)
list = DETECT_SM_LIST_PMATCH;
else {
if (lua->flags & FLAG_DATATYPE_BUFFER) {
if (DetectBufferGetActiveList(de_ctx, s) != -1) {
list = s->init_data->list;
} else {
SCLogError("Lua and sticky buffer failure");
goto error;
}
} else
list = DETECT_SM_LIST_MATCH;
}

} else if (lua->alproto == ALPROTO_HTTP1) {
if (lua->flags & FLAG_DATATYPE_HTTP_RESPONSE_BODY) {
list = DetectBufferTypeGetByName("file_data");
} else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_BODY) {
list = DetectBufferTypeGetByName("http_client_body");
} else if (lua->flags & FLAG_DATATYPE_HTTP_URI) {
list = DetectBufferTypeGetByName("http_uri");
} else if (lua->flags & FLAG_DATATYPE_HTTP_URI_RAW) {
list = DetectBufferTypeGetByName("http_raw_uri");
} else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_COOKIE ||
lua->flags & FLAG_DATATYPE_HTTP_RESPONSE_COOKIE) {
list = DetectBufferTypeGetByName("http_cookie");
} else if (lua->flags & FLAG_DATATYPE_HTTP_REQUEST_UA) {
list = DetectBufferTypeGetByName("http_user_agent");
} else if (lua->flags &
(FLAG_DATATYPE_HTTP_REQUEST_HEADERS | FLAG_DATATYPE_HTTP_RESPONSE_HEADERS)) {
list = DetectBufferTypeGetByName("http_header");
} else if (lua->flags & (FLAG_DATATYPE_HTTP_REQUEST_HEADERS_RAW |
FLAG_DATATYPE_HTTP_RESPONSE_HEADERS_RAW)) {
list = DetectBufferTypeGetByName("http_raw_header");
} else {
list = DetectBufferTypeGetByName("http_request_line");
}
} else if (lua->alproto == ALPROTO_DNS) {
if (lua->flags & FLAG_DATATYPE_DNS_RRNAME) {
list = DetectBufferTypeGetByName("dns_query");
} else if (lua->flags & FLAG_DATATYPE_DNS_REQUEST) {
list = DetectBufferTypeGetByName("dns_request");
} else if (lua->flags & FLAG_DATATYPE_DNS_RESPONSE) {
list = DetectBufferTypeGetByName("dns_response");
}
} else if (lua->alproto == ALPROTO_TLS) {
list = DetectBufferTypeGetByName("tls_generic");
} else if (lua->alproto == ALPROTO_SSH) {
list = DetectBufferTypeGetByName("ssh_banner");
} else if (lua->alproto == ALPROTO_SMTP) {
list = g_smtp_generic_list_id;
} else if (lua->alproto == ALPROTO_DNP3) {
list = DetectBufferTypeGetByName("dnp3");
} else {
SCLogError("lua can't be used with protocol %s", AppLayerGetProtoName(lua->alproto));
goto error;
}

if (list == -1) {
Expand Down

0 comments on commit f06cdb3

Please sign in to comment.