]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/sdp: implement logger
authorGiuseppe Longo <giuseppe@glongo.it>
Sat, 16 Mar 2024 14:34:50 +0000 (15:34 +0100)
committerVictor Julien <victor@inliniac.net>
Thu, 25 Apr 2024 04:52:25 +0000 (06:52 +0200)
This implements a logger for the SDP protocol.
Given that SDP is encapsulated within other protocols (such as SIP),
enabling it separately is not necessary.

Ticket #6627

etc/schema.json
rust/src/sdp/logger.rs [new file with mode: 0644]
rust/src/sdp/mod.rs

index 24e9da1d1a02a5be566b083ae83a0a2a30cedccf..0350fe7593a679240151f49222816543ce50d649 100644 (file)
                 },
                 "version": {
                     "type": "string"
+                },
+                "sdp": {
+                    "type": "object",
+                    "description": "SDP message body",
+                    "optional": true,
+                    "properties": {
+                        "version": {
+                            "type": "integer",
+                            "description": "SDP protocol version"
+                        },
+                        "origin": {
+                            "type": "string",
+                            "description": "Owner of the session"
+                        },
+                        "session_name": {
+                            "type": "string",
+                            "description": "Session name"
+                        },
+                        "session_info": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Textual information about the session"
+                        },
+                        "uri": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "A pointer to additional information about the session"
+                        },
+                        "email": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Email address for the person responsible for the conference"
+                        },
+                        "phone_number": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Phone number for the person responsible for the conference"
+                        },
+                        "connection_data": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Connection data"
+                        },
+                        "bandwidths": {
+                            "type": "array",
+                            "optional": true,
+                            "description": "Proposed bandwidths to be used by the session or media",
+                            "minItems": 1,
+                            "items": {
+                                "type": "string"
+                            }
+                        },
+                        "time": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Start and stop times for a session"
+                        },
+                        "repeat_time": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Specify repeat times for a session"
+                        },
+                        "timezone": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Timezone to specify adjustments for times and offsets from the base time"
+                        },
+                        "encryption_key": {
+                            "type": "string",
+                            "optional": true,
+                            "description": "Field used to convey encryption keys if SDP is used over a secure channel"
+                        },
+                        "attributes": {
+                            "type": "array",
+                            "optional": true,
+                            "description": "A list of attributes to extend SDP",
+                            "minItems": 1,
+                            "items": {
+                                "type": "string",
+                                "description": "Attribute's name and value"
+                            }
+                        },
+                        "media_descriptions": {
+                            "type": "array",
+                            "description": "A list of media descriptions for a session",
+                            "minItems": 1,
+                            "items": {
+                                "type": "object",
+                                "optional": true,
+                                "properties": {
+                                    "media": {
+                                        "type": "string",
+                                        "description": "Media description"
+                                    },
+                                    "media_info": {
+                                        "type": "string",
+                                        "optional": true,
+                                        "description": "Media information primarily intended for labelling media streams"
+                                    },
+                                    "bandwidths": {
+                                        "type": "array",
+                                        "optional": true,
+                                        "description": "A list of bandwidth proposed for a media",
+                                        "minItems": 1,
+                                        "items": {
+                                            "type": "string"
+                                        }
+                                    },
+                                    "connection_data": {
+                                        "type": "string",
+                                        "optional": true,
+                                        "description": "Connection data per media description"
+                                    },
+                                    "attributes": {
+                                        "type": "array",
+                                        "description": "A list of attributes specified for a media description",
+                                        "optional": true,
+                                        "minItems": 1,
+                                        "items": {
+                                            "type": "string",
+                                            "description": "Attribute's name and value"
+                                        }
+                                    }
+                                },
+                                "additionalProperties": false
+                            }
+                        }
+                    },
+                    "additionalProperties": false
                 }
             },
             "additionalProperties": false
