Skip to content

Commit 70f59f4

Browse files
committed
add no-op SSL TLV
1 parent 21c31ad commit 70f59f4

File tree

3 files changed

+77
-10
lines changed

3 files changed

+77
-10
lines changed

actix-proxy-protocol/Cargo.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@ description = "PROXY protocol utilities"
88
keywords = ["proxy", "protocol", "network", "haproxy", "tcp"]
99
categories = ["network-programming", "asynchronous"]
1010
homepage = "https://actix.rs"
11-
repository = "https://github.com/actix/actix-net.git"
12-
license = "MIT OR Apache-2.0"
13-
edition = "2018"
11+
repository = "https://github.com/actix/actix-net"
12+
license.workspace = true
13+
edition.workspace = true
14+
rust-version.workspace = true
1415

1516
[dependencies]
1617
actix-service = "2"
1718
actix-utils = "3"
1819

1920
arrayvec = "0.7"
21+
bitflags = "2"
2022
crc32fast = "1"
2123
futures-core = { version = "0.3.17", default-features = false, features = ["std"] }
2224
futures-util = { version = "0.3.17", default-features = false, features = ["std"] }

actix-proxy-protocol/src/tlv.rs

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::{borrow::Cow, convert::TryFrom, str};
22

3-
const PP2_TYPE_ALPN: u8 = 0x01;
4-
const PP2_TYPE_AUTHORITY: u8 = 0x02;
3+
const PP2_TYPE_ALPN: u8 = 0x01; // done
4+
const PP2_TYPE_AUTHORITY: u8 = 0x02; // done
55
const PP2_TYPE_CRC32C: u8 = 0x03; // done
66
const PP2_TYPE_NOOP: u8 = 0x04; // done
77
const PP2_TYPE_UNIQUE_ID: u8 = 0x05; // done
@@ -100,7 +100,7 @@ impl Tlv for Authority {
100100
}
101101

102102
fn value_bytes(&self) -> Cow<'_, [u8]> {
103-
Cow::Borrowed(&self.authority.as_bytes())
103+
Cow::Borrowed(self.authority.as_bytes())
104104
}
105105
}
106106

@@ -178,11 +178,15 @@ impl UniqueId {
178178
///
179179
///
180180
/// # Panics
181-
/// Panics if `value` is empty (i.e., has length of 0).
181+
/// Panics if `value` is 0 bytes or larger than 128 bytes.
182182
pub fn new(id: impl Into<Vec<u8>>) -> Self {
183183
let value = id.into();
184184

185185
assert!(!value.is_empty(), "UniqueId TLV `value` cannot be empty");
186+
assert!(
187+
value.len() < 128,
188+
"UniqueId TLV `value` cannot be larger than 128 bytes"
189+
);
186190

187191
Self { value }
188192
}
@@ -202,6 +206,67 @@ impl Tlv for UniqueId {
202206
}
203207
}
204208

209+
bitflags::bitflags! {
210+
#[derive(Debug, Clone, PartialEq, Eq)]
211+
struct SslClientFlags: u8 {
212+
const PP2_CLIENT_SSL = 0x01;
213+
const PP2_CLIENT_CERT_CONN = 0x02;
214+
const PP2_CLIENT_CERT_SESS = 0x04;
215+
}
216+
}
217+
218+
/// TLS (SSL).
219+
///
220+
/// Heckin broken atm.
221+
#[derive(Debug, Clone, PartialEq, Eq)]
222+
pub struct Ssl {
223+
/// The <client> field is made of a bit field indicating which element is present.
224+
///
225+
/// Note, that each of these elements may lead to extra data being appended to
226+
/// this TLV using a second level of TLV encapsulation. It is thus possible to
227+
/// find multiple TLV values after this field. The total length of the pp2_tlv_ssl
228+
/// TLV will reflect this.
229+
client: SslClientFlags,
230+
231+
/// The <verify> field will be zero if the client presented a certificate
232+
/// and it was successfully verified, and non-zero otherwise.
233+
verify: bool,
234+
235+
/// Sub-TLVs.
236+
tlvs: Vec<SslTlv>,
237+
}
238+
239+
impl Tlv for Ssl {
240+
const TYPE: u8 = PP2_TYPE_SSL;
241+
242+
fn try_from_value(value: &[u8]) -> Option<Self> {
243+
/// The PP2_CLIENT_SSL flag indicates that the client connected over SSL/TLS. When
244+
/// this field is present, the US-ASCII string representation of the TLS version is
245+
/// appended at the end of the field in the TLV format using the type
246+
/// PP2_SUBTYPE_SSL_VERSION.
247+
const PP2_CLIENT_SSL: u8 = 0x01;
248+
249+
/// PP2_CLIENT_CERT_CONN indicates that the client provided a certificate over the
250+
/// current connection.
251+
const PP2_CLIENT_CERT_CONN: u8 = 0x02;
252+
253+
/// PP2_CLIENT_CERT_SESS indicates that the client provided a
254+
/// certificate at least once over the TLS session this connection belongs to.
255+
const PP2_CLIENT_CERT_SESS: u8 = 0x04;
256+
257+
// TODO: finish parsing
258+
259+
None
260+
}
261+
262+
fn value_bytes(&self) -> Cow<'_, [u8]> {
263+
Cow::Borrowed(&[])
264+
}
265+
}
266+
267+
#[derive(Debug, Clone, PartialEq, Eq)]
268+
struct SslTlv {}
269+
205270
#[cfg(test)]
206271
mod tests {
207272
use super::*;

actix-proxy-protocol/src/v2.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ impl Header {
110110
for (typ, value) in &self.tlvs {
111111
wrt.write_all(&[*typ])?;
112112
wrt.write_all(&(value.len() as u16).to_be_bytes())?;
113-
wrt.write_all(&value)?;
113+
wrt.write_all(value)?;
114114
}
115115

116116
Ok(())
@@ -170,7 +170,7 @@ impl Header {
170170
let crc_sent = self
171171
.tlvs
172172
.iter()
173-
.filter_map(|(typ, value)| Crc32c::try_from_parts(*typ, &value))
173+
.filter_map(|(typ, value)| Crc32c::try_from_parts(*typ, value))
174174
.next()?;
175175

176176
// If the checksum is provided as part of the PROXY header and the checksum
@@ -185,7 +185,7 @@ impl Header {
185185

186186
let mut this = self.clone();
187187
for (typ, value) in this.tlvs.iter_mut() {
188-
if Crc32c::try_from_parts(*typ, &value).is_some() {
188+
if Crc32c::try_from_parts(*typ, value).is_some() {
189189
value.fill(0);
190190
}
191191
}

0 commit comments

Comments
 (0)