Skip to content

Commit

Permalink
feat: add internal host detection support (#384)
Browse files Browse the repository at this point in the history
  • Loading branch information
ruben-rodriguez authored Jul 2, 2024
1 parent 6357a40 commit 26dbd8d
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 3 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
1 change: 1 addition & 0 deletions crates/gpapi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
12 changes: 10 additions & 2 deletions crates/gpapi/src/gateway/parse_gateways.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
34 changes: 33 additions & 1 deletion crates/gpapi/src/portal/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use anyhow::bail;
use dns_lookup::lookup_addr;
use log::{info, warn};
use reqwest::{Client, StatusCode};
use roxmltree::Document;
Expand Down Expand Up @@ -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![]
});
Expand Down
32 changes: 32 additions & 0 deletions crates/gpapi/tests/files/portal_config.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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>
Expand Down

0 comments on commit 26dbd8d

Please sign in to comment.