Skip to main content

iroh_ssh/
cli.rs

1use std::{ffi::OsString, path::PathBuf};
2
3use clap::{ArgAction, Args, Parser, Subcommand};
4
5const TARGET_HELP: &str = "Target in the form user@ENDPOINT_ID";
6const RELAY_URL_HELP: &str = "Use only these relay servers, replacing the defaults (repeatable)";
7const EXTRA_RELAY_URL_HELP: &str = "Add relay servers alongside the defaults (repeatable)";
8
9#[derive(Parser, Debug)]
10#[command(name = "iroh-ssh", about = "ssh without ip")]
11pub struct Cli {
12    #[command(subcommand)]
13    pub cmd: Option<Cmd>,
14
15    #[arg(help = TARGET_HELP)]
16    pub target: Option<String>,
17
18    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
19    pub relay_url: Vec<String>,
20
21    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
22    pub extra_relay_url: Vec<String>,
23
24    #[command(flatten)]
25    pub ssh: SshOpts,
26
27    #[arg(trailing_var_arg = true)]
28    pub remote_cmd: Option<Vec<OsString>>,
29}
30
31#[derive(Subcommand,Debug)]
32pub enum Cmd {
33    Connect(ConnectArgs),
34    #[command(hide = true)]
35    Exec(ExecArgs),
36    Server(ServerArgs),
37    Service {
38        #[command(subcommand)]
39        op: ServiceCmd,
40    },
41    Info,
42    #[command(hide = true)]
43    Proxy(ProxyArgs),
44    #[command(hide = true)]
45    RunService(ServiceArgs),
46    Version,
47}
48
49#[derive(Args, Clone, Debug)]
50pub struct ProxyArgs {
51    #[arg(help = "Proxy Endpoint ID")]
52    pub endpoint_id: String,
53
54    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
55    pub relay_url: Vec<String>,
56
57    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
58    pub extra_relay_url: Vec<String>,
59}
60
61#[derive(Args, Clone, Debug)]
62pub struct ConnectArgs {
63    #[arg(help = TARGET_HELP)]
64    pub target: String,
65
66    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
67    pub relay_url: Vec<String>,
68
69    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
70    pub extra_relay_url: Vec<String>,
71
72    #[command(flatten)]
73    pub ssh: SshOpts,
74
75    #[arg(trailing_var_arg = true)]
76    pub remote_cmd: Vec<OsString>,
77}
78
79#[derive(Args, Clone, Debug)]
80pub struct ExecArgs {
81    #[arg(help = TARGET_HELP)]
82    pub target: String,
83
84    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
85    pub relay_url: Vec<String>,
86
87    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
88    pub extra_relay_url: Vec<String>,
89
90    #[command(flatten)]
91    pub ssh: SshOpts,
92
93    #[arg(trailing_var_arg = true, required = true)]
94    pub remote_cmd: Vec<OsString>,
95}
96
97#[derive(Args, Clone, Default, Debug)]
98pub struct SshOpts {
99    #[arg(
100        short = 'i',
101        long,
102        value_name = "PATH",
103        help = "Identity file for publickey auth"
104    )]
105    pub identity_file: Option<PathBuf>,
106
107    #[arg(short = 'L', value_name = "LPORT:HOST:RPORT",
108        help = "Local forward [bind_addr:]lport:host:rport (host can't be endpoint_id yet)", action = ArgAction::Append)]
109    pub local_forward: Vec<String>,
110
111    #[arg(short = 'R', value_name = "RPORT:HOST:LPORT",
112        help = "Remote forward [bind_addr:]rport:host:lport  (host can't be endpoint_id yet)", action = ArgAction::Append)]
113    pub remote_forward: Vec<String>,
114
115    #[arg(
116        short = 'p',
117        long,
118        value_name = "PORT",
119        help = "Remote sshd port (default 22)"
120    )]
121    pub port: Option<u16>,
122
123    #[arg(short = 'o', value_name = "KEY=VALUE",
124        help = "Pass an ssh option (repeatable)", action = ArgAction::Append)]
125    pub options: Vec<String>,
126
127    #[arg(short = 'A', help = "Enable agent forwarding", action = ArgAction::SetTrue)]
128    pub agent: bool,
129
130    #[arg(short = 'a', help = "Disable agent forwarding", action = ArgAction::SetTrue)]
131    pub no_agent: bool,
132
133    #[arg(short = 'X', help = "Enable X11 forwarding", action = ArgAction::SetTrue)]
134    pub x11: bool,
135
136    #[arg(short = 'Y', help = "Enable trusted X11 forwarding", action = ArgAction::SetTrue)]
137    pub x11_trusted: bool,
138
139    #[arg(short = 'N', help = "Do not execute remote command", action = ArgAction::SetTrue)]
140    pub no_cmd: bool,
141
142    #[arg(short = 't', help = "Force pseudo-terminal", action = ArgAction::SetTrue)]
143    pub force_tty: bool,
144
145    #[arg(short = 'T', help = "Disable pseudo-terminal", action = ArgAction::SetTrue)]
146    pub no_tty: bool,
147
148    #[arg(short = 'v', help = "Increase verbosity",
149        action = ArgAction::Count)]
150    pub verbose: u8,
151
152    #[arg(short = 'q', help = "Quiet mode", action = ArgAction::SetTrue)]
153    pub quiet: bool,
154}
155
156#[derive(Args, Clone, Debug)]
157pub struct ServerArgs {
158    #[arg(long, default_value = "22")]
159    pub ssh_port: u16,
160
161    #[arg(short, long, default_value_t = false)]
162    pub persist: bool,
163
164    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
165    pub relay_url: Vec<String>,
166
167    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
168    pub extra_relay_url: Vec<String>,
169}
170
171#[derive(Subcommand, Clone, Debug)]
172pub enum ServiceCmd {
173    Install {
174        #[arg(long, default_value = "22")]
175        ssh_port: u16,
176
177        #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
178        relay_url: Vec<String>,
179
180        #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
181        extra_relay_url: Vec<String>,
182    },
183    Uninstall,
184}
185
186#[derive(Args, Clone, Debug)]
187pub struct ServiceArgs {
188    #[arg(long, default_value = "22")]
189    pub ssh_port: u16,
190
191    #[arg(long, value_name = "URL", help = RELAY_URL_HELP, action = ArgAction::Append)]
192    pub relay_url: Vec<String>,
193
194    #[arg(long, value_name = "URL", help = EXTRA_RELAY_URL_HELP, action = ArgAction::Append)]
195    pub extra_relay_url: Vec<String>,
196}