mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-04-29 14:16:26 -04:00
Support connect gateway
This commit is contained in:
parent
aac401e7ee
commit
e6994d5733
@ -141,6 +141,16 @@ impl CachedCredential {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<PasswordCredential> for CachedCredential {
|
||||||
|
fn from(value: PasswordCredential) -> Self {
|
||||||
|
Self::new(
|
||||||
|
value.username().to_owned(),
|
||||||
|
Some(value.password().to_owned()),
|
||||||
|
AuthCookieCredential::new("", "", ""),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Type, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Type, Clone)]
|
||||||
#[serde(tag = "type", rename_all = "camelCase")]
|
#[serde(tag = "type", rename_all = "camelCase")]
|
||||||
pub enum Credential {
|
pub enum Credential {
|
||||||
|
@ -22,11 +22,15 @@ pub async fn gateway_login(
|
|||||||
params.extend(extra_params);
|
params.extend(extra_params);
|
||||||
params.insert("server", gateway);
|
params.insert("server", gateway);
|
||||||
|
|
||||||
|
info!("Gateway login params {:?}", params);
|
||||||
|
|
||||||
info!("Gateway login, user_agent: {}", gp_params.user_agent());
|
info!("Gateway login, user_agent: {}", gp_params.user_agent());
|
||||||
|
|
||||||
let res = client.post(&login_url).form(¶ms).send().await?;
|
let res = client.post(&login_url).form(¶ms).send().await?;
|
||||||
let res_xml = res.error_for_status()?.text().await?;
|
let res_xml = res.error_for_status()?.text().await?;
|
||||||
|
|
||||||
|
info!("Gateway login request done");
|
||||||
|
|
||||||
let doc = Document::parse(&res_xml)?;
|
let doc = Document::parse(&res_xml)?;
|
||||||
|
|
||||||
build_gateway_token(&doc, gp_params.computer())
|
build_gateway_token(&doc, gp_params.computer())
|
||||||
|
@ -31,6 +31,15 @@ impl Display for Gateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Gateway {
|
impl Gateway {
|
||||||
|
pub fn new(name: String, address: String) -> Self {
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
address,
|
||||||
|
priority: 0,
|
||||||
|
priority_rules: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> &str {
|
pub fn name(&self) -> &str {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
use anyhow::ensure;
|
use anyhow::bail;
|
||||||
use log::info;
|
use log::info;
|
||||||
use reqwest::Client;
|
use reqwest::{Client, StatusCode};
|
||||||
use roxmltree::Document;
|
use roxmltree::Document;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use specta::Type;
|
use specta::Type;
|
||||||
use thiserror::Error;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
credential::{AuthCookieCredential, Credential},
|
credential::{AuthCookieCredential, Credential},
|
||||||
gateway::{parse_gateways, Gateway},
|
gateway::{parse_gateways, Gateway},
|
||||||
gp_params::GpParams,
|
gp_params::GpParams,
|
||||||
|
portal::PortalError,
|
||||||
utils::{normalize_server, xml},
|
utils::{normalize_server, xml},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,12 +98,6 @@ impl PortalConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
|
||||||
pub enum PortalConfigError {
|
|
||||||
#[error("Empty response, retrying can help")]
|
|
||||||
EmptyResponse,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn retrieve_config(
|
pub async fn retrieve_config(
|
||||||
portal: &str,
|
portal: &str,
|
||||||
cred: &Credential,
|
cred: &Credential,
|
||||||
@ -127,14 +121,35 @@ pub async fn retrieve_config(
|
|||||||
|
|
||||||
info!("Portal config, user_agent: {}", gp_params.user_agent());
|
info!("Portal config, user_agent: {}", gp_params.user_agent());
|
||||||
|
|
||||||
|
info!("Portal config params: {:?}", params);
|
||||||
|
|
||||||
let res = client.post(&url).form(¶ms).send().await?;
|
let res = client.post(&url).form(¶ms).send().await?;
|
||||||
let res_xml = res.error_for_status()?.text().await?;
|
let status = res.status();
|
||||||
|
|
||||||
ensure!(!res_xml.is_empty(), PortalConfigError::EmptyResponse);
|
if status == StatusCode::NOT_FOUND {
|
||||||
|
bail!(PortalError::ConfigError(
|
||||||
|
"Config endpoint not found".to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
let doc = Document::parse(&res_xml)?;
|
let res_xml = res
|
||||||
let mut gateways =
|
.error_for_status()?
|
||||||
parse_gateways(&doc).ok_or_else(|| anyhow::anyhow!("Failed to parse gateways"))?;
|
.text()
|
||||||
|
.await
|
||||||
|
.map_err(|e| PortalError::ConfigError(e.to_string()))?;
|
||||||
|
|
||||||
|
if res_xml.is_empty() {
|
||||||
|
bail!(PortalError::ConfigError(
|
||||||
|
"Empty portal config response".to_string()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
let doc = Document::parse(&res_xml).map_err(|e| PortalError::ConfigError(e.to_string()))?;
|
||||||
|
|
||||||
|
let mut gateways = parse_gateways(&doc).unwrap_or_else(|| {
|
||||||
|
info!("No gateways found in portal config");
|
||||||
|
vec![]
|
||||||
|
});
|
||||||
|
|
||||||
let user_auth_cookie = xml::get_child_text(&doc, "portal-userauthcookie").unwrap_or_default();
|
let user_auth_cookie = xml::get_child_text(&doc, "portal-userauthcookie").unwrap_or_default();
|
||||||
let prelogon_user_auth_cookie =
|
let prelogon_user_auth_cookie =
|
||||||
@ -142,12 +157,7 @@ pub async fn retrieve_config(
|
|||||||
let config_digest = xml::get_child_text(&doc, "config-digest");
|
let config_digest = xml::get_child_text(&doc, "config-digest");
|
||||||
|
|
||||||
if gateways.is_empty() {
|
if gateways.is_empty() {
|
||||||
gateways.push(Gateway {
|
gateways.push(Gateway::new(server.to_string(), server.to_string()));
|
||||||
name: server.to_string(),
|
|
||||||
address: server.to_string(),
|
|
||||||
priority: 0,
|
|
||||||
priority_rules: vec![],
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PortalConfig::new(
|
Ok(PortalConfig::new(
|
||||||
|
@ -3,3 +3,13 @@ mod prelogin;
|
|||||||
|
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use prelogin::*;
|
pub use prelogin::*;
|
||||||
|
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum PortalError {
|
||||||
|
#[error("Portal prelogin error: {0}")]
|
||||||
|
PreloginError(String),
|
||||||
|
#[error("Portal config error: {0}")]
|
||||||
|
ConfigError(String),
|
||||||
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
use anyhow::bail;
|
use anyhow::bail;
|
||||||
use log::{info, trace};
|
use log::info;
|
||||||
use reqwest::Client;
|
use reqwest::{Client, StatusCode};
|
||||||
use roxmltree::Document;
|
use roxmltree::Document;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use specta::Type;
|
use specta::Type;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
gp_params::GpParams,
|
gp_params::GpParams,
|
||||||
|
portal::PortalError,
|
||||||
utils::{base64, normalize_server, xml},
|
utils::{base64, normalize_server, xml},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -118,9 +119,26 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel
|
|||||||
.build()?;
|
.build()?;
|
||||||
|
|
||||||
let res = client.post(&prelogin_url).form(¶ms).send().await?;
|
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()
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
let res_xml = res
|
||||||
|
.error_for_status()?
|
||||||
|
.text()
|
||||||
|
.await
|
||||||
|
.map_err(|e| PortalError::PreloginError(e.to_string()))?;
|
||||||
|
|
||||||
|
let prelogin = parse_res_xml(res_xml).map_err(|e| PortalError::PreloginError(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(prelogin)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_res_xml(res_xml: String) -> anyhow::Result<Prelogin> {
|
||||||
let doc = Document::parse(&res_xml)?;
|
let doc = Document::parse(&res_xml)?;
|
||||||
|
|
||||||
let status = xml::get_child_text(&doc, "status")
|
let status = xml::get_child_text(&doc, "status")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user