static int HttpGetRawHeaders(lua_State *luastate, int dir) { if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); if (htud == NULL) return LuaCallbackError(luastate, "no htud in tx"); uint8_t *raw = htud->request_headers_raw; uint32_t raw_len = htud->request_headers_raw_len; if (dir == 1) { raw = htud->response_headers_raw; raw_len = htud->response_headers_raw_len; } if (raw == NULL || raw_len == 0) return LuaCallbackError(luastate, "no raw headers"); return LuaPushStringBuffer(luastate, raw, raw_len); }
static int HttpGetHeaders(lua_State *luastate, int dir) { if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); htp_table_t *table = tx->request_headers; if (dir == 1) table = tx->response_headers; if (tx->request_headers == NULL) return LuaCallbackError(luastate, "no headers"); lua_newtable(luastate); htp_header_t *h = NULL; size_t i = 0; size_t no_of_headers = htp_table_size(table); for (; i < no_of_headers; i++) { h = htp_table_get_index(table, i, NULL); LuaPushStringBuffer(luastate, bstr_ptr(h->name), bstr_len(h->name)); LuaPushStringBuffer(luastate, bstr_ptr(h->value), bstr_len(h->value)); lua_settable(luastate, -3); } return 1; }
static int HttpGetHeader(lua_State *luastate, int dir) { if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); const char *name = LuaGetStringArgument(luastate, 1); if (name == NULL) return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); htp_table_t *headers = tx->request_headers; if (dir == 1) headers = tx->response_headers; if (headers == NULL) return LuaCallbackError(luastate, "tx has no headers"); htp_header_t *h = (htp_header_t *)htp_table_get_c(headers, name); if (h == NULL || bstr_len(h->value) == 0) return LuaCallbackError(luastate, "header not found"); return LuaPushStringBuffer(luastate, bstr_ptr(h->value), bstr_len(h->value)); }
static int GetCertInfo(lua_State *luastate, const Flow *f, int direction) { void *state = FlowGetAppState(f); if (state == NULL) return LuaCallbackError(luastate, "error: no app layer state"); SSLState *ssl_state = (SSLState *)state; SSLStateConnp *connp = NULL; if (direction) { connp = &ssl_state->client_connp; } else { connp = &ssl_state->server_connp; } if (connp->cert0_subject == NULL) return LuaCallbackError(luastate, "error: no cert"); /* tls.version */ char ssl_version[32] = ""; switch (ssl_state->server_connp.version) { case TLS_VERSION_UNKNOWN: snprintf(ssl_version, sizeof(ssl_version), "UNDETERMINED"); break; case SSL_VERSION_2: snprintf(ssl_version, sizeof(ssl_version), "SSLv2"); break; case SSL_VERSION_3: snprintf(ssl_version, sizeof(ssl_version), "SSLv3"); break; case TLS_VERSION_10: snprintf(ssl_version, sizeof(ssl_version), "TLSv1"); break; case TLS_VERSION_11: snprintf(ssl_version, sizeof(ssl_version), "TLS 1.1"); break; case TLS_VERSION_12: snprintf(ssl_version, sizeof(ssl_version), "TLS 1.2"); break; default: snprintf(ssl_version, sizeof(ssl_version), "0x%04x", ssl_state->server_connp.version); break; } int r = LuaPushStringBuffer(luastate, (uint8_t *)ssl_version, strlen(ssl_version)); r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_subject, strlen(connp->cert0_subject)); r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_issuerdn, strlen(connp->cert0_issuerdn)); r += LuaPushStringBuffer(luastate, (uint8_t *)connp->cert0_fingerprint, strlen(connp->cert0_fingerprint)); return r; }
static int GetSNI(lua_State *luastate, const Flow *f) { void *state = FlowGetAppState(f); if (state == NULL) return LuaCallbackError(luastate, "error: no app layer state"); SSLState *ssl_state = (SSLState *)state; if (ssl_state->client_connp.sni == NULL) return LuaCallbackError(luastate, "error: no server name indication"); return LuaPushStringBuffer(luastate, (uint8_t *)ssl_state->client_connp.sni, strlen(ssl_state->client_connp.sni)); }
static int HttpGetRequestUriRaw(lua_State *luastate) { if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); if (tx->request_uri == NULL) return LuaCallbackError(luastate, "no request uri"); return LuaPushStringBuffer(luastate, bstr_ptr(tx->request_uri), bstr_len(tx->request_uri)); }
static int HttpGetBody(lua_State *luastate, int dir) { HtpBody *body = NULL; if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); if (htud == NULL) return LuaCallbackError(luastate, "no htud in tx"); if (dir == 0) body = &htud->request_body; else body = &htud->response_body; if (body->first == NULL) return LuaCallbackError(luastate, "no body"); int index = 1; HtpBodyChunk *chunk = body->first; lua_newtable(luastate); while (chunk != NULL) { lua_pushinteger(luastate, index); const uint8_t *data = NULL; uint32_t data_len = 0; StreamingBufferSegmentGetData(body->sb, &chunk->sbseg, &data, &data_len); LuaPushStringBuffer(luastate, data, data_len); lua_settable(luastate, -3); chunk = chunk->next; index++; } if (body->first && body->last) { lua_pushinteger(luastate, body->first->sbseg.stream_offset); lua_pushinteger(luastate, body->last->sbseg.stream_offset + body->last->sbseg.segment_len); return 3; } else { return 1; } }
/** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackTuple(lua_State *luastate) { const Packet *p = LuaStateGetPacket(luastate); if (p == NULL) return LuaCallbackError(luastate, "internal error: no packet"); return LuaCallbackTuplePushToStackFromPacket(luastate, p); }
/** \internal * \brief Wrapper for getting payload into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackStreamingBuffer(lua_State *luastate) { const LuaStreamingBuffer *b = LuaStateGetStreamingBuffer(luastate); if (b == NULL) return LuaCallbackError(luastate, "internal error: no buffer"); return LuaCallbackStreamingBufferPushToStack(luastate, b); }
/** \internal * \brief Wrapper for getting packet timestamp (as numbers) into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackPacketTimestamp(lua_State *luastate) { const Packet *p = LuaStateGetPacket(luastate); if (p == NULL) return LuaCallbackError(luastate, "internal error: no packet"); return LuaCallbackTimestampPushToStack(luastate, &p->ts); }
/** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackRuleClass(lua_State *luastate) { const PacketAlert *pa = LuaStateGetPacketAlert(luastate); if (pa == NULL) return LuaCallbackError(luastate, "internal error: no packet"); return LuaCallbackRuleClassPushToStackFromPacketAlert(luastate, pa); }
static int LuaCallbackLogPath(lua_State *luastate) { const char *ld = ConfigGetLogDirectory(); if (ld == NULL) return LuaCallbackError(luastate, "internal error: no log dir"); return LuaPushStringBuffer(luastate, (const uint8_t *)ld, strlen(ld)); }
/** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackThreadInfo(lua_State *luastate) { const ThreadVars *tv = LuaStateGetThreadVars(luastate); if (tv == NULL) return LuaCallbackError(luastate, "internal error: no tv"); return LuaCallbackThreadInfoPushToStackFromThreadVars(luastate, tv); }
/** \internal * \brief Wrapper for getting tuple info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackFileState(lua_State *luastate) { const File *file = LuaStateGetFile(luastate); if (file == NULL) return LuaCallbackError(luastate, "internal error: no file"); return LuaCallbackFileStatePushToStackFromFile(luastate, file); }
static int LuaCallbackLogDebug(lua_State *luastate) { const char *msg = LuaGetStringArgument(luastate, 1); if (msg == NULL) return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); SCLogDebug("%s", msg); return 0; }
/** \internal * \brief Wrapper for getting AppLayerProto info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackStatsFlow(lua_State *luastate) { int r = 0; Flow *f = LuaStateGetFlow(luastate); if (f == NULL) return LuaCallbackError(luastate, "internal error: no flow"); r = LuaCallbackStatsPushToStackFromFlow(luastate, f); return r; }
/** \internal * \brief Wrapper for getting ts info into a lua script * \retval cnt number of items placed on the stack */ static int LuaCallbackFlowTimeString(lua_State *luastate) { int r = 0; Flow *flow = LuaStateGetFlow(luastate); if (flow == NULL) return LuaCallbackError(luastate, "internal error: no flow"); r = LuaCallbackTimeStringPushToStackFromFlow(luastate, flow); return r; }
static int TlsGetSNI(lua_State *luastate) { int r; if (!(LuaStateNeedProto(luastate, ALPROTO_TLS))) return LuaCallbackError(luastate, "error: protocol not tls"); int lock_hint = 0; Flow *f = LuaStateGetFlow(luastate, &lock_hint); if (f == NULL) return LuaCallbackError(luastate, "internal error: no flow"); if (lock_hint == LUA_FLOW_NOT_LOCKED_BY_PARENT) { FLOWLOCK_RDLOCK(f); r = GetSNI(luastate, f); FLOWLOCK_UNLOCK(f); } else { r = GetSNI(luastate, f); } return r; }
int LuaStateNeedProto(lua_State *luastate, AppProto alproto) { AppProto flow_alproto = 0; Flow *flow = LuaStateGetFlow(luastate); if (flow == NULL) return LuaCallbackError(luastate, "internal error: no flow"); flow_alproto = flow->alproto; return (alproto == flow_alproto); }
static int LuaCallbackLogError(lua_State *luastate) { const char *msg = LuaGetStringArgument(luastate, 1); if (msg == NULL) return LuaCallbackError(luastate, "1st argument missing, empty or wrong type"); lua_Debug ar; lua_getstack(luastate, 1, &ar); lua_getinfo(luastate, "nSl", &ar); const char *funcname = ar.name ? ar.name : ar.what; SCLogErrorRaw(SC_ERR_LUA_SCRIPT, ar.short_src, funcname, ar.currentline, "%s", msg); return 0; }
static int HttpGetRequestUriNormalized(lua_State *luastate) { if (!(LuaStateNeedProto(luastate, ALPROTO_HTTP))) return LuaCallbackError(luastate, "error: protocol not http"); htp_tx_t *tx = LuaStateGetTX(luastate); if (tx == NULL) return LuaCallbackError(luastate, "internal error: no tx"); HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); if (htud == NULL) return LuaCallbackError(luastate, "no htud in tx"); if (htud->request_uri_normalized == NULL || bstr_ptr(htud->request_uri_normalized) == NULL || bstr_len(htud->request_uri_normalized) == 0) return LuaCallbackError(luastate, "no normalized uri"); return LuaPushStringBuffer(luastate, bstr_ptr(htud->request_uri_normalized), bstr_len(htud->request_uri_normalized)); }