diff --git a/rust/src/sdp/logger.rs b/rust/src/sdp/logger.rs
new file mode 100644 (file)
index 0000000..b5e8cbc
--- /dev/null
@@ -0,0 +1,154 @@
+/* Copyright (C) 2024 Open Information Security Foundation
+ *
+ * You can copy, redistribute or modify this Program under the terms of
+ * the GNU General Public License version 2 as published by the Free
+ * Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+// written by Giuseppe Longo <giuseppe@glongo.it>
+
+use crate::jsonbuilder::{JsonBuilder, JsonError};
+
+use super::parser::{ConnectionData, MediaDescription, SdpMessage};
+
+pub fn sdp_log(msg: &SdpMessage, js: &mut JsonBuilder) -> Result<(), JsonError> {
+    js.open_object("sdp")?;
+
+    let origin = format!(
+        "{} {} {} {} {} {}",
+        &msg.origin.username,
+        &msg.origin.sess_id,
+        &msg.origin.sess_version,
+        &msg.origin.nettype,
+        &msg.origin.addrtype,
+        &msg.origin.unicast_address
+    );
+
+    js.set_string("origin", &origin)?;
+    js.set_string("session_name", &msg.session_name)?;
+
+    if let Some(session_info) = &msg.session_info {
+        js.set_string("session_info", session_info)?;
+    }
+    if let Some(uri) = &msg.uri {
+        js.set_string("uri", uri)?;
+    }
+    if let Some(email) = &msg.email {
+        js.set_string("email", email)?;
+    }
+    if let Some(phone_number) = &msg.phone_number {
+        js.set_string("phone_number", phone_number)?;
+    }
+    if let Some(conn_data) = &msg.connection_data {
+        log_connection_data(conn_data, js)?;
+    }
+    if let Some(bws) = &msg.bandwidths {
+        log_bandwidth(bws, js)?;
+    }
+    js.set_string("time", &msg.time)?;
+    if let Some(repeat_time) = &msg.repeat_time {
+        js.set_string("repeat_time", repeat_time)?;
+    }
+    if let Some(tz) = &msg.time_zone {
+        js.set_string("timezone", tz)?;
+    }
+    if let Some(enc_key) = &msg.encryption_key {
+        js.set_string("encryption_key", enc_key)?;
+    }
+    if let Some(attrs) = &msg.attributes {
+        log_attributes(attrs, js)?;
+    }
+    if let Some(media) = &msg.media_description {
+        log_media_description(media, js)?;
+    }
+    js.close()?;
+    Ok(())
+}
+
+fn log_media_description(
+    media: &Vec<MediaDescription>, js: &mut JsonBuilder,
+) -> Result<(), JsonError> {
+    if !media.is_empty() {
+        js.open_array("media_descriptions")?;
+        for m in media {
+            js.start_object()?;
+            let port = if let Some(num_ports) = m.number_of_ports {
+                format!("{}/{}", m.port, num_ports)
+            } else {
+                format!("{}", m.port)
+            };
+            let mut media = format!("{} {} {}", &m.media, &port, &m.proto);
+            for f in &m.fmt {
+                media = format!("{} {}", media, f);
+            }
+            js.set_string("media", &media)?;
+
+            if let Some(session_info) = &m.session_info {
+                js.set_string("media_info", session_info)?;
+            };
+            if let Some(bws) = &m.bandwidths {
+                log_bandwidth(bws, js)?;
+            }
+            if let Some(conn_data) = &m.connection_data {
+                log_connection_data(conn_data, js)?;
+            }
+            if let Some(attrs) = &m.attributes {
+                log_attributes(attrs, js)?;
+            }
+            js.close()?;
+        }
+    }
+    js.close()?;
+
+    Ok(())
+}
+
+fn log_bandwidth(bws: &Vec<String>, js: &mut JsonBuilder) -> Result<(), JsonError> {
+    if !bws.is_empty() {
+        js.open_array("bandwidths")?;
+        for bw in bws {
+            js.append_string(bw)?;
+        }
+        js.close()?;
+    }
+    Ok(())
+}
+
+fn log_connection_data(conn_data: &ConnectionData, js: &mut JsonBuilder) -> Result<(), JsonError> {
+    let mut conn = format!(
+        "{} {} {}",
+        &conn_data.nettype,
+        &conn_data.addrtype,
+        &conn_data.connection_address.to_string()
+    );
+    if let Some(ttl) = conn_data.ttl {
+        conn = format!("{}/{}", conn, ttl);
+        js.set_uint("ttl", ttl as u64)?;
+    }
+    if let Some(num_addrs) = conn_data.number_of_addresses {
+        conn = format!("{}/{}", conn, num_addrs);
+    }
+    js.set_string("connection_data", &conn)?;
+    Ok(())
+}
+
+fn log_attributes(attrs: &Vec<String>, js: &mut JsonBuilder) -> Result<(), JsonError> {
+    if !attrs.is_empty() {
+        js.open_array("attributes")?;
+        for attr in attrs {
+            js.append_string(attr)?;
+        }
+        js.close()?;
+    }
+    Ok(())
+}
index 67c567fa01026f8b9cd0be34ab8e7df67a80fdd9..7f87c8b7e2f0a0de1e663caf66a5a2cb74a0e88e 100644 (file)
@@ -1 +1,2 @@
+pub mod logger;
 pub mod parser;