Skip to content

Commit 5395db6

Browse files
committed
Add authentication token support
Add --auth-token CLI option to include Bearer authentication in gRPC requests. Supports both command line argument and SSHX_AUTH_TOKEN environment variable. This enables integration with authentication systems that require tokens to be passed in the Authorization header for both session creation and cleanup. Signed-off-by: Ben Copeland <[email protected]>
1 parent dd42496 commit 5395db6

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

crates/sshx/src/controller.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Network gRPC client allowing server control of terminals.
22
33
use std::collections::HashMap;
4+
use std::convert::TryFrom;
45
use std::pin::pin;
56

67
use anyhow::{Context, Result};
@@ -43,6 +44,21 @@ pub struct Controller {
4344
output_tx: mpsc::Sender<ClientMessage>,
4445
/// Owned receiving end of the `output_tx` channel.
4546
output_rx: mpsc::Receiver<ClientMessage>,
47+
auth_token: Option<String>,
48+
}
49+
50+
fn add_auth_header_to_request<T>(
51+
mut req: tonic::Request<T>,
52+
auth_token: &Option<String>,
53+
) -> tonic::Request<T> {
54+
if let Some(token) = auth_token {
55+
if let Ok(auth_value) =
56+
tonic::metadata::MetadataValue::try_from(format!("Bearer {}", token))
57+
{
58+
req.metadata_mut().insert("authorization", auth_value);
59+
}
60+
}
61+
req
4662
}
4763

4864
impl Controller {
@@ -52,6 +68,7 @@ impl Controller {
5268
name: &str,
5369
runner: Runner,
5470
enable_readers: bool,
71+
auth_token: &Option<String>,
5572
) -> Result<Self> {
5673
debug!(%origin, "connecting to server");
5774
let encryption_key = rand_alphanumeric(14); // 83.3 bits of entropy
@@ -86,6 +103,7 @@ impl Controller {
86103
name: name.into(),
87104
write_password_hash,
88105
};
106+
let req = add_auth_header_to_request(tonic::Request::new(req), auth_token);
89107
let mut resp = client.open(req).await?.into_inner();
90108
resp.url = resp.url + "#" + &encryption_key;
91109

@@ -108,6 +126,7 @@ impl Controller {
108126
shells_tx: HashMap::new(),
109127
output_tx,
110128
output_rx,
129+
auth_token: auth_token.clone(),
111130
})
112131
}
113132

@@ -280,6 +299,7 @@ impl Controller {
280299
name: self.name.clone(),
281300
token: self.token.clone(),
282301
};
302+
let req = add_auth_header_to_request(tonic::Request::new(req), &self.auth_token);
283303
let mut client = Self::connect(&self.origin).await?;
284304
client.close(req).await?;
285305
Ok(())

crates/sshx/src/main.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ struct Args {
3131
/// editors.
3232
#[clap(long)]
3333
enable_readers: bool,
34+
35+
/// Authentication token (sent as Authorization header)
36+
#[arg(long, env = "SSHX_AUTH_TOKEN")]
37+
pub auth_token: Option<String>,
3438
}
3539

3640
fn print_greeting(shell: &str, controller: &Controller) {
@@ -90,7 +94,14 @@ async fn start(args: Args) -> Result<()> {
9094
});
9195

9296
let runner = Runner::Shell(shell.clone());
93-
let mut controller = Controller::new(&args.server, &name, runner, args.enable_readers).await?;
97+
let mut controller = Controller::new(
98+
&args.server,
99+
&name,
100+
runner,
101+
args.enable_readers,
102+
&args.auth_token,
103+
)
104+
.await?;
94105
if args.quiet {
95106
if let Some(write_url) = controller.write_url() {
96107
println!("{}", write_url);

0 commit comments

Comments
 (0)