aboutsummaryrefslogtreecommitdiff
path: root/src/message
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/message/handshake.rs (renamed from src/protocol/message/handshake.rs)159
-rw-r--r--src/message/handshake/types.rs (renamed from src/protocol/message/handshake/types.rs)22
-rw-r--r--src/message/login.rs (renamed from src/protocol/message/login.rs)0
-rw-r--r--src/message/mod.rs (renamed from src/protocol/message/mod.rs)6
4 files changed, 130 insertions, 57 deletions
diff --git a/src/protocol/message/handshake.rs b/src/message/handshake.rs
index 357d1a4..753488e 100644
--- a/src/protocol/message/handshake.rs
+++ b/src/message/handshake.rs
@@ -1,23 +1,56 @@
use failure::Error;
use std::result::Result;
-use crate::protocol::error::ProtocolError;
-use crate::protocol::primitive::{String, StringList, Variant, VariantList};
-use crate::util::get_msg_type;
-
+use crate::error::ProtocolError;
+use crate::primitive::{StringList, Variant, VariantList};
mod types;
-pub use types::{HandshakeDeserialize, HandshakeSerialize, VariantMap};
+use crate::primitive::VariantMap;
+use crate::{HandshakeDeserialize, HandshakeSerialize};
use crate::match_variant;
+/// Data received right after initializing the connection
+///
+/// ConnAck is serialized sequentially
#[derive(Debug)]
pub struct ConnAck {
+ /// The Flag 0x01 for TLS
+ /// and 0x02 for Deflate Compression
flags: u8,
+ /// Some extra protocol version specific data
+ /// So far unused
extra: i16,
+ /// The version of the protocol
+ /// 0x00000001 for the legacy protocol
+ /// 0x00000002 for the datastream protocol
+ ///
+ /// Only the datastream protocol is supported by this crate
version: i8,
}
-impl crate::protocol::primitive::deserialize::Deserialize for ConnAck {
+impl Default for ConnAck {
+ fn default() -> Self {
+ Self {
+ flags: 0x00,
+ extra: 0x00,
+ version: 0x00000002,
+ }
+ }
+}
+
+impl crate::Serialize for ConnAck {
+ fn serialize(&self) -> Result<Vec<std::primitive::u8>, Error> {
+ let mut bytes: Vec<u8> = Vec::new();
+
+ bytes.append(&mut self.flags.serialize()?);
+ bytes.append(&mut self.extra.serialize()?);
+ bytes.append(&mut self.version.serialize()?);
+
+ Ok(bytes)
+ }
+}
+
+impl crate::Deserialize for ConnAck {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (flen, flags) = u8::parse(b)?;
let (elen, extra) = i16::parse(&b[flen..])?;
@@ -34,12 +67,44 @@ impl crate::protocol::primitive::deserialize::Deserialize for ConnAck {
}
}
+/// ClientInit is the Initial message send to the core after establishing a base layer comunication.
+///
+/// Features
+///
+/// | Flag | Name | Description |
+/// | ---- | ---- | ----------- |
+/// | 0x00000001 | SynchronizedMarkerLine | -- |
+/// | 0x00000002 | SaslAuthentication | -- |
+/// | 0x00000004 | SaslExternal | -- |
+/// | 0x00000008 | HideInactiveNetworks | -- |
+/// | 0x00000010 | PasswordChange | -- |
+/// | 0x00000020 | CapNegotiation | IRCv3 capability negotiation, account tracking |
+/// | 0x00000040 | VerifyServerSSL | IRC server SSL validation |
+/// | 0x00000080 | CustomRateLimits | IRC server custom message rate limits |
+/// | 0x00000100 | DccFileTransfer | Currently not supported |
+/// | 0x00000200 | AwayFormatTimestamp | Timestamp formatting in away (e.g. %%hh:mm%%) |
+/// | 0x00000400 | Authenticators | Support for exchangeable auth backends |
+/// | 0x00000800 | BufferActivitySync | Sync buffer activity status |
+/// | 0x00001000 | CoreSideHighlights | Core-Side highlight configuration and matching |
+/// | 0x00002000 | SenderPrefixes | Show prefixes for senders in backlog |
+/// | 0x00004000 | RemoteDisconnect | Supports RPC call disconnectFromCore to remotely disconnect a client |
+/// | 0x00008000 | ExtendedFeatures | Transmit features as list of strings |
+/// | -- | LongTime | Serialize message time as 64-bit |
+/// | -- | RichMessages | Real Name and Avatar URL in backlog |
+/// | -- | BacklogFilterType | Backlogmanager supports filtering backlog by messagetype |
+/// | -- | EcdsaCertfpKeys | ECDSA keys for CertFP in identities |
+/// | -- | LongMessageId | 64-bit IDs for messages |
+/// | -- | SyncedCoreInfo | CoreInfo dynamically updated using signals |
#[derive(Debug)]
pub struct ClientInit {
- pub client_version: String, // Version of the client
- pub client_date: String, // Build date of the client
+ /// Version of the client
+ pub client_version: String,
+ /// Build date of the client
+ pub client_date: String,
+ /// supported features as bitflags
pub client_features: u32,
- pub feature_list: StringList, // List of supported extended features
+ /// List of supported extended features
+ pub feature_list: StringList,
}
impl HandshakeSerialize for ClientInit {
@@ -70,16 +135,16 @@ impl HandshakeDeserialize for ClientInit {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientInit" {
return Ok((
len,
Self {
- client_version: match_variant!(values, Variant::String, "ClientVersion"),
- client_date: match_variant!(values, Variant::String, "ClientDate"),
- feature_list: match_variant!(values, Variant::StringList, "FeatureList"),
- client_features: match_variant!(values, Variant::u32, "Features"),
+ client_version: match_variant!(values["ClientVersion"], Variant::String),
+ client_date: match_variant!(values["ClientDate"], Variant::String),
+ feature_list: match_variant!(values["FeatureList"], Variant::StringList),
+ client_features: match_variant!(values["Features"], Variant::u32),
},
));
} else {
@@ -88,8 +153,10 @@ impl HandshakeDeserialize for ClientInit {
}
}
+/// ClientInitReject is received when the initialization fails
#[derive(Debug)]
pub struct ClientInitReject {
+ /// String with an error message of what went wrong
pub error_string: String,
}
@@ -112,13 +179,13 @@ impl HandshakeDeserialize for ClientInitReject {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientInitReject" {
return Ok((
len,
Self {
- error_string: match_variant!(values, Variant::String, "ErrorString"),
+ error_string: match_variant!(values["ErrorString"], Variant::String),
},
));
} else {
@@ -127,13 +194,19 @@ impl HandshakeDeserialize for ClientInitReject {
}
}
+/// ClientInitAck is received when the initialization was successfull
#[derive(Debug)]
pub struct ClientInitAck {
- pub core_features: u32, // Flags of supported legacy features
- pub core_configured: bool, // If the core has already been configured
- pub storage_backends: VariantList, // List of VariantMaps of info on available backends
- pub authenticators: VariantList, // List of VariantMaps of info on available authenticators
- pub feature_list: StringList, // List of supported extended features
+ /// Flags of supported legacy features
+ pub core_features: u32,
+ /// If the core has already been configured
+ pub core_configured: bool,
+ /// List of VariantMaps of info on available backends
+ pub storage_backends: VariantList,
+ /// List of VariantMaps of info on available authenticators
+ pub authenticators: VariantList,
+ /// List of supported extended features
+ pub feature_list: StringList,
}
impl HandshakeSerialize for ClientInitAck {
@@ -168,21 +241,20 @@ impl HandshakeDeserialize for ClientInitAck {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientInitAck" {
return Ok((
len,
Self {
core_features: 0x00008000,
- core_configured: match_variant!(values, Variant::bool, "Configured"),
+ core_configured: match_variant!(values["Configured"], Variant::bool),
storage_backends: match_variant!(
- values,
- Variant::VariantList,
- "StorageBackends"
+ values["StorageBackends"],
+ Variant::VariantList
),
- authenticators: match_variant!(values, Variant::VariantList, "Authenticators"),
- feature_list: match_variant!(values, Variant::StringList, "FeatureList"),
+ authenticators: match_variant!(values["Authenticators"], Variant::VariantList),
+ feature_list: match_variant!(values["FeatureList"], Variant::StringList),
},
));
} else {
@@ -191,6 +263,8 @@ impl HandshakeDeserialize for ClientInitAck {
}
}
+/// Login to the core with user data
+/// username and password are transmitted in plain text
#[derive(Debug)]
pub struct ClientLogin {
pub user: String,
@@ -217,14 +291,14 @@ impl HandshakeDeserialize for ClientLogin {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientLogin" {
return Ok((
len,
Self {
- user: match_variant!(values, Variant::String, "User"),
- password: match_variant!(values, Variant::String, "Password"),
+ user: match_variant!(values["User"], Variant::String),
+ password: match_variant!(values["Password"], Variant::String),
},
));
} else {
@@ -233,6 +307,8 @@ impl HandshakeDeserialize for ClientLogin {
}
}
+/// ClientLoginAck is received after the client has successfully logged in
+/// it has no fields
#[derive(Debug)]
pub struct ClientLoginAck;
@@ -251,7 +327,7 @@ impl HandshakeDeserialize for ClientLoginAck {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientLogin" {
return Ok((len, Self {}));
@@ -261,6 +337,8 @@ impl HandshakeDeserialize for ClientLoginAck {
}
}
+/// ClientLoginReject is received after the client failed to login
+/// It contains an error message as String
#[derive(Debug)]
pub struct ClientLoginReject {
error: String,
@@ -285,13 +363,13 @@ impl HandshakeDeserialize for ClientLoginReject {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientLogin" {
return Ok((
len,
Self {
- error: match_variant!(values, Variant::String, "ErrorString"),
+ error: match_variant!(values["ErrorString"], Variant::String),
},
));
} else {
@@ -300,10 +378,15 @@ impl HandshakeDeserialize for ClientLoginReject {
}
}
+/// SessionInit is received along with ClientLoginAck to initialize that user Session
+// TODO Replace with proper types
#[derive(Debug)]
pub struct SessionInit {
+ /// List of all configured identities
identities: VariantList,
+ /// List of all existing buffers
buffers: VariantList,
+ /// Ids of all networks
network_ids: VariantList,
}
@@ -334,15 +417,15 @@ impl HandshakeDeserialize for SessionInit {
fn parse(b: &[u8]) -> Result<(usize, Self), Error> {
let (len, values): (usize, VariantMap) = HandshakeDeserialize::parse(b)?;
- let msgtype = get_msg_type(&values["MsgType"])?;
+ let msgtype = match_variant!(&values["MsgType"], Variant::StringUTF8);
if msgtype == "ClientLogin" {
return Ok((
len,
Self {
- identities: match_variant!(values, Variant::VariantList, "Identities"),
- buffers: match_variant!(values, Variant::VariantList, "BufferInfos"),
- network_ids: match_variant!(values, Variant::VariantList, "NetworkIds"),
+ identities: match_variant!(values["Identities"], Variant::VariantList),
+ buffers: match_variant!(values["BufferInfos"], Variant::VariantList),
+ network_ids: match_variant!(values["NetworkIds"], Variant::VariantList),
},
));
} else {
diff --git a/src/protocol/message/handshake/types.rs b/src/message/handshake/types.rs
index 99864b9..04e1dd0 100644
--- a/src/protocol/message/handshake/types.rs
+++ b/src/message/handshake/types.rs
@@ -1,27 +1,17 @@
-use std::collections::HashMap;
use std::convert::TryInto;
use std::result::Result;
use std::vec::Vec;
use failure::Error;
-use crate::protocol::error::ProtocolError;
-use crate::protocol::primitive::deserialize::Deserialize;
-use crate::protocol::primitive::serialize::Serialize;
-use crate::protocol::primitive::{String, Variant};
+use crate::error::ProtocolError;
+use crate::primitive::Variant;
+use crate::Deserialize;
+use crate::Serialize;
use crate::util;
-pub trait HandshakeSerialize {
- fn serialize(&self) -> Result<Vec<u8>, Error>;
-}
-
-pub trait HandshakeDeserialize {
- fn parse(b: &[u8]) -> Result<(usize, Self), Error>
- where
- Self: std::marker::Sized;
-}
-
-pub type VariantMap = HashMap<String, Variant>;
+use crate::primitive::VariantMap;
+use crate::{HandshakeDeserialize, HandshakeSerialize};
impl HandshakeSerialize for VariantMap {
fn serialize<'a>(&'a self) -> Result<Vec<u8>, Error> {
diff --git a/src/protocol/message/login.rs b/src/message/login.rs
index 8b13789..8b13789 100644
--- a/src/protocol/message/login.rs
+++ b/src/message/login.rs
diff --git a/src/protocol/message/mod.rs b/src/message/mod.rs
index f1d4750..b390e2f 100644
--- a/src/protocol/message/mod.rs
+++ b/src/message/mod.rs
@@ -1,5 +1,5 @@
-pub mod handshake;
-pub use handshake::*;
+mod handshake;
+mod login;
-pub mod login;
+pub use handshake::*;
pub use login::*;