From 6abbf9e32be79aaaeb5272c95c1325e6f4b4e26d Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 8 Sep 2000 15:24:19 +0000 Subject: [PATCH] plink can now execute a specific command instead of just a shell session git-svn-id: svn://svn.tartarus.org/sgt/putty@576 cda61777-01e9-0310-a592-d414129be87e --- putty.h | 1 + ssh.c | 38 ++++++++++++++++++++++++++++++-------- windlg.c | 2 ++ 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/putty.h b/putty.h index fbd5e64b..8c69d905 100644 --- a/putty.h +++ b/putty.h @@ -134,6 +134,7 @@ typedef struct { int close_on_exit; int warn_on_close; /* SSH options */ + char remote_cmd[512]; int nopty; enum { CIPHER_3DES, CIPHER_BLOWFISH, CIPHER_DES } cipher; char keyfile[FILENAME_MAX]; diff --git a/ssh.c b/ssh.c index 26043c63..7e02bacf 100644 --- a/ssh.c +++ b/ssh.c @@ -221,6 +221,7 @@ struct Packet { static struct Packet pktin = { 0, 0, NULL, NULL, 0 }; static struct Packet pktout = { 0, 0, NULL, NULL, 0 }; +static int ssh_version; static void (*ssh_protocol)(unsigned char *in, int inlen, int ispkt); static void ssh1_protocol(unsigned char *in, int inlen, int ispkt); static void ssh2_protocol(unsigned char *in, int inlen, int ispkt); @@ -972,6 +973,7 @@ static int do_ssh_init(void) { logevent("Using SSH protocol version 2"); s_write(vstring, strlen(vstring)); ssh_protocol = ssh2_protocol; + ssh_version = 2; s_rdpkt = ssh2_rdpkt; } else { /* @@ -985,6 +987,7 @@ static int do_ssh_init(void) { logevent("Using SSH protocol version 1"); s_write(vstring, strlen(vstring)); ssh_protocol = ssh1_protocol; + ssh_version = 1; s_rdpkt = ssh1_rdpkt; } return 1; @@ -1398,7 +1401,10 @@ static void ssh1_protocol(unsigned char *in, int inlen, int ispkt) { logevent("Allocated pty"); } - send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END); + if (*cfg.remote_cmd) + send_packet(SSH1_CMSG_EXEC_CMD, PKT_STR, cfg.remote_cmd, PKT_END); + else + send_packet(SSH1_CMSG_EXEC_SHELL, PKT_END); logevent("Started session"); ssh_state = SSH_STATE_SESSION; @@ -1744,11 +1750,15 @@ static int do_ssh2_transport(unsigned char *in, int inlen, int ispkt) } /* + * SSH2: remote identifier for the main session channel. + */ +static unsigned long ssh_remote_channel; + +/* * Handle the SSH2 userauth and connection layers. */ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) { - static unsigned long their_channel; static unsigned long remote_winsize; static unsigned long remote_maxpkt; @@ -1909,7 +1919,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) if (ssh2_pkt_getuint32() != 100) { fatalbox("Server's channel confirmation cited wrong channel"); } - their_channel = ssh2_pkt_getuint32(); + ssh_remote_channel = ssh2_pkt_getuint32(); remote_winsize = ssh2_pkt_getuint32(); remote_maxpkt = ssh2_pkt_getuint32(); logevent("Opened channel for session"); @@ -1918,7 +1928,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) * Now allocate a pty for the session. */ ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); - ssh2_pkt_adduint32(their_channel); /* recipient channel */ + ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */ ssh2_pkt_addstring("pty-req"); ssh2_pkt_addbool(1); /* want reply */ ssh2_pkt_addstring(cfg.termtype); @@ -1947,7 +1957,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) * Start a shell. */ ssh2_pkt_init(SSH2_MSG_CHANNEL_REQUEST); - ssh2_pkt_adduint32(their_channel); /* recipient channel */ + ssh2_pkt_adduint32(ssh_remote_channel); /* recipient channel */ ssh2_pkt_addstring("shell"); ssh2_pkt_addbool(1); /* want reply */ ssh2_pkt_send(); @@ -1994,7 +2004,7 @@ static void do_ssh2_authconn(unsigned char *in, int inlen, int ispkt) } else { /* FIXME: for now, ignore window size */ ssh2_pkt_init(SSH2_MSG_CHANNEL_DATA); - ssh2_pkt_adduint32(their_channel); + ssh2_pkt_adduint32(ssh_remote_channel); ssh2_pkt_addstring_start(); ssh2_pkt_addstring_data(in, inlen); ssh2_pkt_send(); @@ -2120,10 +2130,22 @@ static void ssh_size(void) { } /* - * (Send Telnet special codes) + * Send Telnet special codes. TS_EOF is useful for `plink', so you + * can send an EOF and collect resulting output (e.g. `plink + * hostname sort'). */ static void ssh_special (Telnet_Special code) { - /* do nothing */ + if (code == TS_EOF) { + if (ssh_version = 1) { + send_packet(SSH1_CMSG_EOF, PKT_END); + } else { + ssh2_pkt_init(SSH2_MSG_CHANNEL_EOF); + ssh2_pkt_adduint32(ssh_remote_channel); + ssh2_pkt_send(); + } + } else { + /* do nothing */ + } } diff --git a/windlg.c b/windlg.c index f6c342ed..825072b0 100644 --- a/windlg.c +++ b/windlg.c @@ -149,6 +149,7 @@ static void save_settings (char *section, int do_host) { } wpps (sesskey, "UserName", cfg.username); wppi (sesskey, "NoPTY", cfg.nopty); + wpps (sesskey, "RemoteCmd", cfg.remote_cmd); wpps (sesskey, "Cipher", cfg.cipher == CIPHER_BLOWFISH ? "blowfish" : cfg.cipher == CIPHER_DES ? "des" : "3des"); wppi (sesskey, "AuthTIS", cfg.try_tis_auth); @@ -283,6 +284,7 @@ static void load_settings (char *section, int do_host) { } gpps (sesskey, "UserName", "", cfg.username, sizeof(cfg.username)); gppi (sesskey, "NoPTY", 0, &cfg.nopty); + gpps (sesskey, "RemoteCmd", "", cfg.remote_cmd, sizeof(cfg.remote_cmd)); { char cipher[10]; gpps (sesskey, "Cipher", "3des", cipher, 10); -- 2.11.0