1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-10 01:48:00 +00:00

The back ends now contain their own copies of the Config structure,

and have a function to pass in a new one. (Well, actually several
back ends don't actually bother to do this because they need nothing
out of Config after the initial setup phase, but they could if they
wanted to.)

[originally from svn r2561]
This commit is contained in:
Simon Tatham 2003-01-12 14:48:29 +00:00
parent cf2bcad348
commit f49c8c5a07
12 changed files with 190 additions and 114 deletions

View File

@ -539,7 +539,7 @@ int main(int argc, char **argv)
int nodelay = cfg.tcp_nodelay && int nodelay = cfg.tcp_nodelay &&
(GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR); (GetFileType(GetStdHandle(STD_INPUT_HANDLE)) == FILE_TYPE_CHAR);
error = back->init(NULL, &backhandle, cfg.host, cfg.port, error = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port,
&realhost, nodelay); &realhost, nodelay);
if (error) { if (error) {
fprintf(stderr, "Unable to open connection:\n%s", error); fprintf(stderr, "Unable to open connection:\n%s", error);

View File

@ -1828,7 +1828,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
back = &ssh_backend; back = &ssh_backend;
err = back->init(NULL, &backhandle, cfg.host, cfg.port, &realhost, 0); err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
if (err != NULL) { if (err != NULL) {
fprintf(stderr, "ssh_init: %s\n", err); fprintf(stderr, "ssh_init: %s\n", err);
return 1; return 1;

View File

@ -184,8 +184,10 @@ enum {
}; };
struct backend_tag { struct backend_tag {
char *(*init) (void *frontend_handle, void **backend_handle, char *(*init) (void *frontend_handle, void **backend_handle, Config *cfg,
char *host, int port, char **realhost, int nodelay); char *host, int port, char **realhost, int nodelay);
/* back->reconfig() passes in a replacement configuration. */
void (*reconfig) (void *handle, Config *cfg);
/* back->send() returns the current amount of buffered data. */ /* back->send() returns the current amount of buffered data. */
int (*send) (void *handle, char *buf, int len); int (*send) (void *handle, char *buf, int len);
/* back->sendbuffer() does the same thing but without attempting a send */ /* back->sendbuffer() does the same thing but without attempting a send */

9
raw.c
View File

@ -68,6 +68,7 @@ static void raw_sent(Plug plug, int bufsize)
* freed by the caller. * freed by the caller.
*/ */
static char *raw_init(void *frontend_handle, void **backend_handle, static char *raw_init(void *frontend_handle, void **backend_handle,
Config *cfg,
char *host, int port, char **realhost, int nodelay) char *host, int port, char **realhost, int nodelay)
{ {
static const struct plug_function_table fn_table = { static const struct plug_function_table fn_table = {
@ -121,6 +122,13 @@ static char *raw_init(void *frontend_handle, void **backend_handle,
return NULL; return NULL;
} }
/*
* Stub routine (we don't have any need to reconfigure this backend).
*/
static void raw_reconfig(void *handle, Config *cfg)
{
}
/* /*
* Called to send data down the raw connection. * Called to send data down the raw connection.
*/ */
@ -205,6 +213,7 @@ static int raw_exitcode(void *handle)
Backend raw_backend = { Backend raw_backend = {
raw_init, raw_init,
raw_reconfig,
raw_send, raw_send,
raw_sendbuffer, raw_sendbuffer,
raw_size, raw_size,

View File

@ -98,6 +98,7 @@ static void rlogin_sent(Plug plug, int bufsize)
* freed by the caller. * freed by the caller.
*/ */
static char *rlogin_init(void *frontend_handle, void **backend_handle, static char *rlogin_init(void *frontend_handle, void **backend_handle,
Config *cfg,
char *host, int port, char **realhost, int nodelay) char *host, int port, char **realhost, int nodelay)
{ {
static const struct plug_function_table fn_table = { static const struct plug_function_table fn_table = {
@ -113,8 +114,8 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle,
rlogin->fn = &fn_table; rlogin->fn = &fn_table;
rlogin->s = NULL; rlogin->s = NULL;
rlogin->frontend = frontend_handle; rlogin->frontend = frontend_handle;
rlogin->term_width = cfg.width; rlogin->term_width = cfg->width;
rlogin->term_height = cfg.height; rlogin->term_height = cfg->height;
*backend_handle = rlogin; *backend_handle = rlogin;
/* /*
@ -158,20 +159,30 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle,
char z = 0; char z = 0;
char *p; char *p;
sk_write(rlogin->s, &z, 1); sk_write(rlogin->s, &z, 1);
sk_write(rlogin->s, cfg.localusername, strlen(cfg.localusername)); sk_write(rlogin->s, cfg->localusername,
strlen(cfg->localusername));
sk_write(rlogin->s, &z, 1); sk_write(rlogin->s, &z, 1);
sk_write(rlogin->s, cfg.username, strlen(cfg.username)); sk_write(rlogin->s, cfg->username,
strlen(cfg->username));
sk_write(rlogin->s, &z, 1); sk_write(rlogin->s, &z, 1);
sk_write(rlogin->s, cfg.termtype, strlen(cfg.termtype)); sk_write(rlogin->s, cfg->termtype,
strlen(cfg->termtype));
sk_write(rlogin->s, "/", 1); sk_write(rlogin->s, "/", 1);
for (p = cfg.termspeed; isdigit(*p); p++) continue; for (p = cfg->termspeed; isdigit(*p); p++) continue;
sk_write(rlogin->s, cfg.termspeed, p - cfg.termspeed); sk_write(rlogin->s, cfg->termspeed, p - cfg->termspeed);
rlogin->bufsize = sk_write(rlogin->s, &z, 1); rlogin->bufsize = sk_write(rlogin->s, &z, 1);
} }
return NULL; return NULL;
} }
/*
* Stub routine (we don't have any need to reconfigure this backend).
*/
static void rlogin_reconfig(void *handle, Config *cfg)
{
}
/* /*
* Called to send data down the rlogin connection. * Called to send data down the rlogin connection.
*/ */
@ -270,6 +281,7 @@ static int rlogin_exitcode(void *handle)
Backend rlogin_backend = { Backend rlogin_backend = {
rlogin_init, rlogin_init,
rlogin_reconfig,
rlogin_send, rlogin_send,
rlogin_sendbuffer, rlogin_sendbuffer,
rlogin_size, rlogin_size,

2
scp.c
View File

@ -574,7 +574,7 @@ static void do_cmd(char *host, char *user, char *cmd)
back = &ssh_backend; back = &ssh_backend;
err = back->init(NULL, &backhandle, cfg.host, cfg.port, &realhost, 0); err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,0);
if (err != NULL) if (err != NULL)
bump("ssh_init: %s", err); bump("ssh_init: %s", err);
logctx = log_init(NULL); logctx = log_init(NULL);

180
ssh.c
View File

@ -620,6 +620,14 @@ struct ssh_tag {
void (*protocol) (Ssh ssh, unsigned char *in, int inlen, int ispkt); void (*protocol) (Ssh ssh, unsigned char *in, int inlen, int ispkt);
int (*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen); int (*s_rdpkt) (Ssh ssh, unsigned char **data, int *datalen);
/*
* We maintain a full _copy_ of a Config structure here, not
* merely a pointer to it. That way, when we're passed a new
* one for reconfiguration, we can check the differences and
* potentially reconfigure port forwardings etc in mid-session.
*/
Config cfg;
}; };
#define logevent(s) logevent(ssh->frontend, s) #define logevent(s) logevent(ssh->frontend, s)
@ -1711,8 +1719,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
ssh->remote_bugs = 0; ssh->remote_bugs = 0;
if (cfg.sshbug_ignore1 == BUG_ON || if (ssh->cfg.sshbug_ignore1 == BUG_ON ||
(cfg.sshbug_ignore1 == BUG_AUTO && (ssh->cfg.sshbug_ignore1 == BUG_AUTO &&
(!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") || (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
!strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") || !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
!strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")))) { !strcmp(imp, "1.2.22") || !strcmp(imp, "Cisco-1.25")))) {
@ -1725,8 +1733,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version has SSH1 ignore bug"); logevent("We believe remote version has SSH1 ignore bug");
} }
if (cfg.sshbug_plainpw1 == BUG_ON || if (ssh->cfg.sshbug_plainpw1 == BUG_ON ||
(cfg.sshbug_plainpw1 == BUG_AUTO && (ssh->cfg.sshbug_plainpw1 == BUG_AUTO &&
(!strcmp(imp, "Cisco-1.25")))) { (!strcmp(imp, "Cisco-1.25")))) {
/* /*
* These versions need a plain password sent; they can't * These versions need a plain password sent; they can't
@ -1737,8 +1745,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version needs a plain SSH1 password"); logevent("We believe remote version needs a plain SSH1 password");
} }
if (cfg.sshbug_rsa1 == BUG_ON || if (ssh->cfg.sshbug_rsa1 == BUG_ON ||
(cfg.sshbug_rsa1 == BUG_AUTO && (ssh->cfg.sshbug_rsa1 == BUG_AUTO &&
(!strcmp(imp, "Cisco-1.25")))) { (!strcmp(imp, "Cisco-1.25")))) {
/* /*
* These versions apparently have no clue whatever about * These versions apparently have no clue whatever about
@ -1749,8 +1757,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version can't handle RSA authentication"); logevent("We believe remote version can't handle RSA authentication");
} }
if (cfg.sshbug_hmac2 == BUG_ON || if (ssh->cfg.sshbug_hmac2 == BUG_ON ||
(cfg.sshbug_hmac2 == BUG_AUTO && (ssh->cfg.sshbug_hmac2 == BUG_AUTO &&
(wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) || (wc_match("2.1.0*", imp) || wc_match("2.0.*", imp) ||
wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) || wc_match("2.2.0*", imp) || wc_match("2.3.0*", imp) ||
wc_match("2.1 *", imp)))) { wc_match("2.1 *", imp)))) {
@ -1761,8 +1769,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version has SSH2 HMAC bug"); logevent("We believe remote version has SSH2 HMAC bug");
} }
if (cfg.sshbug_derivekey2 == BUG_ON || if (ssh->cfg.sshbug_derivekey2 == BUG_ON ||
(cfg.sshbug_derivekey2 == BUG_AUTO && (ssh->cfg.sshbug_derivekey2 == BUG_AUTO &&
(wc_match("2.0.0*", imp) || wc_match("2.0.1[01]*", imp) ))) { (wc_match("2.0.0*", imp) || wc_match("2.0.1[01]*", imp) ))) {
/* /*
* These versions have the key-derivation bug (failing to * These versions have the key-derivation bug (failing to
@ -1773,8 +1781,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version has SSH2 key-derivation bug"); logevent("We believe remote version has SSH2 key-derivation bug");
} }
if (cfg.sshbug_rsapad2 == BUG_ON || if (ssh->cfg.sshbug_rsapad2 == BUG_ON ||
(cfg.sshbug_rsapad2 == BUG_AUTO && (ssh->cfg.sshbug_rsapad2 == BUG_AUTO &&
(wc_match("OpenSSH_2.[5-9]*", imp) || (wc_match("OpenSSH_2.[5-9]*", imp) ||
wc_match("OpenSSH_3.[0-2]*", imp)))) { wc_match("OpenSSH_3.[0-2]*", imp)))) {
/* /*
@ -1784,7 +1792,7 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
logevent("We believe remote version has SSH2 RSA padding bug"); logevent("We believe remote version has SSH2 RSA padding bug");
} }
if (cfg.sshbug_dhgex2 == BUG_ON) { if (ssh->cfg.sshbug_dhgex2 == BUG_ON) {
/* /*
* User specified the SSH2 DH GEX bug. * User specified the SSH2 DH GEX bug.
*/ */
@ -1871,16 +1879,16 @@ static int do_ssh_init(Ssh ssh, unsigned char c)
/* Anything greater or equal to "1.99" means protocol 2 is supported. */ /* Anything greater or equal to "1.99" means protocol 2 is supported. */
s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0; s->proto2 = ssh_versioncmp(s->version, "1.99") >= 0;
if (cfg.sshprot == 0 && !s->proto1) { if (ssh->cfg.sshprot == 0 && !s->proto1) {
bombout((ssh,"SSH protocol version 1 required by user but not provided by server")); bombout((ssh,"SSH protocol version 1 required by user but not provided by server"));
crReturn(0); crReturn(0);
} }
if (cfg.sshprot == 3 && !s->proto2) { if (ssh->cfg.sshprot == 3 && !s->proto2) {
bombout((ssh,"SSH protocol version 2 required by user but not provided by server")); bombout((ssh,"SSH protocol version 2 required by user but not provided by server"));
crReturn(0); crReturn(0);
} }
if (s->proto2 && (cfg.sshprot >= 2 || !s->proto1)) { if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1)) {
/* /*
* Use v2 protocol. * Use v2 protocol.
*/ */
@ -2315,7 +2323,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
char *cipher_string = NULL; char *cipher_string = NULL;
int i; int i;
for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) { for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
int next_cipher = cfg.ssh_cipherlist[i]; int next_cipher = ssh->cfg.ssh_cipherlist[i];
if (next_cipher == CIPHER_WARN) { if (next_cipher == CIPHER_WARN) {
/* If/when we choose a cipher, warn about it */ /* If/when we choose a cipher, warn about it */
warn = 1; warn = 1;
@ -2394,7 +2402,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
fflush(stdout); fflush(stdout);
{ {
if ((flags & FLAG_INTERACTIVE) && !*cfg.username) { if ((flags & FLAG_INTERACTIVE) && !*ssh->cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) { if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ", if (!ssh_get_line("login as: ",
s->username, sizeof(s->username), FALSE)) { s->username, sizeof(s->username), FALSE)) {
@ -2421,7 +2429,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
c_write_str(ssh, "\r\n"); c_write_str(ssh, "\r\n");
} }
} else { } else {
strncpy(s->username, cfg.username, sizeof(s->username)); strncpy(s->username, ssh->cfg.username, sizeof(s->username));
s->username[sizeof(s->username)-1] = '\0'; s->username[sizeof(s->username)-1] = '\0';
} }
@ -2447,9 +2455,9 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->tried_publickey = s->tried_agent = 0; s->tried_publickey = s->tried_agent = 0;
} }
s->tis_auth_refused = s->ccard_auth_refused = 0; s->tis_auth_refused = s->ccard_auth_refused = 0;
/* Load the public half of cfg.keyfile so we notice if it's in Pageant */ /* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */
if (*cfg.keyfile) { if (*ssh->cfg.keyfile) {
if (!rsakey_pubblob(cfg.keyfile, if (!rsakey_pubblob(ssh->cfg.keyfile,
&s->publickey_blob, &s->publickey_bloblen)) &s->publickey_blob, &s->publickey_bloblen))
s->publickey_blob = NULL; s->publickey_blob = NULL;
} else } else
@ -2577,10 +2585,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
if (s->authed) if (s->authed)
break; break;
} }
if (*cfg.keyfile && !s->tried_publickey) if (*ssh->cfg.keyfile && !s->tried_publickey)
s->pwpkt_type = SSH1_CMSG_AUTH_RSA; s->pwpkt_type = SSH1_CMSG_AUTH_RSA;
if (cfg.try_tis_auth && if (ssh->cfg.try_tis_auth &&
(s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) && (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
!s->tis_auth_refused) { !s->tis_auth_refused) {
s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE; s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
@ -2607,7 +2615,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->prompt[(sizeof s->prompt) - 1] = '\0'; s->prompt[(sizeof s->prompt) - 1] = '\0';
} }
} }
if (cfg.try_tis_auth && if (ssh->cfg.try_tis_auth &&
(s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) && (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
!s->ccard_auth_refused) { !s->ccard_auth_refused) {
s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE; s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
@ -2642,8 +2650,8 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
char msgbuf[256]; char msgbuf[256];
if (flags & FLAG_VERBOSE) if (flags & FLAG_VERBOSE)
c_write_str(ssh, "Trying public key authentication.\r\n"); c_write_str(ssh, "Trying public key authentication.\r\n");
logeventf(ssh, "Trying public key \"%s\"", cfg.keyfile); logeventf(ssh, "Trying public key \"%s\"", ssh->cfg.keyfile);
type = key_type(cfg.keyfile); type = key_type(ssh->cfg.keyfile);
if (type != SSH_KEYTYPE_SSH1) { if (type != SSH_KEYTYPE_SSH1) {
sprintf(msgbuf, "Key is of wrong type (%s)", sprintf(msgbuf, "Key is of wrong type (%s)",
key_type_to_str(type)); key_type_to_str(type));
@ -2653,7 +2661,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->tried_publickey = 1; s->tried_publickey = 1;
continue; continue;
} }
if (!rsakey_encrypted(cfg.keyfile, &comment)) { if (!rsakey_encrypted(ssh->cfg.keyfile, &comment)) {
if (flags & FLAG_VERBOSE) if (flags & FLAG_VERBOSE)
c_write_str(ssh, "No passphrase required.\r\n"); c_write_str(ssh, "No passphrase required.\r\n");
goto tryauth; goto tryauth;
@ -2709,10 +2717,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->tried_publickey = 1; s->tried_publickey = 1;
{ {
int ret = loadrsakey(cfg.keyfile, &s->key, s->password); int ret = loadrsakey(ssh->cfg.keyfile, &s->key, s->password);
if (ret == 0) { if (ret == 0) {
c_write_str(ssh, "Couldn't load private key from "); c_write_str(ssh, "Couldn't load private key from ");
c_write_str(ssh, cfg.keyfile); c_write_str(ssh, ssh->cfg.keyfile);
c_write_str(ssh, ".\r\n"); c_write_str(ssh, ".\r\n");
continue; /* go and try password */ continue; /* go and try password */
} }
@ -2996,7 +3004,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
if (ssh->state == SSH_STATE_CLOSED) if (ssh->state == SSH_STATE_CLOSED)
crReturnV; crReturnV;
if (cfg.agentfwd && agent_exists()) { if (ssh->cfg.agentfwd && agent_exists()) {
logevent("Requesting agent forwarding"); logevent("Requesting agent forwarding");
send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END); send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
do { do {
@ -3014,16 +3022,16 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
} }
} }
if (cfg.x11_forward) { if (ssh->cfg.x11_forward) {
char proto[20], data[64]; char proto[20], data[64];
logevent("Requesting X11 forwarding"); logevent("Requesting X11 forwarding");
ssh->x11auth = x11_invent_auth(proto, sizeof(proto), ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
data, sizeof(data), cfg.x11_auth); data, sizeof(data), ssh->cfg.x11_auth);
x11_get_real_auth(ssh->x11auth, cfg.x11_display); x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) { if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING, send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
PKT_STR, proto, PKT_STR, data, PKT_STR, proto, PKT_STR, data,
PKT_INT, x11_get_screen_number(cfg.x11_display), PKT_INT, x11_get_screen_number(ssh->cfg.x11_display),
PKT_END); PKT_END);
} else { } else {
send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING, send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
@ -3052,7 +3060,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh->rportfwds = newtree234(ssh_rportcmp_ssh1); ssh->rportfwds = newtree234(ssh_rportcmp_ssh1);
/* Add port forwardings. */ /* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd; ssh->portfwd_strptr = ssh->cfg.portfwd;
while (*ssh->portfwd_strptr) { while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++; type = *ssh->portfwd_strptr++;
saddr[0] = '\0'; saddr[0] = '\0';
@ -3169,9 +3177,9 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
} }
} }
if (!cfg.nopty) { if (!ssh->cfg.nopty) {
send_packet(ssh, SSH1_CMSG_REQUEST_PTY, send_packet(ssh, SSH1_CMSG_REQUEST_PTY,
PKT_STR, cfg.termtype, PKT_STR, ssh->cfg.termtype,
PKT_INT, ssh->term_height, PKT_INT, ssh->term_height,
PKT_INT, ssh->term_width, PKT_INT, ssh->term_width,
PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END); PKT_INT, 0, PKT_INT, 0, PKT_CHAR, 0, PKT_END);
@ -3192,7 +3200,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh->editing = ssh->echoing = 1; ssh->editing = ssh->echoing = 1;
} }
if (cfg.compression) { if (ssh->cfg.compression) {
send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END); send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
do { do {
crReturnV; crReturnV;
@ -3220,10 +3228,10 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
* exists, we fall straight back to that. * exists, we fall straight back to that.
*/ */
{ {
char *cmd = cfg.remote_cmd_ptr; char *cmd = ssh->cfg.remote_cmd_ptr;
if (cfg.ssh_subsys && cfg.remote_cmd_ptr2) { if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
cmd = cfg.remote_cmd_ptr2; cmd = ssh->cfg.remote_cmd_ptr2;
ssh->fallback_cmd = TRUE; ssh->fallback_cmd = TRUE;
} }
if (*cmd) if (*cmd)
@ -3276,7 +3284,7 @@ static void ssh1_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
c = smalloc(sizeof(struct ssh_channel)); c = smalloc(sizeof(struct ssh_channel));
c->ssh = ssh; c->ssh = ssh;
if (x11_init(&c->u.x11.s, cfg.x11_display, c, if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
ssh->x11auth, NULL, -1) != NULL) { ssh->x11auth, NULL, -1) != NULL) {
logevent("opening X11 forward connection failed"); logevent("opening X11 forward connection failed");
sfree(c); sfree(c);
@ -3669,12 +3677,12 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt)
*/ */
s->n_preferred_ciphers = 0; s->n_preferred_ciphers = 0;
for (i = 0; i < CIPHER_MAX; i++) { for (i = 0; i < CIPHER_MAX; i++) {
switch (cfg.ssh_cipherlist[i]) { switch (ssh->cfg.ssh_cipherlist[i]) {
case CIPHER_BLOWFISH: case CIPHER_BLOWFISH:
s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish; s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
break; break;
case CIPHER_DES: case CIPHER_DES:
if (cfg.ssh2_des_cbc) { if (ssh->cfg.ssh2_des_cbc) {
s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des; s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
} }
break; break;
@ -3698,7 +3706,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/* /*
* Set up preferred compression. * Set up preferred compression.
*/ */
if (cfg.compression) if (ssh->cfg.compression)
s->preferred_comp = &ssh_zlib; s->preferred_comp = &ssh_zlib;
else else
s->preferred_comp = &ssh_comp_none; s->preferred_comp = &ssh_comp_none;
@ -4313,13 +4321,13 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/* /*
* Get a username. * Get a username.
*/ */
if (s->got_username && !cfg.change_username) { if (s->got_username && !ssh->cfg.change_username) {
/* /*
* We got a username last time round this loop, and * We got a username last time round this loop, and
* with change_username turned off we don't try to get * with change_username turned off we don't try to get
* it again. * it again.
*/ */
} else if ((flags & FLAG_INTERACTIVE) && !*cfg.username) { } else if ((flags & FLAG_INTERACTIVE) && !*ssh->cfg.username) {
if (ssh_get_line && !ssh_getline_pw_only) { if (ssh_get_line && !ssh_getline_pw_only) {
if (!ssh_get_line("login as: ", if (!ssh_get_line("login as: ",
s->username, sizeof(s->username), FALSE)) { s->username, sizeof(s->username), FALSE)) {
@ -4347,7 +4355,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->username[strcspn(s->username, "\n\r")] = '\0'; s->username[strcspn(s->username, "\n\r")] = '\0';
} else { } else {
char *stuff; char *stuff;
strncpy(s->username, cfg.username, sizeof(s->username)); strncpy(s->username, ssh->cfg.username, sizeof(s->username));
s->username[sizeof(s->username)-1] = '\0'; s->username[sizeof(s->username)-1] = '\0';
if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) { if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
stuff = dupprintf("Using username \"%s\".\r\n", s->username); stuff = dupprintf("Using username \"%s\".\r\n", s->username);
@ -4377,21 +4385,21 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
s->tried_agent = FALSE; s->tried_agent = FALSE;
s->tried_keyb_inter = FALSE; s->tried_keyb_inter = FALSE;
s->kbd_inter_running = FALSE; s->kbd_inter_running = FALSE;
/* Load the pub half of cfg.keyfile so we notice if it's in Pageant */ /* Load the pub half of ssh->cfg.keyfile so we notice if it's in Pageant */
if (*cfg.keyfile) { if (*ssh->cfg.keyfile) {
int keytype; int keytype;
logeventf(ssh, "Reading private key file \"%.150s\"", cfg.keyfile); logeventf(ssh, "Reading private key file \"%.150s\"", ssh->cfg.keyfile);
keytype = key_type(cfg.keyfile); keytype = key_type(ssh->cfg.keyfile);
if (keytype == SSH_KEYTYPE_SSH2) { if (keytype == SSH_KEYTYPE_SSH2) {
s->publickey_blob = s->publickey_blob =
ssh2_userkey_loadpub(cfg.keyfile, NULL, ssh2_userkey_loadpub(ssh->cfg.keyfile, NULL,
&s->publickey_bloblen); &s->publickey_bloblen);
} else { } else {
char *msgbuf; char *msgbuf;
logeventf(ssh, "Unable to use this key file (%s)", logeventf(ssh, "Unable to use this key file (%s)",
key_type_to_str(keytype)); key_type_to_str(keytype));
msgbuf = dupprintf("Unable to use key file \"%.150s\"" msgbuf = dupprintf("Unable to use key file \"%.150s\""
" (%s)\r\n", cfg.keyfile, " (%s)\r\n", ssh->cfg.keyfile,
key_type_to_str(keytype)); key_type_to_str(keytype));
c_write_str(ssh, msgbuf); c_write_str(ssh, msgbuf);
sfree(msgbuf); sfree(msgbuf);
@ -4507,7 +4515,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
in_commasep_string("publickey", methods, methlen); in_commasep_string("publickey", methods, methlen);
s->can_passwd = s->can_passwd =
in_commasep_string("password", methods, methlen); in_commasep_string("password", methods, methlen);
s->can_keyb_inter = cfg.try_ki_auth && s->can_keyb_inter = ssh->cfg.try_ki_auth &&
in_commasep_string("keyboard-interactive", methods, methlen); in_commasep_string("keyboard-interactive", methods, methlen);
} }
@ -4682,7 +4690,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
* willing to accept it. * willing to accept it.
*/ */
pub_blob = pub_blob =
(unsigned char *)ssh2_userkey_loadpub(cfg.keyfile, (unsigned char *)ssh2_userkey_loadpub(ssh->cfg.keyfile,
&algorithm, &algorithm,
&pub_blob_len); &pub_blob_len);
if (pub_blob) { if (pub_blob) {
@ -4710,7 +4718,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
* Actually attempt a serious authentication using * Actually attempt a serious authentication using
* the key. * the key.
*/ */
if (ssh2_userkey_encrypted(cfg.keyfile, &comment)) { if (ssh2_userkey_encrypted(ssh->cfg.keyfile, &comment)) {
sprintf(s->pwprompt, sprintf(s->pwprompt,
"Passphrase for key \"%.100s\": ", "Passphrase for key \"%.100s\": ",
comment); comment);
@ -4862,7 +4870,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
*/ */
struct ssh2_userkey *key; struct ssh2_userkey *key;
key = ssh2_load_userkey(cfg.keyfile, s->password); key = ssh2_load_userkey(ssh->cfg.keyfile, s->password);
if (key == SSH2_WRONG_PASSPHRASE || key == NULL) { if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
if (key == SSH2_WRONG_PASSPHRASE) { if (key == SSH2_WRONG_PASSPHRASE) {
c_write_str(ssh, "Wrong passphrase\r\n"); c_write_str(ssh, "Wrong passphrase\r\n");
@ -5064,12 +5072,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/* /*
* Potentially enable X11 forwarding. * Potentially enable X11 forwarding.
*/ */
if (cfg.x11_forward) { if (ssh->cfg.x11_forward) {
char proto[20], data[64]; char proto[20], data[64];
logevent("Requesting X11 forwarding"); logevent("Requesting X11 forwarding");
ssh->x11auth = x11_invent_auth(proto, sizeof(proto), ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
data, sizeof(data), cfg.x11_auth); data, sizeof(data), ssh->cfg.x11_auth);
x11_get_real_auth(ssh->x11auth, cfg.x11_display); x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid); ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
ssh2_pkt_addstring(ssh, "x11-req"); ssh2_pkt_addstring(ssh, "x11-req");
@ -5077,7 +5085,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh2_pkt_addbool(ssh, 0); /* many connections */ ssh2_pkt_addbool(ssh, 0); /* many connections */
ssh2_pkt_addstring(ssh, proto); ssh2_pkt_addstring(ssh, proto);
ssh2_pkt_addstring(ssh, data); ssh2_pkt_addstring(ssh, data);
ssh2_pkt_adduint32(ssh, x11_get_screen_number(cfg.x11_display)); ssh2_pkt_adduint32(ssh, x11_get_screen_number(ssh->cfg.x11_display));
ssh2_pkt_send(ssh); ssh2_pkt_send(ssh);
do { do {
@ -5116,7 +5124,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh->rportfwds = newtree234(ssh_rportcmp_ssh2); ssh->rportfwds = newtree234(ssh_rportcmp_ssh2);
/* Add port forwardings. */ /* Add port forwardings. */
ssh->portfwd_strptr = cfg.portfwd; ssh->portfwd_strptr = ssh->cfg.portfwd;
while (*ssh->portfwd_strptr) { while (*ssh->portfwd_strptr) {
type = *ssh->portfwd_strptr++; type = *ssh->portfwd_strptr++;
saddr[0] = '\0'; saddr[0] = '\0';
@ -5214,7 +5222,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
ssh2_pkt_addbool(ssh, 1);/* want reply */ ssh2_pkt_addbool(ssh, 1);/* want reply */
if (*saddr) if (*saddr)
ssh2_pkt_addstring(ssh, saddr); ssh2_pkt_addstring(ssh, saddr);
if (cfg.rport_acceptall) if (ssh->cfg.rport_acceptall)
ssh2_pkt_addstring(ssh, "0.0.0.0"); ssh2_pkt_addstring(ssh, "0.0.0.0");
else else
ssh2_pkt_addstring(ssh, "127.0.0.1"); ssh2_pkt_addstring(ssh, "127.0.0.1");
@ -5253,7 +5261,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/* /*
* Potentially enable agent forwarding. * Potentially enable agent forwarding.
*/ */
if (cfg.agentfwd && agent_exists()) { if (ssh->cfg.agentfwd && agent_exists()) {
logevent("Requesting OpenSSH-style agent forwarding"); logevent("Requesting OpenSSH-style agent forwarding");
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid); ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
@ -5289,12 +5297,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
/* /*
* Now allocate a pty for the session. * Now allocate a pty for the session.
*/ */
if (!cfg.nopty) { if (!ssh->cfg.nopty) {
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid); /* recipient channel */ ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid); /* recipient channel */
ssh2_pkt_addstring(ssh, "pty-req"); ssh2_pkt_addstring(ssh, "pty-req");
ssh2_pkt_addbool(ssh, 1); /* want reply */ ssh2_pkt_addbool(ssh, 1); /* want reply */
ssh2_pkt_addstring(ssh, cfg.termtype); ssh2_pkt_addstring(ssh, ssh->cfg.termtype);
ssh2_pkt_adduint32(ssh, ssh->term_width); ssh2_pkt_adduint32(ssh, ssh->term_width);
ssh2_pkt_adduint32(ssh, ssh->term_height); ssh2_pkt_adduint32(ssh, ssh->term_height);
ssh2_pkt_adduint32(ssh, 0); /* pixel width */ ssh2_pkt_adduint32(ssh, 0); /* pixel width */
@ -5341,11 +5349,11 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
char *cmd; char *cmd;
if (ssh->fallback_cmd) { if (ssh->fallback_cmd) {
subsys = cfg.ssh_subsys2; subsys = ssh->cfg.ssh_subsys2;
cmd = cfg.remote_cmd_ptr2; cmd = ssh->cfg.remote_cmd_ptr2;
} else { } else {
subsys = cfg.ssh_subsys; subsys = ssh->cfg.ssh_subsys;
cmd = cfg.remote_cmd_ptr; cmd = ssh->cfg.remote_cmd_ptr;
} }
ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST); ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
@ -5386,7 +5394,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
* not, and if the fallback command exists, try falling * not, and if the fallback command exists, try falling
* back to it before complaining. * back to it before complaining.
*/ */
if (!ssh->fallback_cmd && cfg.remote_cmd_ptr2 != NULL) { if (!ssh->fallback_cmd && ssh->cfg.remote_cmd_ptr2 != NULL) {
logevent("Primary command failed; attempting fallback"); logevent("Primary command failed; attempting fallback");
ssh->fallback_cmd = TRUE; ssh->fallback_cmd = TRUE;
continue; continue;
@ -5737,7 +5745,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
if (!ssh->X11_fwd_enabled) if (!ssh->X11_fwd_enabled)
error = "X11 forwarding is not enabled"; error = "X11 forwarding is not enabled";
else if (x11_init(&c->u.x11.s, cfg.x11_display, c, else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
ssh->x11auth, addrstr, port) != NULL) { ssh->x11auth, addrstr, port) != NULL) {
error = "Unable to open an X11 connection"; error = "Unable to open an X11 connection";
} else { } else {
@ -5867,12 +5875,14 @@ static void ssh2_protocol(Ssh ssh, unsigned char *in, int inlen, int ispkt)
* Returns an error message, or NULL on success. * Returns an error message, or NULL on success.
*/ */
static char *ssh_init(void *frontend_handle, void **backend_handle, static char *ssh_init(void *frontend_handle, void **backend_handle,
Config *cfg,
char *host, int port, char **realhost, int nodelay) char *host, int port, char **realhost, int nodelay)
{ {
char *p; char *p;
Ssh ssh; Ssh ssh;
ssh = smalloc(sizeof(*ssh)); ssh = smalloc(sizeof(*ssh));
ssh->cfg = *cfg; /* STRUCTURE COPY */
ssh->s = NULL; ssh->s = NULL;
ssh->cipher = NULL; ssh->cipher = NULL;
ssh->v1_cipher_ctx = NULL; ssh->v1_cipher_ctx = NULL;
@ -5933,8 +5943,8 @@ static char *ssh_init(void *frontend_handle, void **backend_handle,
#endif #endif
ssh->frontend = frontend_handle; ssh->frontend = frontend_handle;
ssh->term_width = cfg.width; ssh->term_width = ssh->cfg.width;
ssh->term_height = cfg.height; ssh->term_height = ssh->cfg.height;
ssh->send_ok = 0; ssh->send_ok = 0;
ssh->editing = 0; ssh->editing = 0;
@ -5952,6 +5962,21 @@ static char *ssh_init(void *frontend_handle, void **backend_handle,
return NULL; return NULL;
} }
/*
* Reconfigure the SSH backend.
*
* Currently, this function does nothing very useful. In future,
* however, we could do some handy things with it. For example, we
* could make the port forwarding configurer active in the Change
* Settings box, and this routine could close down existing
* forwardings and open up new ones in response to changes.
*/
static void ssh_reconfig(void *handle, Config *cfg)
{
Ssh ssh = (Ssh) handle;
ssh->cfg = *cfg; /* STRUCTURE COPY */
}
/* /*
* Called to send data down the Telnet connection. * Called to send data down the Telnet connection.
*/ */
@ -6018,7 +6043,7 @@ static void ssh_size(void *handle, int width, int height)
ssh->size_needed = TRUE; /* buffer for later */ ssh->size_needed = TRUE; /* buffer for later */
break; break;
case SSH_STATE_SESSION: case SSH_STATE_SESSION:
if (!cfg.nopty) { if (!ssh->cfg.nopty) {
if (ssh->version == 1) { if (ssh->version == 1) {
send_packet(ssh, SSH1_CMSG_WINDOW_SIZE, send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
PKT_INT, ssh->term_height, PKT_INT, ssh->term_height,
@ -6209,6 +6234,7 @@ extern int ssh_fallback_cmd(void *handle)
Backend ssh_backend = { Backend ssh_backend = {
ssh_init, ssh_init,
ssh_reconfig,
ssh_send, ssh_send,
ssh_sendbuffer, ssh_sendbuffer,
ssh_size, ssh_size,

View File

@ -217,6 +217,7 @@ typedef struct telnet_tag {
SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
} state; } state;
Config cfg;
} *Telnet; } *Telnet;
#define TELNET_MAX_BACKLOG 4096 #define TELNET_MAX_BACKLOG 4096
@ -386,13 +387,13 @@ static void process_subneg(Telnet telnet)
b[1] = SB; b[1] = SB;
b[2] = TELOPT_TSPEED; b[2] = TELOPT_TSPEED;
b[3] = TELQUAL_IS; b[3] = TELQUAL_IS;
strcpy((char *)(b + 4), cfg.termspeed); strcpy((char *)(b + 4), telnet->cfg.termspeed);
n = 4 + strlen(cfg.termspeed); n = 4 + strlen(telnet->cfg.termspeed);
b[n] = IAC; b[n] = IAC;
b[n + 1] = SE; b[n + 1] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n + 2); telnet->bufsize = sk_write(telnet->s, (char *)b, n + 2);
logevent(telnet->frontend, "server:\tSB TSPEED SEND"); logevent(telnet->frontend, "server:\tSB TSPEED SEND");
logbuf = dupprintf("client:\tSB TSPEED IS %s", cfg.termspeed); logbuf = dupprintf("client:\tSB TSPEED IS %s", telnet->cfg.termspeed);
logevent(telnet->frontend, logbuf); logevent(telnet->frontend, logbuf);
sfree(logbuf); sfree(logbuf);
} else } else
@ -405,11 +406,11 @@ static void process_subneg(Telnet telnet)
b[1] = SB; b[1] = SB;
b[2] = TELOPT_TTYPE; b[2] = TELOPT_TTYPE;
b[3] = TELQUAL_IS; b[3] = TELQUAL_IS;
for (n = 0; cfg.termtype[n]; n++) for (n = 0; telnet->cfg.termtype[n]; n++)
b[n + 4] = (cfg.termtype[n] >= 'a' b[n + 4] = (telnet->cfg.termtype[n] >= 'a'
&& cfg.termtype[n] <= && telnet->cfg.termtype[n] <=
'z' ? cfg.termtype[n] + 'A' - 'z' ? telnet->cfg.termtype[n] + 'A' -
'a' : cfg.termtype[n]); 'a' : telnet->cfg.termtype[n]);
b[n + 4] = IAC; b[n + 4] = IAC;
b[n + 5] = SE; b[n + 5] = SE;
telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6); telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6);
@ -432,7 +433,7 @@ static void process_subneg(Telnet telnet)
logevent(telnet->frontend, logbuf); logevent(telnet->frontend, logbuf);
sfree(logbuf); sfree(logbuf);
if (telnet->sb_opt == TELOPT_OLD_ENVIRON) { if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
if (cfg.rfc_environ) { if (telnet->cfg.rfc_environ) {
value = RFC_VALUE; value = RFC_VALUE;
var = RFC_VAR; var = RFC_VAR;
} else { } else {
@ -465,7 +466,7 @@ static void process_subneg(Telnet telnet)
b[2] = telnet->sb_opt; b[2] = telnet->sb_opt;
b[3] = TELQUAL_IS; b[3] = TELQUAL_IS;
n = 4; n = 4;
e = cfg.environmt; e = telnet->cfg.environmt;
while (*e) { while (*e) {
b[n++] = var; b[n++] = var;
while (*e && *e != '\t') while (*e && *e != '\t')
@ -477,14 +478,14 @@ static void process_subneg(Telnet telnet)
b[n++] = *e++; b[n++] = *e++;
e++; e++;
} }
if (*cfg.username) { if (*telnet->cfg.username) {
b[n++] = var; b[n++] = var;
b[n++] = 'U'; b[n++] = 'U';
b[n++] = 'S'; b[n++] = 'S';
b[n++] = 'E'; b[n++] = 'E';
b[n++] = 'R'; b[n++] = 'R';
b[n++] = value; b[n++] = value;
e = cfg.username; e = telnet->cfg.username;
while (*e) while (*e)
b[n++] = *e++; b[n++] = *e++;
} }
@ -652,6 +653,7 @@ static void telnet_sent(Plug plug, int bufsize)
* freed by the caller. * freed by the caller.
*/ */
static char *telnet_init(void *frontend_handle, void **backend_handle, static char *telnet_init(void *frontend_handle, void **backend_handle,
Config *cfg,
char *host, int port, char **realhost, int nodelay) char *host, int port, char **realhost, int nodelay)
{ {
static const struct plug_function_table fn_table = { static const struct plug_function_table fn_table = {
@ -665,6 +667,7 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
telnet = smalloc(sizeof(*telnet)); telnet = smalloc(sizeof(*telnet));
telnet->fn = &fn_table; telnet->fn = &fn_table;
telnet->cfg = *cfg; /* STRUCTURE COPY */
telnet->s = NULL; telnet->s = NULL;
telnet->echoing = TRUE; telnet->echoing = TRUE;
telnet->editing = TRUE; telnet->editing = TRUE;
@ -672,8 +675,8 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
telnet->sb_buf = NULL; telnet->sb_buf = NULL;
telnet->sb_size = 0; telnet->sb_size = 0;
telnet->frontend = frontend_handle; telnet->frontend = frontend_handle;
telnet->term_width = cfg.width; telnet->term_width = telnet->cfg.width;
telnet->term_height = cfg.height; telnet->term_height = telnet->cfg.height;
telnet->state = TOP_LEVEL; telnet->state = TOP_LEVEL;
*backend_handle = telnet; *backend_handle = telnet;
@ -713,7 +716,7 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
/* /*
* Initialise option states. * Initialise option states.
*/ */
if (cfg.passive_telnet) { if (telnet->cfg.passive_telnet) {
const struct Opt *const *o; const struct Opt *const *o;
for (o = opts; *o; o++) for (o = opts; *o; o++)
@ -737,6 +740,17 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
return NULL; return NULL;
} }
/*
* Reconfigure the Telnet backend. There's no immediate action
* necessary, in this backend: we just save the fresh config for
* any subsequent negotiations.
*/
static void telnet_reconfig(void *handle, Config *cfg)
{
Telnet telnet = (Telnet) handle;
telnet->cfg = *cfg; /* STRUCTURE COPY */
}
/* /*
* Called to send data down the Telnet connection. * Called to send data down the Telnet connection.
*/ */
@ -960,6 +974,7 @@ static int telnet_exitcode(void *handle)
Backend telnet_backend = { Backend telnet_backend = {
telnet_init, telnet_init,
telnet_reconfig,
telnet_send, telnet_send,
telnet_sendbuffer, telnet_sendbuffer,
telnet_size, telnet_size,

View File

@ -2411,7 +2411,8 @@ int main(int argc, char **argv)
term_provide_logctx(inst->term, inst->logctx); term_provide_logctx(inst->term, inst->logctx);
inst->back = &pty_backend; inst->back = &pty_backend;
inst->back->init((void *)inst->term, &inst->backhandle, NULL, 0, NULL, 0); inst->back->init((void *)inst->term, &inst->backhandle, &cfg,
NULL, 0, NULL, 0);
inst->back->provide_logctx(inst->backhandle, inst->logctx); inst->back->provide_logctx(inst->backhandle, inst->logctx);
term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle); term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);

View File

@ -389,7 +389,7 @@ void pty_pre_init(void)
* Also places the canonical host name into `realhost'. It must be * Also places the canonical host name into `realhost'. It must be
* freed by the caller. * freed by the caller.
*/ */
static char *pty_init(void *frontend, void **backend_handle, static char *pty_init(void *frontend, void **backend_handle, Config *cfg,
char *host, int port, char **realhost, int nodelay) char *host, int port, char **realhost, int nodelay)
{ {
int slavefd; int slavefd;
@ -398,8 +398,8 @@ static char *pty_init(void *frontend, void **backend_handle,
pty_frontend = frontend; pty_frontend = frontend;
*backend_handle = NULL; /* we can't sensibly use this, sadly */ *backend_handle = NULL; /* we can't sensibly use this, sadly */
pty_term_width = cfg.width; pty_term_width = cfg->width;
pty_term_height = cfg.height; pty_term_height = cfg->height;
if (pty_master_fd < 0) if (pty_master_fd < 0)
pty_open_master(); pty_open_master();
@ -411,7 +411,7 @@ static char *pty_init(void *frontend, void **backend_handle,
{ {
struct termios attrs; struct termios attrs;
tcgetattr(pty_master_fd, &attrs); tcgetattr(pty_master_fd, &attrs);
attrs.c_cc[VERASE] = cfg.bksp_is_delete ? '\177' : '\010'; attrs.c_cc[VERASE] = cfg->bksp_is_delete ? '\177' : '\010';
tcsetattr(pty_master_fd, TCSANOW, &attrs); tcsetattr(pty_master_fd, TCSANOW, &attrs);
} }
@ -419,7 +419,7 @@ static char *pty_init(void *frontend, void **backend_handle,
* Stamp utmp (that is, tell the utmp helper process to do so), * Stamp utmp (that is, tell the utmp helper process to do so),
* or not. * or not.
*/ */
if (!cfg.stamp_utmp) if (!cfg->stamp_utmp)
close(pty_utmp_helper_pipe); /* just let the child process die */ close(pty_utmp_helper_pipe); /* just let the child process die */
else { else {
char *location = get_x_display(pty_frontend); char *location = get_x_display(pty_frontend);
@ -472,8 +472,8 @@ static char *pty_init(void *frontend, void **backend_handle,
for (i = 3; i < 1024; i++) for (i = 3; i < 1024; i++)
close(i); close(i);
{ {
char term_env_var[10 + sizeof(cfg.termtype)]; char term_env_var[10 + sizeof(cfg->termtype)];
sprintf(term_env_var, "TERM=%s", cfg.termtype); sprintf(term_env_var, "TERM=%s", cfg->termtype);
putenv(term_env_var); putenv(term_env_var);
} }
/* /*
@ -488,7 +488,7 @@ static char *pty_init(void *frontend, void **backend_handle,
else { else {
char *shell = getenv("SHELL"); char *shell = getenv("SHELL");
char *shellname; char *shellname;
if (cfg.login_shell) { if (cfg->login_shell) {
char *p = strrchr(shell, '/'); char *p = strrchr(shell, '/');
shellname = smalloc(2+strlen(shell)); shellname = smalloc(2+strlen(shell));
p = p ? p+1 : shell; p = p ? p+1 : shell;
@ -511,6 +511,13 @@ static char *pty_init(void *frontend, void **backend_handle,
return NULL; return NULL;
} }
/*
* Stub routine (we don't have any need to reconfigure this backend).
*/
static void pty_reconfig(void *handle, Config *cfg)
{
}
/* /*
* Called to send data down the pty. * Called to send data down the pty.
*/ */
@ -617,6 +624,7 @@ static int pty_exitcode(void *handle)
Backend pty_backend = { Backend pty_backend = {
pty_init, pty_init,
pty_reconfig,
pty_send, pty_send,
pty_sendbuffer, pty_sendbuffer,
pty_size, pty_size,

View File

@ -551,7 +551,7 @@ int main(int argc, char **argv)
/* nodelay is only useful if stdin is a terminal device */ /* nodelay is only useful if stdin is a terminal device */
int nodelay = cfg.tcp_nodelay && isatty(0); int nodelay = cfg.tcp_nodelay && isatty(0);
error = back->init(NULL, &backhandle, cfg.host, cfg.port, error = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port,
&realhost, nodelay); &realhost, nodelay);
if (error) { if (error) {
fprintf(stderr, "Unable to open connection:\n%s\n", error); fprintf(stderr, "Unable to open connection:\n%s\n", error);

View File

@ -615,7 +615,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
char msg[1024], *title; char msg[1024], *title;
char *realhost; char *realhost;
error = back->init((void *)term, &backhandle, error = back->init((void *)term, &backhandle, &cfg,
cfg.host, cfg.port, &realhost, cfg.tcp_nodelay); cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
back->provide_logctx(backhandle, logctx); back->provide_logctx(backhandle, logctx);
if (error) { if (error) {
@ -1782,6 +1782,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
/* Pass new config data to the terminal */ /* Pass new config data to the terminal */
term_reconfig(term, &cfg); term_reconfig(term, &cfg);
/* Pass new config data to the back end */
back->reconfig(back, &cfg);
/* Screen size changed ? */ /* Screen size changed ? */
if (cfg.height != prev_cfg.height || if (cfg.height != prev_cfg.height ||
cfg.width != prev_cfg.width || cfg.width != prev_cfg.width ||