feat(protocol): define native session credentials
Verify Protocol / module (push) Successful in 1m13s
Verify Protocol / verify (push) Successful in 35s

This commit is contained in:
sechmachine
2026-08-11 18:38:19 +07:00
parent 79d9e49497
commit afcd5d99db
32 changed files with 1565 additions and 149 deletions
+56 -6
View File
@@ -9,10 +9,10 @@ fn values(input: &str) -> std::collections::BTreeMap<String, String> {
.collect()
}
fn evaluate(kind: &str, input: &str) -> &'static str {
fn evaluate(version: &str, kind: &str, input: &str) -> &'static str {
let values = values(input);
match kind {
"version" if matches!(input, "1" | "0" | "-1") => "valid",
"version" if matches!(input, "2" | "1" | "0") => "valid",
"version" => "invalid:unsupported_version",
"page" => match values.get("limit").and_then(|value| value.parse::<i64>().ok()) {
Some(limit) if (1..=100).contains(&limit) => "valid",
@@ -24,12 +24,62 @@ fn evaluate(kind: &str, input: &str) -> &'static str {
"manifest"
if values.get("version").map(String::as_str) == Some("1")
&& values.contains_key("gateway_id")
&& values.contains_key("public_identity")
&& values.get("grant").map_or(false, |value| value.len() >= 43)
&& values.get("purpose").map(String::as_str) == Some("launch") => "valid",
"manifest" => "invalid:invalid_manifest",
"clipboard" if values.get("encoding").map(String::as_str) == Some("utf-8")
&& !values.contains_key("file") => "valid",
"clipboard" => "invalid:unsupported_clipboard",
"session_request" if version != "2" => "invalid:unsupported_version",
"session_request" if values.contains_key("policy_snapshot") => "invalid:forbidden_field",
"session_request" => match SessionRequest::new(
values.get("client_device_id").cloned().unwrap_or_default(),
values.get("device_key_id").cloned().unwrap_or_default(),
values.get("pool_id").cloned().unwrap_or_default(),
values.get("idempotency_key").cloned().unwrap_or_default(),
None,
) {
Ok(_) => "valid",
Err(_) => "invalid:required",
},
"browser_authenticated_session" if values.contains_key("client_device_id") || values.contains_key("device_key_id") => "invalid:forbidden_field",
"browser_authenticated_session" => match BrowserAuthenticatedSession::new(
values.get("username").cloned().unwrap_or_default(),
values.get("provider").cloned().unwrap_or_default(),
vec![values.get("roles").cloned().unwrap_or_default()],
values.get("role").cloned().unwrap_or_default(),
) {
Ok(_) => "valid",
Err(_) => "invalid:invalid_session",
},
"native_authenticated_session" if !values.contains_key("client_device_id") || !values.contains_key("device_key_id") => "invalid:required",
"native_authenticated_session" => {
let identity = match NativeSessionIdentity::new(values["client_device_id"].clone(), values["device_key_id"].clone()) {
Ok(identity) => identity,
Err(_) => return "invalid:required",
};
match NativeAuthenticatedSession::new(
values.get("username").cloned().unwrap_or_default(),
values.get("provider").cloned().unwrap_or_default(),
vec![values.get("roles").cloned().unwrap_or_default()],
values.get("role").cloned().unwrap_or_default(),
identity,
) {
Ok(_) => "valid",
Err(_) => "invalid:invalid_session",
}
}
"native_tunnel_credential" => match NativeTunnelCredential::new(
values.get("client_device_id").cloned().unwrap_or_default(),
values.get("device_key_id").cloned().unwrap_or_default(),
values.get("certificate_chain_pem").cloned().unwrap_or_default(),
values.get("trust_bundle_pem").cloned().unwrap_or_default(),
values.get("expires_at").cloned().unwrap_or_default(),
) {
Ok(_) => "valid",
Err(_) => "invalid:invalid_credential",
},
"event" if values.get("version").map(String::as_str) != Some("1") => {
"invalid:unsupported_version"
}
@@ -46,9 +96,9 @@ fn evaluate(kind: &str, input: &str) -> &'static str {
"event" if values.get("sequence").and_then(|value| value.parse::<i64>().ok()).map_or(true, |sequence| sequence < 1)
|| !values.contains_key("correlation_id") => "invalid:required",
"event" => "valid",
"tunnel" if matches!(values.get("offered").map(String::as_str), Some("1") | Some("0") | Some("-1"))
&& matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => "valid",
"tunnel" if !matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => {
"tunnel" if matches!(values.get("offered").map(String::as_str), Some("2") | Some("1") | Some("0"))
&& matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("control.v2") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => "valid",
"tunnel" if !matches!(values.get("feature").map(String::as_str), Some("control.v1") | Some("control.v2") | Some("display.request.v1") | Some("input.absolute.v1") | Some("input.scroll.v1")) => {
"invalid:unsupported_feature"
}
"tunnel" => "invalid:unsupported_version",
@@ -283,7 +333,7 @@ fn main() {
for line in lines {
let fields: Vec<&str> = line.split('\t').collect();
assert_eq!(fields.len(), 5);
let actual = evaluate(fields[2], fields[3]);
let actual = evaluate(fields[1], fields[2], fields[3]);
assert_eq!(actual, fields[4], "{}", fields[0]);
results.push(format!("{}\t{}", fields[0], actual));
}