Skip to content

Commit

Permalink
feat: support default browser for CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
yuezk committed Apr 14, 2024
1 parent 18ae1c5 commit ece6181
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 14 deletions.
2 changes: 1 addition & 1 deletion apps/gpclient/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ license.workspace = true

[dependencies]
common = { path = "../../crates/common" }
gpapi = { path = "../../crates/gpapi", features = ["clap"] }
gpapi = { path = "../../crates/gpapi", features = ["clap", "browser-auth"] }
openconnect = { path = "../../crates/openconnect" }
anyhow.workspace = true
clap.workspace = true
Expand Down
56 changes: 43 additions & 13 deletions apps/gpclient/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use gpapi::{
portal::{prelogin, retrieve_config, Prelogin},
process::{
auth_launcher::SamlAuthLauncher,
browser_authenticator::BrowserAuthenticator,
users::{get_non_root_user, get_user_by_name},
},
utils::shutdown_signal,
Expand All @@ -19,8 +20,9 @@ use gpapi::{
use inquire::{Password, PasswordDisplayMode, Select, Text};
use log::info;
use openconnect::Vpn;
use tokio::{io::AsyncReadExt, net::TcpListener};

use crate::{cli::SharedArgs, GP_CLIENT_LOCK_FILE};
use crate::{cli::SharedArgs, GP_CLIENT_LOCK_FILE, GP_CLIENT_PORT_FILE};

#[derive(Args)]
pub(crate) struct ConnectArgs {
Expand Down Expand Up @@ -60,6 +62,8 @@ pub(crate) struct ConnectArgs {
hidpi: bool,
#[arg(long, help = "Do not reuse the remembered authentication cookie")]
clean: bool,
#[arg(long, help = "Use the default browser to authenticate")]
default_browser: bool,
}

impl ConnectArgs {
Expand Down Expand Up @@ -240,18 +244,44 @@ impl<'a> ConnectHandler<'a> {

match prelogin {
Prelogin::Saml(prelogin) => {
SamlAuthLauncher::new(&self.args.server)
.gateway(is_gateway)
.saml_request(prelogin.saml_request())
.user_agent(&self.args.user_agent)
.os(self.args.os.as_str())
.os_version(Some(&self.args.os_version()))
.hidpi(self.args.hidpi)
.fix_openssl(self.shared_args.fix_openssl)
.ignore_tls_errors(self.shared_args.ignore_tls_errors)
.clean(self.args.clean)
.launch()
.await
let use_default_browser = prelogin.support_default_browser() && self.args.default_browser;
if use_default_browser {
let browser_auth = BrowserAuthenticator::new(prelogin.saml_request());
browser_auth.authenticate()?;

info!("Waiting for the browser authentication to complete...");

// 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();

// Write the port to a file
fs::write(GP_CLIENT_PORT_FILE, port.to_string())?;

info!("Listening on port {}", port);
let (mut socket, _) = listener.accept().await?;

info!("Read the browser authentication data from the socket");
let mut data = String::new();
socket.read_to_string(&mut data).await?;

info!("Received the browser authentication data: {}", data);

panic!("TODO: implement the browser authentication data processing")
} else {
SamlAuthLauncher::new(&self.args.server)
.gateway(is_gateway)
.saml_request(prelogin.saml_request())
.user_agent(&self.args.user_agent)
.os(self.args.os.as_str())
.os_version(Some(&self.args.os_version()))
.hidpi(self.args.hidpi)
.fix_openssl(self.shared_args.fix_openssl)
.ignore_tls_errors(self.shared_args.ignore_tls_errors)
.clean(self.args.clean)
.launch()
.await
}
}
Prelogin::Standard(prelogin) => {
let prefix = if is_gateway { "Gateway" } else { "Portal" };
Expand Down
17 changes: 17 additions & 0 deletions apps/gpclient/src/launch_gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ use gpapi::{
utils::{endpoint::http_endpoint, env_file, shutdown_signal},
};
use log::info;
use tokio::io::AsyncWriteExt;

use crate::GP_CLIENT_PORT_FILE;

#[derive(Args)]
pub(crate) struct LaunchGuiArgs {
Expand Down Expand Up @@ -78,6 +81,11 @@ impl<'a> LaunchGuiHandler<'a> {
}

async fn feed_auth_data(auth_data: &str) -> anyhow::Result<()> {
let _ = tokio::join!(feed_auth_data_gui(auth_data), feed_auth_data_cli(auth_data));
Ok(())
}

async fn feed_auth_data_gui(auth_data: &str) -> anyhow::Result<()> {
let service_endpoint = http_endpoint().await?;

reqwest::Client::default()
Expand All @@ -90,6 +98,15 @@ async fn feed_auth_data(auth_data: &str) -> anyhow::Result<()> {
Ok(())
}

async fn feed_auth_data_cli(auth_data: &str) -> anyhow::Result<()> {
let port = tokio::fs::read_to_string(GP_CLIENT_PORT_FILE).await?;
let mut stream = tokio::net::TcpStream::connect(format!("127.0.0.1:{}", port.trim())).await?;

stream.write_all(auth_data.as_bytes()).await?;

Ok(())
}

async fn try_active_gui() -> anyhow::Result<()> {
let service_endpoint = http_endpoint().await?;

Expand Down
1 change: 1 addition & 0 deletions apps/gpclient/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod disconnect;
mod launch_gui;

pub(crate) const GP_CLIENT_LOCK_FILE: &str = "/var/run/gpclient.lock";
pub(crate) const GP_CLIENT_PORT_FILE: &str = "/var/run/gpclient.port";

#[tokio::main]
async fn main() {
Expand Down

0 comments on commit ece6181

Please sign in to comment.