зеркало из https://github.com/github/putty.git
Implement part of `ssh2-generality': introduce the ability to tell
PuTTY / Plink not to run a remote shell/command at all. Supported in the GUI configuration and via the (OpenSSH-like) -N command-line option. No effort is currently made to arrange `nice' UI properties. If you do this in GUI PuTTY, a full-size terminal window will still be created, and will sit there with almost nothing in it throughout your session. If you do it in Plink, Plink will not accept any kind of request to terminate gracefully; you'll have to ^C or kill it. Nonetheless, even this little will be useful to some people... [originally from svn r4614]
This commit is contained in:
Родитель
8f656a37b5
Коммит
dd279dffc2
|
@ -314,6 +314,13 @@ int cmdline_process_param(char *p, char *value, int need_save, Config *cfg)
|
|||
cfg->nopty = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(p, "-N")) {
|
||||
RETURN(1);
|
||||
UNAVAILABLE_IN(TOOLTYPE_FILETRANSFER | TOOLTYPE_NONNETWORK);
|
||||
SAVEABLE(0);
|
||||
cfg->ssh_no_shell = 1;
|
||||
}
|
||||
|
||||
if (!strcmp(p, "-C")) {
|
||||
RETURN(1);
|
||||
UNAVAILABLE_IN(TOOLTYPE_NONNETWORK);
|
||||
|
|
6
config.c
6
config.c
|
@ -1491,6 +1491,10 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
|
|||
HELPCTX(ssh_nopty),
|
||||
dlg_stdcheckbox_handler,
|
||||
I(offsetof(Config,nopty)));
|
||||
ctrl_checkbox(s, "Don't start a shell or command at all", 'n',
|
||||
HELPCTX(ssh_noshell),
|
||||
dlg_stdcheckbox_handler,
|
||||
I(offsetof(Config,ssh_no_shell)));
|
||||
ctrl_checkbox(s, "Enable compression", 'e',
|
||||
HELPCTX(ssh_compress),
|
||||
dlg_stdcheckbox_handler,
|
||||
|
@ -1502,7 +1506,7 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
|
|||
"1 only", 'l', I(0),
|
||||
"1", '1', I(1),
|
||||
"2", '2', I(2),
|
||||
"2 only", 'n', I(3), NULL);
|
||||
"2 only", 'y', I(3), NULL);
|
||||
|
||||
s = ctrl_getset(b, "Connection/SSH", "encryption", "Encryption options");
|
||||
c = ctrl_draglist(s, "Encryption cipher selection policy:", 's',
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
\versionid $Id: config.but,v 1.92 2004/10/06 22:31:07 jacob Exp $
|
||||
\versionid $Id: config.but,v 1.93 2004/10/13 13:43:11 simon Exp $
|
||||
|
||||
\C{config} Configuring PuTTY
|
||||
|
||||
|
@ -1936,6 +1936,27 @@ in a pseudo-terminal. In PuTTY, this is generally only useful for
|
|||
very specialist purposes; although in Plink (see \k{plink}) it is
|
||||
the usual way of working.
|
||||
|
||||
\S{config-ssh-noshell} \q{Don't start a shell or command at all}
|
||||
|
||||
\cfg{winhelp-topic}{ssh.noshell}
|
||||
|
||||
If you tick this box, PuTTY will not attempt to run a shell or
|
||||
command after connecting to the remote server. You might want to use
|
||||
this option if you are only using the SSH connection for port
|
||||
forwarding, and your user account on the server does not have the
|
||||
ability to run a shell.
|
||||
|
||||
This feature is only available in SSH protocol version 2 (since the
|
||||
version 1 protocol assumes you will always want to run a shell).
|
||||
|
||||
This feature can also be enabled using the \c{-N} command-line
|
||||
option; see \k{using-cmdline-noshell}.
|
||||
|
||||
If you use this feature in Plink, you will not be able to terminate
|
||||
the Plink process by any graceful means; the only way to kill it
|
||||
will be by pressing Control-C or sending a kill signal from another
|
||||
program.
|
||||
|
||||
\S{config-ssh-comp} \q{Enable compression}
|
||||
|
||||
\cfg{winhelp-topic}{ssh.compress}
|
||||
|
|
|
@ -104,6 +104,7 @@ saved sessions from
|
|||
\IM{-T-upper} \c{-T} command-line option
|
||||
\IM{-t} \c{-t} command-line option
|
||||
\IM{-C-upper} \c{-C} command-line option
|
||||
\IM{-N-upper} \c{-N} command-line option
|
||||
\IM{-1} \c{-1} command-line option
|
||||
\IM{-2} \c{-2} command-line option
|
||||
\IM{-i} \c{-i} command-line option
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
\versionid $Id: using.but,v 1.33 2004/10/06 22:31:07 jacob Exp $
|
||||
\versionid $Id: using.but,v 1.34 2004/10/13 13:43:11 simon Exp $
|
||||
|
||||
\C{using} Using PuTTY
|
||||
|
||||
|
@ -694,6 +694,24 @@ configuration box (see \k{config-ssh-pty}).
|
|||
These options are not available in the file transfer tools PSCP and
|
||||
PSFTP.
|
||||
|
||||
\S2{using-cmdline-noshell} \I{-N-upper}\c{-N}: suppress starting a
|
||||
shell or command
|
||||
|
||||
The \c{-N} option prevents PuTTY from attempting to start a shell or
|
||||
command on the remote server. You might want to use this option if
|
||||
you are only using the SSH connection for port forwarding, and your
|
||||
user account on the server does not have the ability to run a shell.
|
||||
|
||||
This feature is only available in SSH protocol version 2 (since the
|
||||
version 1 protocol assumes you will always want to run a shell).
|
||||
|
||||
This option is equivalent to the \q{Don't start a shell or command
|
||||
at all} checkbox in the SSH panel of the PuTTY configuration box
|
||||
(see \k{config-ssh-noshell}).
|
||||
|
||||
These options are not available in the file transfer tools PSCP and
|
||||
PSFTP.
|
||||
|
||||
\S2{using-cmdline-compress} \I{-C-upper}\c{-C}: enable \i{compression}
|
||||
|
||||
The \c{-C} option enables compression of the data sent across the
|
||||
|
|
1
putty.h
1
putty.h
|
@ -358,6 +358,7 @@ struct config_tag {
|
|||
int try_ki_auth;
|
||||
int ssh_subsys; /* run a subsystem rather than a command */
|
||||
int ssh_subsys2; /* fallback to go with remote_cmd2 */
|
||||
int ssh_no_shell; /* avoid running a shell */
|
||||
/* Telnet options */
|
||||
char termtype[32];
|
||||
char termspeed[32];
|
||||
|
|
|
@ -228,6 +228,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg)
|
|||
cfg->ssh_cipherlist);
|
||||
write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth);
|
||||
write_setting_i(sesskey, "AuthKI", cfg->try_ki_auth);
|
||||
write_setting_i(sesskey, "SshNoShell", cfg->ssh_no_shell);
|
||||
write_setting_i(sesskey, "SshProt", cfg->sshprot);
|
||||
write_setting_i(sesskey, "SSH2DES", cfg->ssh2_des_cbc);
|
||||
write_setting_filename(sesskey, "PublicKeyFile", cfg->keyfile);
|
||||
|
@ -490,6 +491,7 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg)
|
|||
gppi(sesskey, "SSH2DES", 0, &cfg->ssh2_des_cbc);
|
||||
gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth);
|
||||
gppi(sesskey, "AuthKI", 1, &cfg->try_ki_auth);
|
||||
gppi(sesskey, "SshNoShell", 0, &cfg->ssh_no_shell);
|
||||
gppfile(sesskey, "PublicKeyFile", &cfg->keyfile);
|
||||
gpps(sesskey, "RemoteCommand", "", cfg->remote_cmd,
|
||||
sizeof(cfg->remote_cmd));
|
||||
|
|
89
ssh.c
89
ssh.c
|
@ -5612,43 +5612,47 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
* point; there's no need to send SERVICE_REQUEST.
|
||||
*/
|
||||
|
||||
/*
|
||||
* So now create a channel with a session in it.
|
||||
*/
|
||||
ssh->channels = newtree234(ssh_channelcmp);
|
||||
ssh->mainchan = snew(struct ssh_channel);
|
||||
ssh->mainchan->ssh = ssh;
|
||||
ssh->mainchan->localid = alloc_channel_id(ssh);
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_OPEN);
|
||||
ssh2_pkt_addstring(ssh, "session");
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->localid);
|
||||
ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->v.v2.locwindow);/* our window size */
|
||||
ssh2_pkt_adduint32(ssh, 0x4000UL); /* our max pkt size */
|
||||
ssh2_pkt_send(ssh);
|
||||
crWaitUntilV(ispkt);
|
||||
if (ssh->pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
|
||||
bombout(("Server refused to open a session"));
|
||||
crStopV;
|
||||
/* FIXME: error data comes back in FAILURE packet */
|
||||
}
|
||||
if (ssh_pkt_getuint32(ssh) != ssh->mainchan->localid) {
|
||||
bombout(("Server's channel confirmation cited wrong channel"));
|
||||
crStopV;
|
||||
}
|
||||
ssh->mainchan->remoteid = ssh_pkt_getuint32(ssh);
|
||||
ssh->mainchan->type = CHAN_MAINSESSION;
|
||||
ssh->mainchan->closes = 0;
|
||||
ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(ssh);
|
||||
ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(ssh);
|
||||
bufchain_init(&ssh->mainchan->v.v2.outbuffer);
|
||||
add234(ssh->channels, ssh->mainchan);
|
||||
logevent("Opened channel for session");
|
||||
|
||||
/*
|
||||
* Create the main session channel.
|
||||
*/
|
||||
if (!ssh->cfg.ssh_no_shell) {
|
||||
ssh->mainchan = snew(struct ssh_channel);
|
||||
ssh->mainchan->ssh = ssh;
|
||||
ssh->mainchan->localid = alloc_channel_id(ssh);
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_OPEN);
|
||||
ssh2_pkt_addstring(ssh, "session");
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->localid);
|
||||
ssh->mainchan->v.v2.locwindow = OUR_V2_WINSIZE;
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->v.v2.locwindow);/* our window size */
|
||||
ssh2_pkt_adduint32(ssh, 0x4000UL); /* our max pkt size */
|
||||
ssh2_pkt_send(ssh);
|
||||
crWaitUntilV(ispkt);
|
||||
if (ssh->pktin.type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
|
||||
bombout(("Server refused to open a session"));
|
||||
crStopV;
|
||||
/* FIXME: error data comes back in FAILURE packet */
|
||||
}
|
||||
if (ssh_pkt_getuint32(ssh) != ssh->mainchan->localid) {
|
||||
bombout(("Server's channel confirmation cited wrong channel"));
|
||||
crStopV;
|
||||
}
|
||||
ssh->mainchan->remoteid = ssh_pkt_getuint32(ssh);
|
||||
ssh->mainchan->type = CHAN_MAINSESSION;
|
||||
ssh->mainchan->closes = 0;
|
||||
ssh->mainchan->v.v2.remwindow = ssh_pkt_getuint32(ssh);
|
||||
ssh->mainchan->v.v2.remmaxpkt = ssh_pkt_getuint32(ssh);
|
||||
bufchain_init(&ssh->mainchan->v.v2.outbuffer);
|
||||
add234(ssh->channels, ssh->mainchan);
|
||||
logevent("Opened channel for session");
|
||||
} else
|
||||
ssh->mainchan = NULL;
|
||||
|
||||
/*
|
||||
* Potentially enable X11 forwarding.
|
||||
*/
|
||||
if (ssh->cfg.x11_forward) {
|
||||
if (ssh->mainchan && ssh->cfg.x11_forward) {
|
||||
char proto[20], data[64];
|
||||
logevent("Requesting X11 forwarding");
|
||||
ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
|
||||
|
@ -5861,7 +5865,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
/*
|
||||
* Potentially enable agent forwarding.
|
||||
*/
|
||||
if (ssh->cfg.agentfwd && agent_exists()) {
|
||||
if (ssh->mainchan && ssh->cfg.agentfwd && agent_exists()) {
|
||||
logevent("Requesting OpenSSH-style agent forwarding");
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
|
||||
|
@ -5897,7 +5901,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
/*
|
||||
* Now allocate a pty for the session.
|
||||
*/
|
||||
if (!ssh->cfg.nopty) {
|
||||
if (ssh->mainchan && !ssh->cfg.nopty) {
|
||||
/* Unpick the terminal-speed string. */
|
||||
/* XXX perhaps we should allow no speeds to be sent. */
|
||||
ssh->ospeed = 38400; ssh->ispeed = 38400; /* last-resort defaults */
|
||||
|
@ -5954,7 +5958,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
* this twice if the config data has provided a second choice
|
||||
* of command.
|
||||
*/
|
||||
while (1) {
|
||||
if (ssh->mainchan) while (1) {
|
||||
int subsys;
|
||||
char *cmd;
|
||||
|
||||
|
@ -6028,7 +6032,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
*/
|
||||
if (ssh->ldisc)
|
||||
ldisc_send(ssh->ldisc, NULL, 0, 0);/* cause ldisc to notice changes */
|
||||
ssh->send_ok = 1;
|
||||
if (ssh->mainchan)
|
||||
ssh->send_ok = 1;
|
||||
while (1) {
|
||||
crReturnV;
|
||||
s->try_send = FALSE;
|
||||
|
@ -6171,8 +6176,10 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
|
||||
/*
|
||||
* See if that was the last channel left open.
|
||||
* (This is only our termination condition if we're
|
||||
* not running in -N mode.)
|
||||
*/
|
||||
if (count234(ssh->channels) == 0) {
|
||||
if (!ssh->cfg.ssh_no_shell && count234(ssh->channels) == 0) {
|
||||
logevent("All channels closed. Disconnecting");
|
||||
#if 0
|
||||
/*
|
||||
|
@ -6452,7 +6459,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
|
|||
bombout(("Strange packet received: type %d", ssh->pktin.type));
|
||||
crStopV;
|
||||
}
|
||||
} else {
|
||||
} else if (ssh->mainchan) {
|
||||
/*
|
||||
* We have spare data. Add it to the channel buffer.
|
||||
*/
|
||||
|
@ -6772,7 +6779,7 @@ static void ssh_size(void *handle, int width, int height)
|
|||
PKT_INT, ssh->term_height,
|
||||
PKT_INT, ssh->term_width,
|
||||
PKT_INT, 0, PKT_INT, 0, PKT_END);
|
||||
} else {
|
||||
} else if (ssh->mainchan) {
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
|
||||
ssh2_pkt_addstring(ssh, "window-change");
|
||||
|
@ -6834,7 +6841,7 @@ static void ssh_special(void *handle, Telnet_Special code)
|
|||
}
|
||||
if (ssh->version == 1) {
|
||||
send_packet(ssh, SSH1_CMSG_EOF, PKT_END);
|
||||
} else {
|
||||
} else if (ssh->mainchan) {
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_EOF);
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
|
||||
ssh2_pkt_send(ssh);
|
||||
|
@ -6856,7 +6863,7 @@ static void ssh_special(void *handle, Telnet_Special code)
|
|||
|| ssh->state == SSH_STATE_PREPACKET) return;
|
||||
if (ssh->version == 1) {
|
||||
logevent("Unable to send BREAK signal in SSH1");
|
||||
} else {
|
||||
} else if (ssh->mainchan) {
|
||||
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
|
||||
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
|
||||
ssh2_pkt_addstring(ssh, "break");
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
#define WINHELP_CTX_telnet_newline "telnet.newline"
|
||||
#define WINHELP_CTX_rlogin_localuser "rlogin.localuser"
|
||||
#define WINHELP_CTX_ssh_nopty "ssh.nopty"
|
||||
#define WINHELP_CTX_ssh_noshell "ssh.noshell"
|
||||
#define WINHELP_CTX_ssh_ciphers "ssh.ciphers"
|
||||
#define WINHELP_CTX_ssh_protocol "ssh.protocol"
|
||||
#define WINHELP_CTX_ssh_command "ssh.command"
|
||||
|
|
Загрузка…
Ссылка в новой задаче