mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-04-02 18:31:50 -04:00
feat: add internal host detection support (#384)
This commit is contained in:
parent
6357a4087d
commit
26dbd8d312
13
Cargo.lock
generated
13
Cargo.lock
generated
@ -889,6 +889,18 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
|
||||
|
||||
[[package]]
|
||||
name = "dns-lookup"
|
||||
version = "2.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"socket2",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.8"
|
||||
@ -1424,6 +1436,7 @@ dependencies = [
|
||||
"base64 0.21.5",
|
||||
"chacha20poly1305",
|
||||
"clap",
|
||||
"dns-lookup",
|
||||
"log",
|
||||
"md5",
|
||||
"open",
|
||||
|
@ -17,6 +17,7 @@ base64 = "0.21"
|
||||
clap = { version = "4.4.2", features = ["derive"] }
|
||||
ctrlc = "3.4"
|
||||
directories = "5.0"
|
||||
dns-lookup = "2.0.4"
|
||||
env_logger = "0.10"
|
||||
is_executable = "1.0"
|
||||
log = "0.4"
|
||||
|
@ -7,6 +7,7 @@ license = "MIT"
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
base64.workspace = true
|
||||
dns-lookup.workspace = true
|
||||
log.workspace = true
|
||||
reqwest.workspace = true
|
||||
openssl.workspace = true
|
||||
|
@ -2,9 +2,17 @@ use roxmltree::Document;
|
||||
|
||||
use super::{Gateway, PriorityRule};
|
||||
|
||||
pub(crate) fn parse_gateways(doc: &Document) -> Option<Vec<Gateway>> {
|
||||
pub(crate) fn parse_gateways(doc: &Document, external: bool) -> Option<Vec<Gateway>> {
|
||||
let node_gateways = doc.descendants().find(|n| n.has_tag_name("gateways"))?;
|
||||
let list_gateway = node_gateways.descendants().find(|n| n.has_tag_name("list"))?;
|
||||
|
||||
// if external flag is set, look for external gateways, otherwise look for internal gateways
|
||||
let kind_gateways = if external {
|
||||
node_gateways.descendants().find(|n| n.has_tag_name("external"))?
|
||||
} else {
|
||||
node_gateways.descendants().find(|n| n.has_tag_name("internal"))?
|
||||
};
|
||||
|
||||
let list_gateway = kind_gateways.descendants().find(|n| n.has_tag_name("list"))?;
|
||||
|
||||
let gateways = list_gateway
|
||||
.children()
|
||||
|
@ -1,4 +1,5 @@
|
||||
use anyhow::bail;
|
||||
use dns_lookup::lookup_addr;
|
||||
use log::{info, warn};
|
||||
use reqwest::{Client, StatusCode};
|
||||
use roxmltree::Document;
|
||||
@ -125,7 +126,38 @@ pub async fn retrieve_config(portal: &str, cred: &Credential, gp_params: &GpPara
|
||||
|
||||
let doc = Document::parse(&res_xml).map_err(|e| PortalError::ConfigError(e.to_string()))?;
|
||||
|
||||
let mut gateways = parse_gateways(&doc).unwrap_or_else(|| {
|
||||
let mut external_gateway = true;
|
||||
|
||||
// Perform DNS lookup, set flag to internal or external, and pass it to parse_gateways
|
||||
if let Some(_) = xml::get_child_text(&doc, "internal-host-detection") {
|
||||
let ip_info = [
|
||||
(xml::get_child_text(&doc, "ip-address"), xml::get_child_text(&doc, "host")),
|
||||
(xml::get_child_text(&doc, "ipv6-address"), xml::get_child_text(&doc, "ipv6-host")),
|
||||
];
|
||||
|
||||
info!("internal-host-detection returned, performing DNS lookup");
|
||||
|
||||
for (ip_address, host) in ip_info.iter() {
|
||||
if let (Some(ip_address), Some(host)) = (ip_address.as_deref(), host.as_deref()) {
|
||||
if !ip_address.is_empty() && !host.is_empty() {
|
||||
match ip_address.parse::<std::net::IpAddr>() {
|
||||
Ok(ip) => match lookup_addr(&ip) {
|
||||
Ok(host_lookup) if host_lookup == *host => {
|
||||
external_gateway = false;
|
||||
break;
|
||||
}
|
||||
Ok(_) => (),
|
||||
Err(err) => warn!("DNS lookup failed for {}: {}", ip_address, err),
|
||||
},
|
||||
Err(err) => warn!("Invalid IP address {}: {}", ip_address, err),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let mut gateways = parse_gateways(&doc, external_gateway).unwrap_or_else(|| {
|
||||
info!("No gateways found in portal config");
|
||||
vec![]
|
||||
});
|
||||
|
@ -46,7 +46,26 @@
|
||||
<use-sso>yes</use-sso>
|
||||
<ip-address></ip-address>
|
||||
<host></host>
|
||||
<internal-host-detection>
|
||||
<ip-address></ip-address>
|
||||
<host></host>
|
||||
<ipv6-address/>
|
||||
<ipv6-host/>
|
||||
</internal-host-detection>
|
||||
<gateways>
|
||||
<internal>
|
||||
<list>
|
||||
<entry name="xxx.xxx.xxx.xxx">
|
||||
<priority-rule>
|
||||
<entry name="Any">
|
||||
<priority>1</priority>
|
||||
</entry>
|
||||
</priority-rule>
|
||||
<priority>1</priority>
|
||||
<description>vpn_gateway</description>
|
||||
</entry>
|
||||
</list>
|
||||
</internal>
|
||||
<cutoff-time>5</cutoff-time>
|
||||
<external>
|
||||
<list>
|
||||
@ -63,6 +82,19 @@
|
||||
</external>
|
||||
</gateways>
|
||||
<gateways-v6>
|
||||
<internal>
|
||||
<list>
|
||||
<entry name="vpn_gateway">
|
||||
<ipv4>xxx.xxx.xxx.xxx</ipv4>
|
||||
<priority-rule>
|
||||
<entry name="Any">
|
||||
<priority>1</priority>
|
||||
</entry>
|
||||
</priority-rule>
|
||||
<priority>1</priority>
|
||||
</entry>
|
||||
</list>
|
||||
</internal>
|
||||
<cutoff-time>5</cutoff-time>
|
||||
<external>
|
||||
<list>
|
||||
|
Loading…
Reference in New Issue
Block a user