mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-27 18:02:58 +01:00
add no-op SSL TLV
This commit is contained in:
parent
21c31ad63d
commit
70f59f46ef
@ -8,15 +8,17 @@ description = "PROXY protocol utilities"
|
|||||||
keywords = ["proxy", "protocol", "network", "haproxy", "tcp"]
|
keywords = ["proxy", "protocol", "network", "haproxy", "tcp"]
|
||||||
categories = ["network-programming", "asynchronous"]
|
categories = ["network-programming", "asynchronous"]
|
||||||
homepage = "https://actix.rs"
|
homepage = "https://actix.rs"
|
||||||
repository = "https://github.com/actix/actix-net.git"
|
repository = "https://github.com/actix/actix-net"
|
||||||
license = "MIT OR Apache-2.0"
|
license.workspace = true
|
||||||
edition = "2018"
|
edition.workspace = true
|
||||||
|
rust-version.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-service = "2"
|
actix-service = "2"
|
||||||
actix-utils = "3"
|
actix-utils = "3"
|
||||||
|
|
||||||
arrayvec = "0.7"
|
arrayvec = "0.7"
|
||||||
|
bitflags = "2"
|
||||||
crc32fast = "1"
|
crc32fast = "1"
|
||||||
futures-core = { version = "0.3.17", default-features = false, features = ["std"] }
|
futures-core = { version = "0.3.17", default-features = false, features = ["std"] }
|
||||||
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
|
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use std::{borrow::Cow, convert::TryFrom, str};
|
use std::{borrow::Cow, convert::TryFrom, str};
|
||||||
|
|
||||||
const PP2_TYPE_ALPN: u8 = 0x01;
|
const PP2_TYPE_ALPN: u8 = 0x01; // done
|
||||||
const PP2_TYPE_AUTHORITY: u8 = 0x02;
|
const PP2_TYPE_AUTHORITY: u8 = 0x02; // done
|
||||||
const PP2_TYPE_CRC32C: u8 = 0x03; // done
|
const PP2_TYPE_CRC32C: u8 = 0x03; // done
|
||||||
const PP2_TYPE_NOOP: u8 = 0x04; // done
|
const PP2_TYPE_NOOP: u8 = 0x04; // done
|
||||||
const PP2_TYPE_UNIQUE_ID: u8 = 0x05; // done
|
const PP2_TYPE_UNIQUE_ID: u8 = 0x05; // done
|
||||||
@ -100,7 +100,7 @@ impl Tlv for Authority {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn value_bytes(&self) -> Cow<'_, [u8]> {
|
fn value_bytes(&self) -> Cow<'_, [u8]> {
|
||||||
Cow::Borrowed(&self.authority.as_bytes())
|
Cow::Borrowed(self.authority.as_bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,11 +178,15 @@ impl UniqueId {
|
|||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
/// Panics if `value` is empty (i.e., has length of 0).
|
/// Panics if `value` is 0 bytes or larger than 128 bytes.
|
||||||
pub fn new(id: impl Into<Vec<u8>>) -> Self {
|
pub fn new(id: impl Into<Vec<u8>>) -> Self {
|
||||||
let value = id.into();
|
let value = id.into();
|
||||||
|
|
||||||
assert!(!value.is_empty(), "UniqueId TLV `value` cannot be empty");
|
assert!(!value.is_empty(), "UniqueId TLV `value` cannot be empty");
|
||||||
|
assert!(
|
||||||
|
value.len() < 128,
|
||||||
|
"UniqueId TLV `value` cannot be larger than 128 bytes"
|
||||||
|
);
|
||||||
|
|
||||||
Self { value }
|
Self { value }
|
||||||
}
|
}
|
||||||
@ -202,6 +206,67 @@ impl Tlv for UniqueId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct SslClientFlags: u8 {
|
||||||
|
const PP2_CLIENT_SSL = 0x01;
|
||||||
|
const PP2_CLIENT_CERT_CONN = 0x02;
|
||||||
|
const PP2_CLIENT_CERT_SESS = 0x04;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TLS (SSL).
|
||||||
|
///
|
||||||
|
/// Heckin broken atm.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct Ssl {
|
||||||
|
/// The <client> field is made of a bit field indicating which element is present.
|
||||||
|
///
|
||||||
|
/// Note, that each of these elements may lead to extra data being appended to
|
||||||
|
/// this TLV using a second level of TLV encapsulation. It is thus possible to
|
||||||
|
/// find multiple TLV values after this field. The total length of the pp2_tlv_ssl
|
||||||
|
/// TLV will reflect this.
|
||||||
|
client: SslClientFlags,
|
||||||
|
|
||||||
|
/// The <verify> field will be zero if the client presented a certificate
|
||||||
|
/// and it was successfully verified, and non-zero otherwise.
|
||||||
|
verify: bool,
|
||||||
|
|
||||||
|
/// Sub-TLVs.
|
||||||
|
tlvs: Vec<SslTlv>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Tlv for Ssl {
|
||||||
|
const TYPE: u8 = PP2_TYPE_SSL;
|
||||||
|
|
||||||
|
fn try_from_value(value: &[u8]) -> Option<Self> {
|
||||||
|
/// The PP2_CLIENT_SSL flag indicates that the client connected over SSL/TLS. When
|
||||||
|
/// this field is present, the US-ASCII string representation of the TLS version is
|
||||||
|
/// appended at the end of the field in the TLV format using the type
|
||||||
|
/// PP2_SUBTYPE_SSL_VERSION.
|
||||||
|
const PP2_CLIENT_SSL: u8 = 0x01;
|
||||||
|
|
||||||
|
/// PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
|
||||||
|
/// current connection.
|
||||||
|
const PP2_CLIENT_CERT_CONN: u8 = 0x02;
|
||||||
|
|
||||||
|
/// PP2_CLIENT_CERT_SESS indicates that the client provided a
|
||||||
|
/// certificate at least once over the TLS session this connection belongs to.
|
||||||
|
const PP2_CLIENT_CERT_SESS: u8 = 0x04;
|
||||||
|
|
||||||
|
// TODO: finish parsing
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn value_bytes(&self) -> Cow<'_, [u8]> {
|
||||||
|
Cow::Borrowed(&[])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
struct SslTlv {}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -110,7 +110,7 @@ impl Header {
|
|||||||
for (typ, value) in &self.tlvs {
|
for (typ, value) in &self.tlvs {
|
||||||
wrt.write_all(&[*typ])?;
|
wrt.write_all(&[*typ])?;
|
||||||
wrt.write_all(&(value.len() as u16).to_be_bytes())?;
|
wrt.write_all(&(value.len() as u16).to_be_bytes())?;
|
||||||
wrt.write_all(&value)?;
|
wrt.write_all(value)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -170,7 +170,7 @@ impl Header {
|
|||||||
let crc_sent = self
|
let crc_sent = self
|
||||||
.tlvs
|
.tlvs
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(typ, value)| Crc32c::try_from_parts(*typ, &value))
|
.filter_map(|(typ, value)| Crc32c::try_from_parts(*typ, value))
|
||||||
.next()?;
|
.next()?;
|
||||||
|
|
||||||
// If the checksum is provided as part of the PROXY header and the checksum
|
// If the checksum is provided as part of the PROXY header and the checksum
|
||||||
@ -185,7 +185,7 @@ impl Header {
|
|||||||
|
|
||||||
let mut this = self.clone();
|
let mut this = self.clone();
|
||||||
for (typ, value) in this.tlvs.iter_mut() {
|
for (typ, value) in this.tlvs.iter_mut() {
|
||||||
if Crc32c::try_from_parts(*typ, &value).is_some() {
|
if Crc32c::try_from_parts(*typ, value).is_some() {
|
||||||
value.fill(0);
|
value.fill(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user