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 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 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 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 LuaGetFlowvar(lua_State *luastate) { uint16_t idx; int id; Flow *f; FlowVar *fv; DetectLuaData *ld; /* need lua data for id -> idx conversion */ lua_pushlightuserdata(luastate, (void *)&luaext_key_ld); lua_gettable(luastate, LUA_REGISTRYINDEX); ld = lua_touserdata(luastate, -1); SCLogDebug("ld %p", ld); if (ld == NULL) { lua_pushnil(luastate); lua_pushstring(luastate, "internal error: no ld"); return 2; } /* need flow and lock hint */ f = LuaStateGetFlow(luastate); if (f == NULL) { lua_pushnil(luastate); lua_pushstring(luastate, "no flow"); return 2; } /* need flowvar idx */ if (!lua_isnumber(luastate, 1)) { lua_pushnil(luastate); lua_pushstring(luastate, "1st arg not a number"); return 2; } id = lua_tonumber(luastate, 1); if (id < 0 || id >= DETECT_LUAJIT_MAX_FLOWVARS) { lua_pushnil(luastate); lua_pushstring(luastate, "flowvar id out of range"); return 2; } idx = ld->flowvar[id]; if (idx == 0) { lua_pushnil(luastate); lua_pushstring(luastate, "flowvar id uninitialized"); return 2; } fv = FlowVarGet(f, idx); if (fv == NULL) { lua_pushnil(luastate); lua_pushstring(luastate, "no flow var"); return 2; } LuaPushStringBuffer(luastate, (const uint8_t *)fv->data.fv_str.value, (size_t)fv->data.fv_str.value_len); return 1; }
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)); }
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; } }
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)); }
void LuaPushTableKeyValueArray(lua_State *luastate, const char *key, const uint8_t *value, size_t len) { lua_pushstring(luastate, key); LuaPushStringBuffer(luastate, value, len); lua_settable(luastate, -3); }