-\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
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}
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);
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));
* point; there's no need to send SERVICE_REQUEST.
*/
+ ssh->channels = newtree234(ssh_channelcmp);
+
/*
- * So now create a channel with a session in it.
+ * Create the main session channel.
*/
- 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");
+ 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),
/*
* 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);
/*
* 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 */
* this twice if the config data has provided a second choice
* of command.
*/
- while (1) {
+ if (ssh->mainchan) while (1) {
int subsys;
char *cmd;
*/
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;
/*
* 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
/*
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.
*/
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");
}
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);
|| 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");