mirror of
				https://github.com/yuezk/GlobalProtect-openconnect.git
				synced 2025-05-20 07:26:58 -04:00 
			
		
		
		
	Refactor using Tauri (#278)
This commit is contained in:
		
							
								
								
									
										74
									
								
								crates/gpapi/src/gateway/login.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								crates/gpapi/src/gateway/login.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,74 @@ | ||||
| use log::info; | ||||
| use reqwest::Client; | ||||
| use roxmltree::Document; | ||||
| use urlencoding::encode; | ||||
|  | ||||
| use crate::{credential::Credential, gp_params::GpParams}; | ||||
|  | ||||
| pub async fn gateway_login( | ||||
|   gateway: &str, | ||||
|   cred: &Credential, | ||||
|   gp_params: &GpParams, | ||||
| ) -> anyhow::Result<String> { | ||||
|   let login_url = format!("https://{}/ssl-vpn/login.esp", gateway); | ||||
|   let client = Client::builder() | ||||
|     .user_agent(gp_params.user_agent()) | ||||
|     .build()?; | ||||
|  | ||||
|   let mut params = cred.to_params(); | ||||
|   let extra_params = gp_params.to_params(); | ||||
|  | ||||
|   params.extend(extra_params); | ||||
|   params.insert("server", gateway); | ||||
|  | ||||
|   info!("Gateway login, user_agent: {}", gp_params.user_agent()); | ||||
|  | ||||
|   let res_xml = client | ||||
|     .post(&login_url) | ||||
|     .form(¶ms) | ||||
|     .send() | ||||
|     .await? | ||||
|     .error_for_status()? | ||||
|     .text() | ||||
|     .await?; | ||||
|  | ||||
|   let doc = Document::parse(&res_xml)?; | ||||
|  | ||||
|   build_gateway_token(&doc, gp_params.computer()) | ||||
| } | ||||
|  | ||||
| fn build_gateway_token(doc: &Document, computer: &str) -> anyhow::Result<String> { | ||||
|   let args = doc | ||||
|     .descendants() | ||||
|     .filter(|n| n.has_tag_name("argument")) | ||||
|     .map(|n| n.text().unwrap_or("").to_string()) | ||||
|     .collect::<Vec<_>>(); | ||||
|  | ||||
|   let params = [ | ||||
|     read_args(&args, 1, "authcookie")?, | ||||
|     read_args(&args, 3, "portal")?, | ||||
|     read_args(&args, 4, "user")?, | ||||
|     read_args(&args, 7, "domain")?, | ||||
|     read_args(&args, 15, "preferred-ip")?, | ||||
|     ("computer", computer), | ||||
|   ]; | ||||
|  | ||||
|   let token = params | ||||
|     .iter() | ||||
|     .map(|(k, v)| format!("{}={}", k, encode(v))) | ||||
|     .collect::<Vec<_>>() | ||||
|     .join("&"); | ||||
|  | ||||
|   Ok(token) | ||||
| } | ||||
|  | ||||
| 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")) | ||||
|     .map(|s| (key, s.as_ref())) | ||||
| } | ||||
							
								
								
									
										41
									
								
								crates/gpapi/src/gateway/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								crates/gpapi/src/gateway/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,41 @@ | ||||
| mod login; | ||||
| mod parse_gateways; | ||||
|  | ||||
| pub use login::*; | ||||
| pub(crate) use parse_gateways::*; | ||||
|  | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use specta::Type; | ||||
|  | ||||
| use std::fmt::Display; | ||||
|  | ||||
| #[derive(Debug, Serialize, Deserialize, Type, Clone)] | ||||
| pub(crate) struct PriorityRule { | ||||
|   pub(crate) name: String, | ||||
|   pub(crate) priority: u32, | ||||
| } | ||||
|  | ||||
| #[derive(Debug, Serialize, Deserialize, Type, Clone)] | ||||
| #[serde(rename_all = "camelCase")] | ||||
| pub struct Gateway { | ||||
|   pub(crate) name: String, | ||||
|   pub(crate) address: String, | ||||
|   pub(crate) priority: u32, | ||||
|   pub(crate) priority_rules: Vec<PriorityRule>, | ||||
| } | ||||
|  | ||||
| impl Display for Gateway { | ||||
|   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||||
|     write!(f, "{} ({})", self.name, self.address) | ||||
|   } | ||||
| } | ||||
|  | ||||
| impl Gateway { | ||||
|   pub fn name(&self) -> &str { | ||||
|     &self.name | ||||
|   } | ||||
|  | ||||
|   pub fn server(&self) -> &str { | ||||
|     &self.address | ||||
|   } | ||||
| } | ||||
							
								
								
									
										63
									
								
								crates/gpapi/src/gateway/parse_gateways.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								crates/gpapi/src/gateway/parse_gateways.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| use roxmltree::Document; | ||||
|  | ||||
| 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 gateways = list_gateway | ||||
|     .children() | ||||
|     .filter_map(|gateway_item| { | ||||
|       if !gateway_item.has_tag_name("entry") { | ||||
|         return None; | ||||
|       } | ||||
|       let address = gateway_item.attribute("name").unwrap_or("").to_string(); | ||||
|       let name = gateway_item | ||||
|         .children() | ||||
|         .find(|n| n.has_tag_name("description")) | ||||
|         .and_then(|n| n.text()) | ||||
|         .unwrap_or("") | ||||
|         .to_string(); | ||||
|       let priority = gateway_item | ||||
|         .children() | ||||
|         .find(|n| n.has_tag_name("priority")) | ||||
|         .and_then(|n| n.text()) | ||||
|         .and_then(|s| s.parse().ok()) | ||||
|         .unwrap_or(u32::MAX); | ||||
|       let priority_rules = gateway_item | ||||
|         .children() | ||||
|         .find(|n| n.has_tag_name("priority-rule")) | ||||
|         .map(|n| { | ||||
|           n.children() | ||||
|             .filter_map(|n| { | ||||
|               if !n.has_tag_name("entry") { | ||||
|                 return None; | ||||
|               } | ||||
|               let name = n.attribute("name").unwrap_or("").to_string(); | ||||
|               let priority: u32 = n | ||||
|                 .children() | ||||
|                 .find(|n| n.has_tag_name("priority")) | ||||
|                 .and_then(|n| n.text()) | ||||
|                 .and_then(|s| s.parse().ok()) | ||||
|                 .unwrap_or(u32::MAX); | ||||
|  | ||||
|               Some(PriorityRule { name, priority }) | ||||
|             }) | ||||
|             .collect() | ||||
|         }) | ||||
|         .unwrap_or_default(); | ||||
|  | ||||
|       Some(Gateway { | ||||
|         name, | ||||
|         address, | ||||
|         priority, | ||||
|         priority_rules, | ||||
|       }) | ||||
|     }) | ||||
|     .collect(); | ||||
|  | ||||
|   Some(gateways) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user