Skip to content

Commit

Permalink
PoC authentication
Browse files Browse the repository at this point in the history
Signed-off-by: Eloi DEMOLIS <[email protected]>
  • Loading branch information
Wonshtrum committed Dec 20, 2024
1 parent 0722e78 commit 6110de3
Show file tree
Hide file tree
Showing 10 changed files with 185 additions and 111 deletions.
2 changes: 2 additions & 0 deletions bin/src/ctl/request_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ impl CommandManager {
Some(tags) => tags,
None => BTreeMap::new(),
},
required_auth: todo!(),
redirect: todo!(),

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 254 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression
redirect_scheme: todo!(),
redirect_template: todo!(),
Expand Down Expand Up @@ -304,6 +305,7 @@ impl CommandManager {
Some(tags) => tags,
None => BTreeMap::new(),
},
required_auth: todo!(),
redirect: todo!(),

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (nightly, true)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, stable)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Test (false, beta)

unreachable expression

Check warning on line 309 in bin/src/ctl/request_builder.rs

View workflow job for this annotation

GitHub Actions / Build Sozu 🦀

unreachable expression
redirect_scheme: todo!(),
redirect_template: todo!(),
Expand Down
17 changes: 9 additions & 8 deletions command/src/command.proto
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,8 @@ message ListenersList {

enum RedirectPolicy {
FORWARD = 0;
TEMPORARY = 1;
PERMANENT = 2;
UNAUTHORIZED = 3;
PERMANENT = 1;
UNAUTHORIZED = 2;
}

enum RedirectScheme {
Expand All @@ -236,11 +235,12 @@ message RequestHttpFrontend {
// custom tags to identify the frontend in the access logs
map<string, string> tags = 7;
optional RedirectPolicy redirect = 8;
optional RedirectScheme redirect_scheme = 9;
optional string redirect_template = 10;
optional string rewrite_host = 11;
optional string rewrite_path = 12;
optional uint32 rewrite_port = 13;
optional bool required_auth = 9;
optional RedirectScheme redirect_scheme = 10;
optional string redirect_template = 11;
optional string rewrite_host = 12;
optional string rewrite_path = 13;
optional uint32 rewrite_port = 14;
}

message RequestTcpFrontend {
Expand Down Expand Up @@ -371,6 +371,7 @@ message Cluster {
optional LoadMetric load_metric = 7;
optional uint32 https_redirect_port = 8;
map<string, string> answers = 9;
repeated uint64 authorized_hashes = 10;
}

enum LoadBalancingAlgorithms {
Expand Down
11 changes: 11 additions & 0 deletions command/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ pub struct FileClusterFrontendConfig {
#[serde(default)]
pub position: RulePosition,
pub tags: Option<BTreeMap<String, String>>,
pub required_auth: Option<bool>,
pub redirect: Option<RedirectPolicy>,
pub redirect_scheme: Option<RedirectScheme>,
pub redirect_template: Option<String>,
Expand Down Expand Up @@ -716,6 +717,7 @@ impl FileClusterFrontendConfig {
path,
method: self.method.clone(),
tags: self.tags.clone(),
required_auth: self.required_auth.unwrap_or(false),
redirect: self.redirect,
redirect_scheme: self.redirect_scheme,
redirect_template: self.redirect_template.clone(),
Expand Down Expand Up @@ -758,6 +760,8 @@ pub struct FileClusterConfig {
pub load_metric: Option<LoadMetric>,
#[serde(default)]
pub answers: Option<BTreeMap<String, String>>,
#[serde(default)]
pub authorized_hashes: Vec<u64>,
}

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
Expand Down Expand Up @@ -845,6 +849,7 @@ impl FileClusterConfig {
load_balancing: self.load_balancing,
load_metric: self.load_metric,
answers: load_answers(self.answers.as_ref())?,
authorized_hashes: self.authorized_hashes,
}))
}
}
Expand All @@ -866,6 +871,7 @@ pub struct HttpFrontendConfig {
#[serde(default)]
pub position: RulePosition,
pub tags: Option<BTreeMap<String, String>>,
pub required_auth: bool,
pub redirect: Option<RedirectPolicy>,
pub redirect_scheme: Option<RedirectScheme>,
pub redirect_template: Option<String>,
Expand Down Expand Up @@ -909,6 +915,7 @@ impl HttpFrontendConfig {
method: self.method.clone(),
position: self.position.into(),
tags,
required_auth: Some(self.required_auth),
redirect: self.redirect.map(Into::into),
redirect_scheme: self.redirect_scheme.map(Into::into),
redirect_template: self.redirect_template.clone(),
Expand All @@ -929,6 +936,7 @@ impl HttpFrontendConfig {
method: self.method.clone(),
position: self.position.into(),
tags,
required_auth: Some(self.required_auth),
redirect: self.redirect.map(Into::into),
redirect_scheme: self.redirect_scheme.map(Into::into),
redirect_template: self.redirect_template.clone(),
Expand Down Expand Up @@ -956,6 +964,7 @@ pub struct HttpClusterConfig {
pub load_balancing: LoadBalancingAlgorithms,
pub load_metric: Option<LoadMetric>,
pub answers: BTreeMap<String, String>,
pub authorized_hashes: Vec<u64>,
}

impl HttpClusterConfig {
Expand All @@ -969,6 +978,7 @@ impl HttpClusterConfig {
load_balancing: self.load_balancing as i32,
load_metric: self.load_metric.map(|s| s as i32),
answers: self.answers.clone(),
authorized_hashes: self.authorized_hashes.clone(),
})
.into()];

Expand Down Expand Up @@ -1029,6 +1039,7 @@ impl TcpClusterConfig {
load_balancing: self.load_balancing as i32,
load_metric: self.load_metric.map(|s| s as i32),
answers: Default::default(),
authorized_hashes: Default::default(),
})
.into()];

Expand Down
1 change: 1 addition & 0 deletions command/src/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ impl RequestHttpFrontend {
pub fn to_frontend(self) -> Result<HttpFrontend, RequestError> {
Ok(HttpFrontend {
position: self.position(),
required_auth: self.required_auth.unwrap_or(false),
redirect: self.redirect(),
redirect_scheme: self.redirect_scheme(),
redirect_template: self.redirect_template,
Expand Down
2 changes: 2 additions & 0 deletions command/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ pub struct HttpFrontend {
#[serde(default)]
pub position: RulePosition,
pub tags: Option<BTreeMap<String, String>>,
pub required_auth: bool,
pub redirect: RedirectPolicy,
pub redirect_scheme: RedirectScheme,
#[serde(skip_serializing_if = "Option::is_none")]
Expand All @@ -61,6 +62,7 @@ impl From<HttpFrontend> for RequestHttpFrontend {
method: val.method,
position: val.position.into(),
tags: val.tags.unwrap_or_default(),
required_auth: Some(val.required_auth),
redirect: Some(val.redirect.into()),
redirect_scheme: Some(val.redirect_scheme.into()),
redirect_template: val.redirect_template,
Expand Down
12 changes: 8 additions & 4 deletions lib/src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1284,6 +1284,7 @@ mod tests {
path: PathRule::prefix(uri1),
position: RulePosition::Tree,
cluster_id: Some(cluster_id1),
required_auth: false,
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
redirect_template: None,
Expand All @@ -1301,6 +1302,7 @@ mod tests {
path: PathRule::prefix(uri2),
position: RulePosition::Tree,
cluster_id: Some(cluster_id2),
required_auth: false,
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
redirect_template: None,
Expand All @@ -1318,6 +1320,7 @@ mod tests {
path: PathRule::prefix(uri3),
position: RulePosition::Tree,
cluster_id: Some(cluster_id3),
required_auth: false,
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
redirect_template: None,
Expand All @@ -1335,6 +1338,7 @@ mod tests {
path: PathRule::prefix("/test".to_owned()),
position: RulePosition::Tree,
cluster_id: Some("cluster_1".to_owned()),
required_auth: false,
redirect: RedirectPolicy::Forward,
redirect_scheme: RedirectScheme::UseSame,
redirect_template: None,
Expand Down Expand Up @@ -1369,19 +1373,19 @@ mod tests {
let frontend5 = listener.frontend_from_request("domain", "/", &Method::Get);
assert_eq!(
frontend1.expect("should find frontend"),
RouteResult::simple("cluster_1".to_string())
RouteResult::forward("cluster_1".to_string())
);
assert_eq!(
frontend2.expect("should find frontend"),
RouteResult::simple("cluster_1".to_string())
RouteResult::forward("cluster_1".to_string())
);
assert_eq!(
frontend3.expect("should find frontend"),
RouteResult::simple("cluster_2".to_string())
RouteResult::forward("cluster_2".to_string())
);
assert_eq!(
frontend4.expect("should find frontend"),
RouteResult::simple("cluster_3".to_string())
RouteResult::forward("cluster_3".to_string())
);
assert!(frontend5.is_err());
}
Expand Down
16 changes: 8 additions & 8 deletions lib/src/https.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1504,25 +1504,25 @@ mod tests {
"lolcatho.st".as_bytes(),
&PathRule::Prefix(uri1),
&MethodRule::new(None),
&Route::simple(cluster_id1.clone())
&Route::forward(cluster_id1.clone())
));
assert!(fronts.add_tree_rule(
"lolcatho.st".as_bytes(),
&PathRule::Prefix(uri2),
&MethodRule::new(None),
&Route::simple(cluster_id2)
&Route::forward(cluster_id2)
));
assert!(fronts.add_tree_rule(
"lolcatho.st".as_bytes(),
&PathRule::Prefix(uri3),
&MethodRule::new(None),
&Route::simple(cluster_id3)
&Route::forward(cluster_id3)
));
assert!(fronts.add_tree_rule(
"other.domain".as_bytes(),
&PathRule::Prefix("test".to_string()),
&MethodRule::new(None),
&Route::simple(cluster_id1)
&Route::forward(cluster_id1)
));

let address = SocketAddress::new_v4(127, 0, 0, 1, 1032);
Expand Down Expand Up @@ -1561,25 +1561,25 @@ mod tests {
let frontend1 = listener.frontend_from_request("lolcatho.st", "/", &Method::Get);
assert_eq!(
frontend1.expect("should find a frontend"),
RouteResult::simple("cluster_1".to_string())
RouteResult::forward("cluster_1".to_string())
);
println!("TEST {}", line!());
let frontend2 = listener.frontend_from_request("lolcatho.st", "/test", &Method::Get);
assert_eq!(
frontend2.expect("should find a frontend"),
RouteResult::simple("cluster_1".to_string())
RouteResult::forward("cluster_1".to_string())
);
println!("TEST {}", line!());
let frontend3 = listener.frontend_from_request("lolcatho.st", "/yolo/test", &Method::Get);
assert_eq!(
frontend3.expect("should find a frontend"),
RouteResult::simple("cluster_2".to_string())
RouteResult::forward("cluster_2".to_string())
);
println!("TEST {}", line!());
let frontend4 = listener.frontend_from_request("lolcatho.st", "/yolo/swag", &Method::Get);
assert_eq!(
frontend4.expect("should find a frontend"),
RouteResult::simple("cluster_3".to_string())
RouteResult::forward("cluster_3".to_string())
);
println!("TEST {}", line!());
let frontend5 = listener.frontend_from_request("domain", "/", &Method::Get);
Expand Down
11 changes: 8 additions & 3 deletions lib/src/protocol/kawa_h1/editor.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::{
hash::{DefaultHasher, Hash, Hasher},
net::{IpAddr, SocketAddr},
str::{from_utf8, from_utf8_unchecked},
};
Expand All @@ -24,7 +25,7 @@ pub struct HttpContext {
/// the value of the sticky session cookie in the request
pub sticky_session_found: Option<String>,
/// position of the last authentication header, only valid until prepare is called
pub authentication_found: Option<usize>,
pub authentication_found: Option<u64>,
// ---------- Status Line
/// the value of the method in the request line
pub method: Option<Method>,
Expand Down Expand Up @@ -137,7 +138,7 @@ impl HttpContext {
let mut has_x_port = false;
let mut has_x_proto = false;
let mut has_connection = false;
for (i, block) in request.blocks.iter_mut().enumerate() {
for block in &mut request.blocks {
match block {
kawa::Block::Header(header) if !header.is_elided() => {
let key = header.key.data(buf);
Expand Down Expand Up @@ -185,7 +186,11 @@ impl HttpContext {
.and_then(|data| from_utf8(data).ok())
.map(ToOwned::to_owned);
} else if compare_no_case(key, b"Proxy-Authenticate") {
self.authentication_found = Some(i);
self.authentication_found = header.val.data_opt(buf).map(|auth| {
let mut h = DefaultHasher::new();
auth.hash(&mut h);
h.finish()
});
}
}
_ => {}
Expand Down
Loading

0 comments on commit 6110de3

Please sign in to comment.