Skip to content

Commit d7fb03d

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 d7fb03d

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

crates/sshx/src/controller.rs

Lines changed: 16 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,17 @@ 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+
51+
fn add_auth_header_to_request<T>(mut req: tonic::Request<T>, auth_token: &Option<String>) -> tonic::Request<T> {
52+
if let Some(token) = auth_token {
53+
if let Ok(auth_value) = tonic::metadata::MetadataValue::try_from(format!("Bearer {}", token)) {
54+
req.metadata_mut().insert("authorization", auth_value);
55+
}
56+
}
57+
req
4658
}
4759

4860
impl Controller {
@@ -52,6 +64,7 @@ impl Controller {
5264
name: &str,
5365
runner: Runner,
5466
enable_readers: bool,
67+
auth_token: &Option<String>,
5568
) -> Result<Self> {
5669
debug!(%origin, "connecting to server");
5770
let encryption_key = rand_alphanumeric(14); // 83.3 bits of entropy
@@ -86,6 +99,7 @@ impl Controller {
8699
name: name.into(),
87100
write_password_hash,
88101
};
102+
let req = add_auth_header_to_request(tonic::Request::new(req), auth_token);
89103
let mut resp = client.open(req).await?.into_inner();
90104
resp.url = resp.url + "#" + &encryption_key;
91105

@@ -108,6 +122,7 @@ impl Controller {
108122
shells_tx: HashMap::new(),
109123
output_tx,
110124
output_rx,
125+
auth_token: auth_token.clone(),
111126
})
112127
}
113128

@@ -280,6 +295,7 @@ impl Controller {
280295
name: self.name.clone(),
281296
token: self.token.clone(),
282297
};
298+
let req = add_auth_header_to_request(tonic::Request::new(req), &self.auth_token);
283299
let mut client = Self::connect(&self.origin).await?;
284300
client.close(req).await?;
285301
Ok(())

crates/sshx/src/main.rs

Lines changed: 5 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,7 @@ 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(&args.server, &name, runner, args.enable_readers, &args.auth_token).await?;
9498
if args.quiet {
9599
if let Some(write_url) = controller.write_url() {
96100
println!("{}", write_url);

0 commit comments

Comments
 (0)