summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2019-04-02 09:03:35 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2019-04-02 09:03:35 +0200
commit47ec5de29e56c4cf223e0582b930b88ca2a589ee (patch)
tree70943702b3cb7e3f47e6771a8d0ce008c2c81f88
parent4f0bfe0fb8dc608a94fe429c5ddb12e58997e1ce (diff)
ssh: implement -W option for making remote tcp connections
-rw-r--r--sys/man/1/ssh10
-rw-r--r--sys/src/cmd/ssh.c108
2 files changed, 80 insertions, 38 deletions
diff --git a/sys/man/1/ssh b/sys/man/1/ssh
index 3e6ca94d6..ac4f8f754 100644
--- a/sys/man/1/ssh
+++ b/sys/man/1/ssh
@@ -23,6 +23,9 @@ ssh - secure shell remote login client
] [
.IR user @] host
[
+.B -W
+.I remote!port
+] [
.I cmd
.I args
.I ...
@@ -83,6 +86,13 @@ with the
.B -r
option.
.PP
+With the
+.B -W
+option, instead of executing a command remotely, makes
+the server dial a tcp connection to
+.I remote!port
+which the client relays on standard input and output.
+.PP
The
.B -d
option enables debug output.
diff --git a/sys/src/cmd/ssh.c b/sys/src/cmd/ssh.c
index 18fea5805..29d6e2de3 100644
--- a/sys/src/cmd/ssh.c
+++ b/sys/src/cmd/ssh.c
@@ -80,8 +80,8 @@ int nsid;
uchar sid[256];
char thumb[2*SHA2_256dlen+1], *thumbfile;
-int fd, intr, raw, debug;
-char *user, *service, *status, *host, *cmd;
+int fd, intr, raw, port, debug;
+char *user, *service, *status, *host, *remote, *cmd;
Oneway recv, send;
void dispatch(void);
@@ -1147,7 +1147,7 @@ kfmt(Fmt *f)
void
usage(void)
{
- fprint(2, "usage: %s [-dR] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [cmd args...]\n", argv0);
+ fprint(2, "usage: %s [-dR] [-t thumbfile] [-T tries] [-u user] [-h] [user@]host [-W remote!port] [cmd args...]\n", argv0);
exits("usage");
}
@@ -1173,6 +1173,17 @@ main(int argc, char *argv[])
case 'd':
debug++;
break;
+ case 'W':
+ remote = EARGF(usage());
+ s = strrchr(remote, '!');
+ if(s == nil)
+ s = strrchr(remote, ':');
+ if(s == nil)
+ usage();
+ *s++ = 0;
+ port = atoi(s);
+ raw = 0;
+ break;
case 'R':
raw = 0;
break;
@@ -1221,6 +1232,9 @@ main(int argc, char *argv[])
}
}
+ if(remote != nil && cmd != nil)
+ usage();
+
if((fd = dial(netmkaddr(host, nil, "ssh"), nil, nil, nil)) < 0)
sysfatal("dial: %r");
@@ -1260,11 +1274,27 @@ Next0: switch(recvpkt()){
recv.chan = 0;
/* open hailing frequencies */
- sendpkt("bsuuu", MSG_CHANNEL_OPEN,
- "session", 7,
- recv.chan,
- recv.win,
- recv.pkt);
+ if(remote != nil){
+ NetConnInfo *nci = getnetconninfo(nil, fd);
+ if(nci == nil)
+ sysfatal("can't get netconninfo: %r");
+ sendpkt("bsuuususu", MSG_CHANNEL_OPEN,
+ "direct-tcpip", 12,
+ recv.chan,
+ recv.win,
+ recv.pkt,
+ remote, strlen(remote),
+ port,
+ nci->laddr, strlen(nci->laddr),
+ atoi(nci->lserv));
+ free(nci);
+ } else {
+ sendpkt("bsuuu", MSG_CHANNEL_OPEN,
+ "session", 7,
+ recv.chan,
+ recv.win,
+ recv.pkt);
+ }
Next1: switch(recvpkt()){
default:
@@ -1307,36 +1337,38 @@ Next1: switch(recvpkt()){
/* child reads input and sends packets */
qlock(&sl);
- if(raw) {
- rawon();
- sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,
- send.chan,
- "pty-req", 7,
- 0,
- tty.term, strlen(tty.term),
- tty.cols,
- tty.lines,
- tty.xpixels,
- tty.ypixels,
- "", 0);
- }
- if(cmd == nil){
- sendpkt("busb", MSG_CHANNEL_REQUEST,
- send.chan,
- "shell", 5,
- 0);
- } else if(*cmd == '#') {
- sendpkt("busbs", MSG_CHANNEL_REQUEST,
- send.chan,
- "subsystem", 9,
- 0,
- cmd+1, strlen(cmd)-1);
- } else {
- sendpkt("busbs", MSG_CHANNEL_REQUEST,
- send.chan,
- "exec", 4,
- 0,
- cmd, strlen(cmd));
+ if(remote == nil){
+ if(raw) {
+ rawon();
+ sendpkt("busbsuuuus", MSG_CHANNEL_REQUEST,
+ send.chan,
+ "pty-req", 7,
+ 0,
+ tty.term, strlen(tty.term),
+ tty.cols,
+ tty.lines,
+ tty.xpixels,
+ tty.ypixels,
+ "", 0);
+ }
+ if(cmd == nil){
+ sendpkt("busb", MSG_CHANNEL_REQUEST,
+ send.chan,
+ "shell", 5,
+ 0);
+ } else if(*cmd == '#') {
+ sendpkt("busbs", MSG_CHANNEL_REQUEST,
+ send.chan,
+ "subsystem", 9,
+ 0,
+ cmd+1, strlen(cmd)-1);
+ } else {
+ sendpkt("busbs", MSG_CHANNEL_REQUEST,
+ send.chan,
+ "exec", 4,
+ 0,
+ cmd, strlen(cmd));
+ }
}
for(;;){
static uchar buf[MaxPacket];