mirror of
				https://github.com/yuezk/GlobalProtect-openconnect.git
				synced 2025-05-20 07:26:58 -04:00 
			
		
		
		
	Update format
This commit is contained in:
		| @@ -27,11 +27,7 @@ impl SamlAuthResult { | ||||
| } | ||||
|  | ||||
| impl SamlAuthData { | ||||
|   pub fn new( | ||||
|     username: String, | ||||
|     prelogin_cookie: Option<String>, | ||||
|     portal_userauthcookie: Option<String>, | ||||
|   ) -> Self { | ||||
|   pub fn new(username: String, prelogin_cookie: Option<String>, portal_userauthcookie: Option<String>) -> Self { | ||||
|     Self { | ||||
|       username, | ||||
|       prelogin_cookie, | ||||
| @@ -78,13 +74,9 @@ impl SamlAuthData { | ||||
|     prelogin_cookie: &Option<String>, | ||||
|     portal_userauthcookie: &Option<String>, | ||||
|   ) -> bool { | ||||
|     let username_valid = username | ||||
|       .as_ref() | ||||
|       .is_some_and(|username| !username.is_empty()); | ||||
|     let username_valid = username.as_ref().is_some_and(|username| !username.is_empty()); | ||||
|     let prelogin_cookie_valid = prelogin_cookie.as_ref().is_some_and(|val| val.len() > 5); | ||||
|     let portal_userauthcookie_valid = portal_userauthcookie | ||||
|       .as_ref() | ||||
|       .is_some_and(|val| val.len() > 5); | ||||
|     let portal_userauthcookie_valid = portal_userauthcookie.as_ref().is_some_and(|val| val.len() > 5); | ||||
|  | ||||
|     username_valid && (prelogin_cookie_valid || portal_userauthcookie_valid) | ||||
|   } | ||||
|   | ||||
| @@ -112,11 +112,7 @@ pub struct CachedCredential { | ||||
| } | ||||
|  | ||||
| impl CachedCredential { | ||||
|   pub fn new( | ||||
|     username: String, | ||||
|     password: Option<String>, | ||||
|     auth_cookie: AuthCookieCredential, | ||||
|   ) -> Self { | ||||
|   pub fn new(username: String, password: Option<String>, auth_cookie: AuthCookieCredential) -> Self { | ||||
|     Self { | ||||
|       username, | ||||
|       password, | ||||
| @@ -193,8 +189,7 @@ impl Credential { | ||||
|     let mut params = HashMap::new(); | ||||
|     params.insert("user", self.username()); | ||||
|  | ||||
|     let (passwd, prelogin_cookie, portal_userauthcookie, portal_prelogonuserauthcookie) = match self | ||||
|     { | ||||
|     let (passwd, prelogin_cookie, portal_userauthcookie, portal_prelogonuserauthcookie) = match self { | ||||
|       Credential::Password(cred) => (Some(cred.password()), None, None, None), | ||||
|       Credential::PreloginCookie(cred) => (None, Some(cred.prelogin_cookie()), None, None), | ||||
|       Credential::AuthCookie(cred) => ( | ||||
| @@ -213,10 +208,7 @@ impl Credential { | ||||
|  | ||||
|     params.insert("passwd", passwd.unwrap_or_default()); | ||||
|     params.insert("prelogin-cookie", prelogin_cookie.unwrap_or_default()); | ||||
|     params.insert( | ||||
|       "portal-userauthcookie", | ||||
|       portal_userauthcookie.unwrap_or_default(), | ||||
|     ); | ||||
|     params.insert("portal-userauthcookie", portal_userauthcookie.unwrap_or_default()); | ||||
|     params.insert( | ||||
|       "portal-prelogonuserauthcookie", | ||||
|       portal_prelogonuserauthcookie.unwrap_or_default(), | ||||
|   | ||||
| @@ -10,11 +10,7 @@ use crate::{ | ||||
|   utils::{normalize_server, remove_url_scheme}, | ||||
| }; | ||||
|  | ||||
| pub async fn gateway_login( | ||||
|   gateway: &str, | ||||
|   cred: &Credential, | ||||
|   gp_params: &GpParams, | ||||
| ) -> anyhow::Result<String> { | ||||
| pub async fn gateway_login(gateway: &str, cred: &Credential, gp_params: &GpParams) -> anyhow::Result<String> { | ||||
|   let url = normalize_server(gateway)?; | ||||
|   let gateway = remove_url_scheme(&url); | ||||
|  | ||||
| @@ -70,11 +66,7 @@ fn build_gateway_token(doc: &Document, computer: &str) -> anyhow::Result<String> | ||||
|   Ok(token) | ||||
| } | ||||
|  | ||||
| fn read_args<'a>( | ||||
|   args: &'a [String], | ||||
|   index: usize, | ||||
|   key: &'a str, | ||||
| ) -> anyhow::Result<(&'a str, &'a str)> { | ||||
| fn read_args<'a>(args: &'a [String], index: usize, key: &'a str) -> anyhow::Result<(&'a str, &'a str)> { | ||||
|   args | ||||
|     .get(index) | ||||
|     .ok_or_else(|| anyhow::anyhow!("Failed to read {key} from args")) | ||||
|   | ||||
| @@ -4,9 +4,7 @@ use super::{Gateway, PriorityRule}; | ||||
|  | ||||
| pub(crate) fn parse_gateways(doc: &Document) -> 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"))?; | ||||
|   let list_gateway = node_gateways.descendants().find(|n| n.has_tag_name("list"))?; | ||||
|  | ||||
|   let gateways = list_gateway | ||||
|     .children() | ||||
|   | ||||
| @@ -79,21 +79,11 @@ impl PortalConfig { | ||||
|     } | ||||
|  | ||||
|     // If no gateway is found, return the gateway with the lowest priority | ||||
|     preferred_gateway.unwrap_or_else(|| { | ||||
|       self | ||||
|         .gateways | ||||
|         .iter() | ||||
|         .min_by_key(|gateway| gateway.priority) | ||||
|         .unwrap() | ||||
|     }) | ||||
|     preferred_gateway.unwrap_or_else(|| self.gateways.iter().min_by_key(|gateway| gateway.priority).unwrap()) | ||||
|   } | ||||
| } | ||||
|  | ||||
| pub async fn retrieve_config( | ||||
|   portal: &str, | ||||
|   cred: &Credential, | ||||
|   gp_params: &GpParams, | ||||
| ) -> anyhow::Result<PortalConfig> { | ||||
| pub async fn retrieve_config(portal: &str, cred: &Credential, gp_params: &GpParams) -> anyhow::Result<PortalConfig> { | ||||
|   let portal = normalize_server(portal)?; | ||||
|   let server = remove_url_scheme(&portal); | ||||
|  | ||||
| @@ -116,24 +106,17 @@ pub async fn retrieve_config( | ||||
|   let status = res.status(); | ||||
|  | ||||
|   if status == StatusCode::NOT_FOUND { | ||||
|     bail!(PortalError::ConfigError( | ||||
|       "Config endpoint not found".to_string() | ||||
|     )) | ||||
|     bail!(PortalError::ConfigError("Config endpoint not found".to_string())) | ||||
|   } | ||||
|  | ||||
|   if status.is_client_error() || status.is_server_error() { | ||||
|     bail!("Portal config error: {}", status) | ||||
|   } | ||||
|  | ||||
|   let res_xml = res | ||||
|     .text() | ||||
|     .await | ||||
|     .map_err(|e| PortalError::ConfigError(e.to_string()))?; | ||||
|   let res_xml = res.text().await.map_err(|e| PortalError::ConfigError(e.to_string()))?; | ||||
|  | ||||
|   if res_xml.is_empty() { | ||||
|     bail!(PortalError::ConfigError( | ||||
|       "Empty portal config response".to_string() | ||||
|     )) | ||||
|     bail!(PortalError::ConfigError("Empty portal config response".to_string())) | ||||
|   } | ||||
|  | ||||
|   let doc = Document::parse(&res_xml).map_err(|e| PortalError::ConfigError(e.to_string()))?; | ||||
| @@ -144,8 +127,7 @@ pub async fn retrieve_config( | ||||
|   }); | ||||
|  | ||||
|   let user_auth_cookie = xml::get_child_text(&doc, "portal-userauthcookie").unwrap_or_default(); | ||||
|   let prelogon_user_auth_cookie = | ||||
|     xml::get_child_text(&doc, "portal-prelogonuserauthcookie").unwrap_or_default(); | ||||
|   let prelogon_user_auth_cookie = xml::get_child_text(&doc, "portal-prelogonuserauthcookie").unwrap_or_default(); | ||||
|   let config_digest = xml::get_child_text(&doc, "config-digest"); | ||||
|  | ||||
|   if gateways.is_empty() { | ||||
| @@ -154,11 +136,7 @@ pub async fn retrieve_config( | ||||
|  | ||||
|   Ok(PortalConfig { | ||||
|     portal: server.to_string(), | ||||
|     auth_cookie: AuthCookieCredential::new( | ||||
|       cred.username(), | ||||
|       &user_auth_cookie, | ||||
|       &prelogon_user_auth_cookie, | ||||
|     ), | ||||
|     auth_cookie: AuthCookieCredential::new(cred.username(), &user_auth_cookie, &prelogon_user_auth_cookie), | ||||
|     config_cred: cred.clone(), | ||||
|     gateways, | ||||
|     config_digest, | ||||
|   | ||||
| @@ -102,11 +102,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel | ||||
|  | ||||
|   let portal = normalize_server(portal)?; | ||||
|   let is_gateway = gp_params.is_gateway(); | ||||
|   let path = if is_gateway { | ||||
|     "ssl-vpn" | ||||
|   } else { | ||||
|     "global-protect" | ||||
|   }; | ||||
|   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(); | ||||
|  | ||||
| @@ -115,11 +111,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel | ||||
|     params.insert("default-browser", "1"); | ||||
|   } | ||||
|  | ||||
|   params.retain(|k, _| { | ||||
|     REQUIRED_PARAMS | ||||
|       .iter() | ||||
|       .any(|required_param| required_param == k) | ||||
|   }); | ||||
|   params.retain(|k, _| REQUIRED_PARAMS.iter().any(|required_param| required_param == k)); | ||||
|  | ||||
|   let client = Client::builder() | ||||
|     .danger_accept_invalid_certs(gp_params.ignore_tls_errors()) | ||||
| @@ -130,9 +122,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel | ||||
|   let status = res.status(); | ||||
|  | ||||
|   if status == StatusCode::NOT_FOUND { | ||||
|     bail!(PortalError::PreloginError( | ||||
|       "Prelogin endpoint not found".to_string() | ||||
|     )) | ||||
|     bail!(PortalError::PreloginError("Prelogin endpoint not found".to_string())) | ||||
|   } | ||||
|  | ||||
|   if status.is_client_error() || status.is_server_error() { | ||||
| @@ -144,8 +134,7 @@ pub async fn prelogin(portal: &str, gp_params: &GpParams) -> anyhow::Result<Prel | ||||
|     .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()))?; | ||||
|   let prelogin = parse_res_xml(res_xml, is_gateway).map_err(|e| PortalError::PreloginError(e.to_string()))?; | ||||
|  | ||||
|   Ok(prelogin) | ||||
| } | ||||
| @@ -170,9 +159,7 @@ fn parse_res_xml(res_xml: String, is_gateway: bool) -> anyhow::Result<Prelogin> | ||||
|   // Check if the prelogin response is SAML | ||||
|   if saml_method.is_some() && saml_request.is_some() { | ||||
|     let saml_request = base64::decode_to_string(&saml_request.unwrap())?; | ||||
|     let support_default_browser = saml_default_browser | ||||
|       .map(|s| s.to_lowercase() == "yes") | ||||
|       .unwrap_or(false); | ||||
|     let support_default_browser = saml_default_browser.map(|s| s.to_lowercase() == "yes").unwrap_or(false); | ||||
|  | ||||
|     let saml_prelogin = SamlPrelogin { | ||||
|       region, | ||||
| @@ -188,8 +175,8 @@ fn parse_res_xml(res_xml: String, is_gateway: bool) -> anyhow::Result<Prelogin> | ||||
|   let label_password = xml::get_child_text(&doc, "password-label"); | ||||
|   // Check if the prelogin response is standard login | ||||
|   if label_username.is_some() && label_password.is_some() { | ||||
|     let auth_message = xml::get_child_text(&doc, "authentication-message") | ||||
|       .unwrap_or(String::from("Please enter the login credentials")); | ||||
|     let auth_message = | ||||
|       xml::get_child_text(&doc, "authentication-message").unwrap_or(String::from("Please enter the login credentials")); | ||||
|     let standard_prelogin = StandardPrelogin { | ||||
|       region, | ||||
|       is_gateway, | ||||
|   | ||||
| @@ -129,7 +129,7 @@ impl<'a> SamlAuthLauncher<'a> { | ||||
|       .wait_with_output() | ||||
|       .await?; | ||||
|  | ||||
|     let auth_result: SamlAuthResult = serde_json::from_slice(&output.stdout) | ||||
|     let auth_result = serde_json::from_slice::<SamlAuthResult>(&output.stdout) | ||||
|       .map_err(|_| anyhow::anyhow!("Failed to parse auth data"))?; | ||||
|  | ||||
|     match auth_result { | ||||
|   | ||||
| @@ -21,8 +21,7 @@ impl CommandExt for Command { | ||||
|   } | ||||
|  | ||||
|   fn into_non_root(mut self) -> anyhow::Result<Command> { | ||||
|     let user = | ||||
|       get_non_root_user().map_err(|_| anyhow::anyhow!("{:?} cannot be run as root", self))?; | ||||
|     let user = get_non_root_user().map_err(|_| anyhow::anyhow!("{:?} cannot be run as root", self))?; | ||||
|  | ||||
|     self | ||||
|       .env("HOME", user.home_dir()) | ||||
| @@ -42,8 +41,7 @@ fn get_non_root_user() -> anyhow::Result<User> { | ||||
|   let user = if current_user == "root" { | ||||
|     get_real_user()? | ||||
|   } else { | ||||
|     uzers::get_user_by_name(¤t_user) | ||||
|       .ok_or_else(|| anyhow::anyhow!("User ({}) not found", current_user))? | ||||
|     uzers::get_user_by_name(¤t_user).ok_or_else(|| anyhow::anyhow!("User ({}) not found", current_user))? | ||||
|   }; | ||||
|  | ||||
|   if user.uid() == 0 { | ||||
|   | ||||
| @@ -66,10 +66,7 @@ impl GuiLauncher { | ||||
|  | ||||
|     let mut non_root_cmd = cmd.into_non_root()?; | ||||
|  | ||||
|     let mut child = non_root_cmd | ||||
|       .kill_on_drop(true) | ||||
|       .stdin(Stdio::piped()) | ||||
|       .spawn()?; | ||||
|     let mut child = non_root_cmd.kill_on_drop(true).stdin(Stdio::piped()).spawn()?; | ||||
|  | ||||
|     let mut stdin = child | ||||
|       .stdin | ||||
|   | ||||
| @@ -58,10 +58,7 @@ impl ConnectArgs { | ||||
|   } | ||||
|  | ||||
|   pub fn openconnect_os(&self) -> Option<String> { | ||||
|     self | ||||
|       .os | ||||
|       .as_ref() | ||||
|       .map(|os| os.to_openconnect_os().to_string()) | ||||
|     self.os.as_ref().map(|os| os.to_openconnect_os().to_string()) | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -30,9 +30,7 @@ pub fn normalize_server(server: &str) -> anyhow::Result<String> { | ||||
|     .host_str() | ||||
|     .ok_or(anyhow::anyhow!("Invalid server URL: missing host"))?; | ||||
|  | ||||
|   let port: String = normalized_url | ||||
|     .port() | ||||
|     .map_or("".into(), |port| format!(":{}", port)); | ||||
|   let port: String = normalized_url.port().map_or("".into(), |port| format!(":{}", port)); | ||||
|  | ||||
|   let normalized_url = format!("{}://{}{}", scheme, host, port); | ||||
|  | ||||
|   | ||||
| @@ -115,12 +115,7 @@ pub fn redact_uri(uri: &str) -> String { | ||||
|       .map(|query| format!("?{}", query)) | ||||
|       .unwrap_or_default(); | ||||
|  | ||||
|     return format!( | ||||
|       "{}://[**********]{}{}", | ||||
|       url.scheme(), | ||||
|       url.path(), | ||||
|       redacted_query | ||||
|     ); | ||||
|     return format!("{}://[**********]{}{}", url.scheme(), url.path(), redacted_query); | ||||
|   } | ||||
|  | ||||
|   let redacted_query = redact_query(url.query()); | ||||
| @@ -165,10 +160,7 @@ mod tests { | ||||
|  | ||||
|     redaction.add_value("foo").unwrap(); | ||||
|  | ||||
|     assert_eq!( | ||||
|       redaction.redact_str("hello, foo, bar"), | ||||
|       "hello, [**********], bar" | ||||
|     ); | ||||
|     assert_eq!(redaction.redact_str("hello, foo, bar"), "hello, [**********], bar"); | ||||
|   } | ||||
|  | ||||
|   #[test] | ||||
|   | ||||
| @@ -2,9 +2,7 @@ use tokio::signal; | ||||
|  | ||||
| pub async fn shutdown_signal() { | ||||
|   let ctrl_c = async { | ||||
|     signal::ctrl_c() | ||||
|       .await | ||||
|       .expect("failed to install Ctrl+C handler"); | ||||
|     signal::ctrl_c().await.expect("failed to install Ctrl+C handler"); | ||||
|   }; | ||||
|  | ||||
|   #[cfg(unix)] | ||||
|   | ||||
| @@ -5,8 +5,5 @@ fn main() { | ||||
|   println!("cargo:rerun-if-changed=src/ffi/vpn.h"); | ||||
|  | ||||
|   // Compile the vpn.c file | ||||
|   cc::Build::new() | ||||
|     .file("src/ffi/vpn.c") | ||||
|     .include("src/ffi") | ||||
|     .compile("vpn"); | ||||
|   cc::Build::new().file("src/ffi/vpn.c").include("src/ffi").compile("vpn"); | ||||
| } | ||||
|   | ||||
| @@ -20,10 +20,7 @@ pub(crate) struct ConnectOptions { | ||||
| #[link(name = "vpn")] | ||||
| extern "C" { | ||||
|   #[link_name = "vpn_connect"] | ||||
|   fn vpn_connect( | ||||
|     options: *const ConnectOptions, | ||||
|     callback: extern "C" fn(i32, *mut c_void), | ||||
|   ) -> c_int; | ||||
|   fn vpn_connect(options: *const ConnectOptions, callback: extern "C" fn(i32, *mut c_void)) -> c_int; | ||||
|  | ||||
|   #[link_name = "vpn_disconnect"] | ||||
|   fn vpn_disconnect(); | ||||
|   | ||||
| @@ -27,11 +27,7 @@ impl Vpn { | ||||
|   } | ||||
|  | ||||
|   pub fn connect(&self, on_connected: impl FnOnce() + 'static + Send + Sync) -> i32 { | ||||
|     self | ||||
|       .callback | ||||
|       .write() | ||||
|       .unwrap() | ||||
|       .replace(Box::new(on_connected)); | ||||
|     self.callback.write().unwrap().replace(Box::new(on_connected)); | ||||
|     let options = self.build_connect_options(); | ||||
|  | ||||
|     ffi::connect(&options) | ||||
| @@ -107,10 +103,7 @@ impl VpnBuilder { | ||||
|  | ||||
|   pub fn build(self) -> Vpn { | ||||
|     let user_agent = self.user_agent.unwrap_or_default(); | ||||
|     let script = self | ||||
|       .script | ||||
|       .or_else(find_default_vpnc_script) | ||||
|       .unwrap_or_default(); | ||||
|     let script = self.script.or_else(find_default_vpnc_script).unwrap_or_default(); | ||||
|     let os = self.os.unwrap_or("linux".to_string()); | ||||
|  | ||||
|     Vpn { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user