mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-04-02 18:31:50 -04:00
162 lines
3.5 KiB
Rust
162 lines
3.5 KiB
Rust
use std::process::Stdio;
|
|
|
|
use anyhow::bail;
|
|
use tokio::process::Command;
|
|
|
|
use crate::{auth::SamlAuthResult, credential::Credential, GP_AUTH_BINARY};
|
|
|
|
use super::command_traits::CommandExt;
|
|
|
|
pub struct SamlAuthLauncher<'a> {
|
|
server: &'a str,
|
|
gateway: bool,
|
|
saml_request: Option<&'a str>,
|
|
user_agent: Option<&'a str>,
|
|
os: Option<&'a str>,
|
|
os_version: Option<&'a str>,
|
|
hidpi: bool,
|
|
fix_openssl: bool,
|
|
ignore_tls_errors: bool,
|
|
clean: bool,
|
|
default_browser: bool,
|
|
browser: Option<&'a str>,
|
|
}
|
|
|
|
impl<'a> SamlAuthLauncher<'a> {
|
|
pub fn new(server: &'a str) -> Self {
|
|
Self {
|
|
server,
|
|
gateway: false,
|
|
saml_request: None,
|
|
user_agent: None,
|
|
os: None,
|
|
os_version: None,
|
|
hidpi: false,
|
|
fix_openssl: false,
|
|
ignore_tls_errors: false,
|
|
clean: false,
|
|
default_browser: false,
|
|
browser: None,
|
|
}
|
|
}
|
|
|
|
pub fn gateway(mut self, gateway: bool) -> Self {
|
|
self.gateway = gateway;
|
|
self
|
|
}
|
|
|
|
pub fn saml_request(mut self, saml_request: &'a str) -> Self {
|
|
self.saml_request = Some(saml_request);
|
|
self
|
|
}
|
|
|
|
pub fn user_agent(mut self, user_agent: &'a str) -> Self {
|
|
self.user_agent = Some(user_agent);
|
|
self
|
|
}
|
|
|
|
pub fn os(mut self, os: &'a str) -> Self {
|
|
self.os = Some(os);
|
|
self
|
|
}
|
|
|
|
pub fn os_version(mut self, os_version: Option<&'a str>) -> Self {
|
|
self.os_version = os_version;
|
|
self
|
|
}
|
|
|
|
pub fn hidpi(mut self, hidpi: bool) -> Self {
|
|
self.hidpi = hidpi;
|
|
self
|
|
}
|
|
|
|
pub fn fix_openssl(mut self, fix_openssl: bool) -> Self {
|
|
self.fix_openssl = fix_openssl;
|
|
self
|
|
}
|
|
|
|
pub fn ignore_tls_errors(mut self, ignore_tls_errors: bool) -> Self {
|
|
self.ignore_tls_errors = ignore_tls_errors;
|
|
self
|
|
}
|
|
|
|
pub fn clean(mut self, clean: bool) -> Self {
|
|
self.clean = clean;
|
|
self
|
|
}
|
|
|
|
pub fn default_browser(mut self, default_browser: bool) -> Self {
|
|
self.default_browser = default_browser;
|
|
self
|
|
}
|
|
|
|
pub fn browser(mut self, browser: Option<&'a str>) -> Self {
|
|
self.browser = browser;
|
|
self
|
|
}
|
|
|
|
/// Launch the authenticator binary as the current user or SUDO_USER if available.
|
|
pub async fn launch(self) -> anyhow::Result<Credential> {
|
|
let mut auth_cmd = Command::new(GP_AUTH_BINARY);
|
|
auth_cmd.arg(self.server);
|
|
|
|
if self.gateway {
|
|
auth_cmd.arg("--gateway");
|
|
}
|
|
|
|
if let Some(saml_request) = self.saml_request {
|
|
auth_cmd.arg("--saml-request").arg(saml_request);
|
|
}
|
|
|
|
if let Some(user_agent) = self.user_agent {
|
|
auth_cmd.arg("--user-agent").arg(user_agent);
|
|
}
|
|
|
|
if let Some(os) = self.os {
|
|
auth_cmd.arg("--os").arg(os);
|
|
}
|
|
|
|
if let Some(os_version) = self.os_version {
|
|
auth_cmd.arg("--os-version").arg(os_version);
|
|
}
|
|
|
|
if self.hidpi {
|
|
auth_cmd.arg("--hidpi");
|
|
}
|
|
|
|
if self.fix_openssl {
|
|
auth_cmd.arg("--fix-openssl");
|
|
}
|
|
|
|
if self.ignore_tls_errors {
|
|
auth_cmd.arg("--ignore-tls-errors");
|
|
}
|
|
|
|
if self.clean {
|
|
auth_cmd.arg("--clean");
|
|
}
|
|
|
|
if self.default_browser {
|
|
auth_cmd.arg("--default-browser");
|
|
}
|
|
|
|
if let Some(browser) = self.browser {
|
|
auth_cmd.arg("--browser").arg(browser);
|
|
}
|
|
|
|
let mut non_root_cmd = auth_cmd.into_non_root()?;
|
|
let output = non_root_cmd
|
|
.kill_on_drop(true)
|
|
.stdout(Stdio::piped())
|
|
.spawn()?
|
|
.wait_with_output()
|
|
.await?;
|
|
|
|
let Ok(auth_result) = serde_json::from_slice::<SamlAuthResult>(&output.stdout) else {
|
|
bail!("Failed to parse auth data")
|
|
};
|
|
|
|
Credential::try_from(auth_result)
|
|
}
|
|
}
|