pgsql: add events

Events for:
- parsing error when parsing pgsql packet length
- parsing error for pgsql requests (post length parsing)
- parsing error for pgsql responses (post length parsing)
- too many transactions

Include `pgsql-events.rules` file, and PGSQL events SID range definition

Task #5566
pull/12625/head
Juliana Fajardini 2 weeks ago committed by Victor Julien
parent 6eadb752ec
commit 1b6f4da23b

@ -29,6 +29,7 @@ signature IDs.
| QUIC | 2231000 | 2231999 |
| FTP | 2232000 | 2232999 |
| DNS | 2240000 | 2240999 |
| PGSQL | 2241000 | 2241999 |
| MODBUS | 2250000 | 2250999 |
| DNP3 | 2270000 | 2270999 |
| HTTP2 | 2290000 | 2290999 |

@ -0,0 +1,8 @@
# PGSQL app-layer event rules
#
# SID range start: 2241000
# SID range end: 2241999
alert pgsql any any -> any any (msg:"SURICATA PGSQL Too many transactions"; app-layer-event:pgsql.too_many_transactions; sid:2241000; rev:1;)
alert pgsql any any -> any any (msg:"SURICATA PGSQL Malformed request"; app-layer-event:pgsql.malformed_request; flow:to_server; sid:2241001; rev:1;)
alert pgsql any any -> any any (msg:"SURICATA PGSQL Malformed response"; app-layer-event:pgsql.malformed_response; flow:to_client; sid:2241002; rev:1;)
alert pgsql any any -> any any (msg:"SURICATA PGSQL Invalid length"; app-layer-event:pgsql.invalid_length; sid:2241003; rev:1;)

@ -27,10 +27,10 @@ use crate::core::{ALPROTO_FAILED, ALPROTO_UNKNOWN, IPPROTO_TCP, *};
use crate::direction::Direction;
use crate::flow::Flow;
use nom7::{Err, IResult};
use suricata_sys::sys::AppProto;
use std;
use std::collections::VecDeque;
use std::ffi::CString;
use suricata_sys::sys::AppProto;
pub const PGSQL_CONFIG_DEFAULT_STREAM_DEPTH: u32 = 0;
@ -38,6 +38,14 @@ static mut ALPROTO_PGSQL: AppProto = ALPROTO_UNKNOWN;
static mut PGSQL_MAX_TX: usize = 1024;
#[derive(AppLayerEvent, Debug, PartialEq, Eq)]
pub enum PgsqlEvent {
InvalidLength, // Can't parse the length field
MalformedRequest, // Enough data, but unexpected request format
MalformedResponse, // Enough data, but unexpected response format
TooManyTransactions,
}
#[repr(u8)]
#[derive(Copy, Clone, PartialOrd, PartialEq, Eq, Debug)]
pub enum PgsqlTxProgress {
@ -218,7 +226,9 @@ impl PgsqlState {
// when they're parsed, as of now
tx_old.tx_req_state = PgsqlTxProgress::TxFlushedOut;
tx_old.tx_res_state = PgsqlTxProgress::TxFlushedOut;
//TODO set event
tx_old
.tx_data
.set_event(PgsqlEvent::TooManyTransactions as u8);
break;
}
}
@ -400,15 +410,18 @@ impl PgsqlState {
return AppLayerResult::incomplete(consumed as u32, needed_estimation as u32);
}
Err(Err::Error(err)) => {
let mut tx = self.new_tx();
match err {
PgsqlParseError::InvalidLength => {
// TODO set event invalid length event
tx.tx_data.set_event(PgsqlEvent::InvalidLength as u8);
self.transactions.push_back(tx);
// If we don't get a valid length, we can't know how to proceed
return AppLayerResult::err();
}
PgsqlParseError::NomError(_i, error_kind) => {
if error_kind == nom7::error::ErrorKind::Switch {
// TODO set event switch / PgsqlEvent::MalformedData // or something like that
tx.tx_data.set_event(PgsqlEvent::MalformedRequest as u8);
self.transactions.push_back(tx);
}
SCLogDebug!("Parsing error: {:?}", error_kind);
}
@ -593,15 +606,18 @@ impl PgsqlState {
return AppLayerResult::incomplete(consumed as u32, needed_estimation as u32);
}
Err(Err::Error(err)) => {
let mut tx = self.new_tx();
match err {
PgsqlParseError::InvalidLength => {
// TODO set event invalid length event
tx.tx_data.set_event(PgsqlEvent::InvalidLength as u8);
self.transactions.push_back(tx);
// If we don't get a valid length, we can't know how to proceed
return AppLayerResult::err();
}
PgsqlParseError::NomError(_i, error_kind) => {
if error_kind == nom7::error::ErrorKind::Switch {
// TODO set event switch / PgsqlEvent::MalformedData // or something like that
tx.tx_data.set_event(PgsqlEvent::MalformedResponse as u8);
self.transactions.push_back(tx);
}
SCLogDebug!("Parsing error: {:?}", error_kind);
}
@ -830,8 +846,8 @@ pub unsafe extern "C" fn SCRegisterPgsqlParser() {
tx_comp_st_ts: PgsqlTxProgress::TxDone as i32,
tx_comp_st_tc: PgsqlTxProgress::TxDone as i32,
tx_get_progress: tx_get_al_state_progress,
get_eventinfo: None,
get_eventinfo_byid: None,
get_eventinfo: Some(PgsqlEvent::get_event_info),
get_eventinfo_byid: Some(PgsqlEvent::get_event_info_by_id),
localstorage_new: None,
localstorage_free: None,
get_tx_files: None,

Loading…
Cancel
Save