mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-05-20 07:26:58 -04:00
Support connect gateway (#306)
This commit is contained in:
@@ -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(¶ms).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(),
|
||||
|
Reference in New Issue
Block a user