bool MsdpNetwork::run_plugins_msdp(const tbyte* data, int len) { //OUTPUT_BYTES(data, len, len, "PLUGINS MSDP"); // translate msdp data into lua table lua_newtable(L); cursor c; c.p = data; c.e = data + len; while (c.p != c.e) { if (!process_var(c)) { lua_pop(L, 1); return false; } if (!process_val(c)) { lua_pop(L, 1); return false; } } // run plugins tortilla::getPluginsManager()->processPluginsMethod("msdp", 1); return true; }
bool MsdpNetwork::process_val(cursor& c) { const tbyte* p = c.p; if (p == c.e || *p != MSDP_VAL) return false; const tbyte* b = p+1; if (b == c.e) { lua_pushstring(L, ""); lua_settable(L, -3); c.p = b; return true; } if (*b >= ' ') { while (b != c.e && *b >= ' ') b++; if (b != c.e && *b != MSDP_VAR && *b != MSDP_VAL && *b != MSDP_ARRAY_CLOSE && *b != MSDP_TABLE_CLOSE) return false; std::string value((const char*)(p+1), b-p-1); if (m_utf8_encoding) { lua_pushstring(L, value.c_str()); } else { std::string newval; const char* b0 = value.c_str(); const tbyte* b = (const tbyte*)b0; const tbyte* e = b + value.length(); while (b != e) { const tbyte *p = b; while (p!=e && *p!=0xff) p++; if (p==e) break; p++; if (p==e) break; newval.append((const char*)b, p-b); if (*p == 0xff) { p++; } b = p; } newval.append((const char*)b); TA2W ws(newval.c_str()); luaT_pushwstring(L, ws); } lua_settable(L, -3); c.p = b; return true; } else if (*b == MSDP_ARRAY_OPEN) { c.p = b+1; if (c.p == c.e) return false; int index = 1; // index for array's vars lua_newtable(L); // table for array while(true) { lua_pushinteger(L, index++); if (!process_val(c)) { lua_pop(L, 2); return false; } if (*c.p != MSDP_VAL && *c.p != MSDP_ARRAY_CLOSE) { lua_pop(L, 2); return false; } if (*c.p == MSDP_ARRAY_CLOSE) { lua_settable(L, -3); c.p++; return true; } } } else if (*b == MSDP_TABLE_OPEN) { c.p = b+1; if (c.p == c.e) return false; lua_newtable(L); // table for table while (true) { if (!process_var(c)) { lua_pop(L, 1); return false; } if (!process_val(c)) { lua_pop(L, 2); return false; } if (*c.p != MSDP_VAR && *c.p != MSDP_TABLE_CLOSE) { lua_pop(L, 2); return false; } if (*c.p == MSDP_TABLE_CLOSE) { lua_settable(L, -3); c.p++; return true; } } } else if (*b == MSDP_VAL || *b == MSDP_VAR) { lua_pushstring(L, ""); lua_settable(L, -3); c.p = b; return true; } return false; }
int ruleIMAIL_LDAPeval(void *p) { u_int32_t current_byte = 0; u_int32_t width, value, lengthwidth; int retval; u_int32_t payload_len; const u_int8_t *cursor_normal, *beg_of_payload, *end_of_payload; SFSnortPacket *sp = (SFSnortPacket *) p; if(sp == NULL) return RULE_NOMATCH; if(sp->payload == NULL) return RULE_NOMATCH; /* call flow match */ if (checkFlow(sp, ruleIMAIL_LDAPoptions[0]->option_u.flowFlags) <= 0 ) return RULE_NOMATCH; /* call content match */ if (contentMatch(sp, ruleIMAIL_LDAPoptions[1]->option_u.content, &cursor_normal) <= 0) { return RULE_NOMATCH; } if(getBuffer(sp, CONTENT_BUF_NORMALIZED, &beg_of_payload, &end_of_payload) <= 0) return RULE_NOMATCH; payload_len = end_of_payload - beg_of_payload; if(payload_len < 10) /* Minimum bind request length */ return RULE_NOMATCH; /* our contentMatch already assures us the first byte is \x30, so just jump over it */ current_byte++; /* Begin packet structure processing */ /* Packet length (only care about width of the specifier) */ if(beg_of_payload[current_byte] & 0x80) { current_byte += beg_of_payload[current_byte] & 0x0F; /* Does imail do this properly? */ } current_byte++; /* Message number (only care about width of the specifier) */ if(payload_len < current_byte + 8) return RULE_NOMATCH; if(beg_of_payload[current_byte] != 0x02) /* Int data type */ return RULE_NOMATCH; current_byte++; /* int width specifier */ if(beg_of_payload[current_byte] & 0x80) { width = beg_of_payload[current_byte] & 0x0F; current_byte++; if(payload_len < current_byte + width) return RULE_NOMATCH; retval = process_val(&(beg_of_payload[current_byte]), width, &value); if(retval < 0) return RULE_NOMATCH; /* width is either 0 or > 4 */ current_byte += width; /* width of data width specifier */ current_byte += value; /* width of data itself */ } else { current_byte += beg_of_payload[current_byte] + 1; } /* Bind request */ if(payload_len < current_byte + 5) return RULE_NOMATCH; if(beg_of_payload[current_byte] != 0x60) return RULE_NOMATCH; current_byte++; /* Message length (only care about width of the specifier) */ if(beg_of_payload[current_byte] & 0x80) { current_byte += beg_of_payload[current_byte] & 0x0F; } current_byte++; /* ldap version */ if(payload_len < current_byte + 3) return RULE_NOMATCH; /* ldap version */ if(beg_of_payload[current_byte] != 0x02) /* Int data type */ return RULE_NOMATCH; current_byte++; /* Now check for funkiness with the version field */ /* Get width of version number */ if(beg_of_payload[current_byte] & 0x80) { /* Excess bits in the high nibble */ if(beg_of_payload[current_byte] & 0x70) return RULE_MATCH; lengthwidth = beg_of_payload[current_byte] & 0x0F; current_byte++; if(payload_len < current_byte + lengthwidth) return RULE_NOMATCH; retval = process_val(&(beg_of_payload[current_byte]), lengthwidth, &value); if(retval < 0) return RULE_MATCH; /* Something screwy's going on around here */ width = value; current_byte += lengthwidth; } else { width = beg_of_payload[current_byte]; current_byte++; } if(payload_len < current_byte + width) return RULE_NOMATCH; /* In this case, if the version value is this fubar, trigger */ retval = process_val(&(beg_of_payload[current_byte]), width, &value); if(retval < 0) return RULE_MATCH; /* LDAP version > 9 (currently, should be 1-3) */ if(value > 9) return RULE_MATCH; return RULE_NOMATCH; }