Support connect gateway (#306)

This commit is contained in:
Kevin Yue
2024-01-28 11:41:48 +08:00
committed by GitHub
parent 6fe6a1387a
commit b2bb35994f
14 changed files with 220 additions and 92 deletions

View File

@@ -1,12 +1,13 @@
use anyhow::bail;
use log::{info, trace};
use reqwest::Client;
use log::info;
use reqwest::{Client, StatusCode};
use roxmltree::Document;
use serde::Serialize;
use specta::Type;
use crate::{
gp_params::GpParams,
portal::PortalError,
utils::{base64, normalize_server, xml},
};
@@ -25,6 +26,7 @@ const REQUIRED_PARAMS: [&str; 8] = [
#[serde(rename_all = "camelCase")]
pub struct SamlPrelogin {
region: String,
is_gateway: bool,
saml_request: String,
support_default_browser: bool,
}
@@ -47,6 +49,7 @@ impl SamlPrelogin {
#[serde(rename_all = "camelCase")]
pub struct StandardPrelogin {
region: String,
is_gateway: bool,
auth_message: String,
label_username: String,
label_password: String,
@@ -84,21 +87,27 @@ impl Prelogin {
Prelogin::Standard(standard) => standard.region(),
}
}
pub fn is_gateway(&self) -> bool {
match self {
Prelogin::Saml(saml) => saml.is_gateway,
Prelogin::Standard(standard) => standard.is_gateway,
}
}
}
pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prelogin> {
let user_agent = gp_params.user_agent();
info!("Portal prelogin, user_agent: {}", user_agent);
info!("Prelogin with user_agent: {}", user_agent);
let portal = normalize_server(portal)?;
let prelogin_url = format!(
"{portal}/{}/prelogin.esp",
if gp_params.is_gateway() {
"ssl-vpn"
} else {
"global-protect"
}
);
let is_gateway = gp_params.is_gateway();
let path = if is_gateway {
"ssl-vpn"
} else {
"global-protect"
};
let prelogin_url = format!("{portal}/{}/prelogin.esp", path);
let mut params = gp_params.to_params();
params.insert("tmp", "tmp");
@@ -118,9 +127,30 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel
.build()?;
let res = client.post(&prelogin_url).form(&params).send().await?;
let res_xml = res.error_for_status()?.text().await?;
let status = res.status();
trace!("Prelogin response: {}", res_xml);
if status == StatusCode::NOT_FOUND {
bail!(PortalError::PreloginError(
"Prelogin endpoint not found".to_string()
))
}
if status.is_client_error() || status.is_server_error() {
bail!("Prelogin error: {}", status)
}
let res_xml = res
.text()
.await
.map_err(|e| PortalError::PreloginError(e.to_string()))?;
let prelogin =
parse_res_xml(res_xml, is_gateway).map_err(|e| PortalError::PreloginError(e.to_string()))?;
Ok(prelogin)
}
fn parse_res_xml(res_xml: String, is_gateway: bool) -> anyhow::Result<Prelogin> {
let doc = Document::parse(&res_xml)?;
let status = xml::get_child_text(&doc, "status")
@@ -146,6 +176,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel
let saml_prelogin = SamlPrelogin {
region,
is_gateway,
saml_request,
support_default_browser,
};
@@ -161,6 +192,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel
.unwrap_or(String::from("Please enter the login credentials"));
let standard_prelogin = StandardPrelogin {
region,
is_gateway,
auth_message,
label_username: label_username.unwrap(),
label_password: label_password.unwrap(),