mirror of
https://github.com/yuezk/GlobalProtect-openconnect.git
synced 2025-05-20 07:26:58 -04:00
60 lines
2.0 KiB
Rust
60 lines
2.0 KiB
Rust
use std::{env::temp_dir, fs, future::Future, os::unix::fs::PermissionsExt};
|
|
|
|
use gpapi::{auth::SamlAuthData, GP_CALLBACK_PORT_FILENAME};
|
|
use log::info;
|
|
use tokio::{io::AsyncReadExt, net::TcpListener};
|
|
|
|
use crate::{browser_auth::browser_auth_impl::BrowserAuthenticatorImpl, AuthWindow};
|
|
|
|
pub trait BrowserAuthenticator {
|
|
fn browser_authenticate(&self, browser: Option<&str>) -> impl Future<Output = anyhow::Result<SamlAuthData>> + Send;
|
|
}
|
|
|
|
impl BrowserAuthenticator for AuthWindow<'_> {
|
|
async fn browser_authenticate(&self, browser: Option<&str>) -> anyhow::Result<SamlAuthData> {
|
|
let auth_request = self.initial_auth_request().await?;
|
|
let browser_auth = if let Some(browser) = browser {
|
|
BrowserAuthenticatorImpl::new_with_browser(&auth_request, browser)
|
|
} else {
|
|
BrowserAuthenticatorImpl::new(&auth_request)
|
|
};
|
|
|
|
browser_auth.authenticate()?;
|
|
info!("Please continue the authentication process in the default browser");
|
|
|
|
wait_auth_data().await
|
|
}
|
|
}
|
|
|
|
async fn wait_auth_data() -> anyhow::Result<SamlAuthData> {
|
|
// Start a local server to receive the browser authentication data
|
|
let listener = TcpListener::bind("127.0.0.1:0").await?;
|
|
let port = listener.local_addr()?.port();
|
|
let port_file = temp_dir().join(GP_CALLBACK_PORT_FILENAME);
|
|
|
|
// Write the port to a file
|
|
fs::write(&port_file, port.to_string())?;
|
|
fs::set_permissions(&port_file, fs::Permissions::from_mode(0o600))?;
|
|
|
|
// Remove the previous log file
|
|
let callback_log = temp_dir().join("gpcallback.log");
|
|
let _ = fs::remove_file(&callback_log);
|
|
|
|
info!("Listening authentication data on port {}", port);
|
|
info!(
|
|
"If it hangs, please check the logs at `{}` for more information",
|
|
callback_log.display()
|
|
);
|
|
let (mut socket, _) = listener.accept().await?;
|
|
|
|
info!("Received the browser authentication data from the socket");
|
|
let mut data = String::new();
|
|
socket.read_to_string(&mut data).await?;
|
|
|
|
// Remove the port file
|
|
fs::remove_file(&port_file)?;
|
|
|
|
let auth_data = SamlAuthData::from_gpcallback(&data)?;
|
|
Ok(auth_data)
|
|
}
|