]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
The back ends now contain their own copies of the Config structure,
authorSimon Tatham <anakin@pobox.com>
Sun, 12 Jan 2003 14:48:29 +0000 (14:48 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 12 Jan 2003 14:48:29 +0000 (14:48 +0000)
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]

12 files changed:
plink.c
psftp.c
putty.h
raw.c
rlogin.c
scp.c
ssh.c
telnet.c
unix/pterm.c
unix/pty.c
unix/uxplink.c
window.c

diff --git a/plink.c b/plink.c
index 7ada2d48fd80685f63d07e2b7397c2c5c4479323..f92715191ed701d4d62d2c691b6d2337c2d7b2d3 100644 (file)
--- a/plink.c
+++ b/plink.c
@@ -539,7 +539,7 @@ int main(int argc, char **argv)
        int nodelay = cfg.tcp_nodelay &&
            (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);
        if (error) {
            fprintf(stderr, "Unable to open connection:\n%s", error);
diff --git a/psftp.c b/psftp.c
index f528c21859b94b15513ee4bfcf553e81074dd43b..f8d1f79923f4679478f0560059d0ea578040c435 100644 (file)
--- a/psftp.c
+++ b/psftp.c
@@ -1828,7 +1828,7 @@ static int psftp_connect(char *userhost, char *user, int portnumber)
 
     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) {
        fprintf(stderr, "ssh_init: %s\n", err);
        return 1;
diff --git a/putty.h b/putty.h
index 19000fc7dbc119e57a6d026284dde038fda12e3a..65a99ebe3ef1870eff67aa57af9321293b628253 100644 (file)
--- a/putty.h
+++ b/putty.h
@@ -184,8 +184,10 @@ enum {
 };
 
 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);
+    /* back->reconfig() passes in a replacement configuration. */
+    void (*reconfig) (void *handle, Config *cfg);
     /* back->send() returns the current amount of buffered data. */
     int (*send) (void *handle, char *buf, int len);
     /* back->sendbuffer() does the same thing but without attempting a send */
diff --git a/raw.c b/raw.c
index 0e6c14102cdb7de39a00f1695f0076dc25b4d2a5..09903338cf72ad056a3c054dc404a94c987c305d 100644 (file)
--- a/raw.c
+++ b/raw.c
@@ -68,6 +68,7 @@ static void raw_sent(Plug plug, int bufsize)
  * freed by the caller.
  */
 static char *raw_init(void *frontend_handle, void **backend_handle,
+                     Config *cfg,
                      char *host, int port, char **realhost, int nodelay)
 {
     static const struct plug_function_table fn_table = {
@@ -121,6 +122,13 @@ static char *raw_init(void *frontend_handle, void **backend_handle,
     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.
  */
@@ -205,6 +213,7 @@ static int raw_exitcode(void *handle)
 
 Backend raw_backend = {
     raw_init,
+    raw_reconfig,
     raw_send,
     raw_sendbuffer,
     raw_size,
index 9c249f27f5e245706be3ed4785677a1dc6aedb81..afc3d2c3e5ab910f0caa0467d849ec63b78045b0 100644 (file)
--- a/rlogin.c
+++ b/rlogin.c
@@ -98,6 +98,7 @@ static void rlogin_sent(Plug plug, int bufsize)
  * freed by the caller.
  */
 static char *rlogin_init(void *frontend_handle, void **backend_handle,
+                        Config *cfg,
                         char *host, int port, char **realhost, int nodelay)
 {
     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->s = NULL;
     rlogin->frontend = frontend_handle;
-    rlogin->term_width = cfg.width;
-    rlogin->term_height = cfg.height;
+    rlogin->term_width = cfg->width;
+    rlogin->term_height = cfg->height;
     *backend_handle = rlogin;
 
     /*
@@ -158,20 +159,30 @@ static char *rlogin_init(void *frontend_handle, void **backend_handle,
        char z = 0;
        char *p;
        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, cfg.username, strlen(cfg.username));
+       sk_write(rlogin->s, cfg->username,
+                strlen(cfg->username));
        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);
-       for (p = cfg.termspeed; isdigit(*p); p++) continue;
-       sk_write(rlogin->s, cfg.termspeed, p - cfg.termspeed);
+       for (p = cfg->termspeed; isdigit(*p); p++) continue;
+       sk_write(rlogin->s, cfg->termspeed, p - cfg->termspeed);
        rlogin->bufsize = sk_write(rlogin->s, &z, 1);
     }
 
     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.
  */
@@ -270,6 +281,7 @@ static int rlogin_exitcode(void *handle)
 
 Backend rlogin_backend = {
     rlogin_init,
+    rlogin_reconfig,
     rlogin_send,
     rlogin_sendbuffer,
     rlogin_size,
diff --git a/scp.c b/scp.c
index 389799d1c5fdeda66cdfed6dc562f473c568e137..20f97dd7c5f90b7cef6f67a6873089f2ad7f4813 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -574,7 +574,7 @@ static void do_cmd(char *host, char *user, char *cmd)
 
     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)
        bump("ssh_init: %s", err);
     logctx = log_init(NULL);
diff --git a/ssh.c b/ssh.c
index a2e74c0e837182ed1dd31759533e8c4897f67a9b..70f3a069d8c0bdb7c437c3d9990a945ec6e374b2 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -620,6 +620,14 @@ struct ssh_tag {
 
     void (*protocol) (Ssh ssh, unsigned char *in, int inlen, int ispkt);
     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)
@@ -1711,8 +1719,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
 
     ssh->remote_bugs = 0;
 
-    if (cfg.sshbug_ignore1 == BUG_ON ||
-       (cfg.sshbug_ignore1 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_ignore1 == BUG_ON ||
+       (ssh->cfg.sshbug_ignore1 == BUG_AUTO &&
         (!strcmp(imp, "1.2.18") || !strcmp(imp, "1.2.19") ||
          !strcmp(imp, "1.2.20") || !strcmp(imp, "1.2.21") ||
          !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");
     }
 
-    if (cfg.sshbug_plainpw1 == BUG_ON ||
-       (cfg.sshbug_plainpw1 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_plainpw1 == BUG_ON ||
+       (ssh->cfg.sshbug_plainpw1 == BUG_AUTO &&
         (!strcmp(imp, "Cisco-1.25")))) {
        /*
         * 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");
     }
 
-    if (cfg.sshbug_rsa1 == BUG_ON ||
-       (cfg.sshbug_rsa1 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_rsa1 == BUG_ON ||
+       (ssh->cfg.sshbug_rsa1 == BUG_AUTO &&
         (!strcmp(imp, "Cisco-1.25")))) {
        /*
         * 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");
     }
 
-    if (cfg.sshbug_hmac2 == BUG_ON ||
-       (cfg.sshbug_hmac2 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_hmac2 == BUG_ON ||
+       (ssh->cfg.sshbug_hmac2 == BUG_AUTO &&
         (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.1 *", imp)))) {
@@ -1761,8 +1769,8 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring)
        logevent("We believe remote version has SSH2 HMAC bug");
     }
 
-    if (cfg.sshbug_derivekey2 == BUG_ON ||
-       (cfg.sshbug_derivekey2 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_derivekey2 == BUG_ON ||
+       (ssh->cfg.sshbug_derivekey2 == BUG_AUTO &&
         (wc_match("2.0.0*", imp) || wc_match("2.0.1[01]*", imp) ))) {
        /*
         * 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");
     }
 
-    if (cfg.sshbug_rsapad2 == BUG_ON ||
-       (cfg.sshbug_rsapad2 == BUG_AUTO &&
+    if (ssh->cfg.sshbug_rsapad2 == BUG_ON ||
+       (ssh->cfg.sshbug_rsapad2 == BUG_AUTO &&
         (wc_match("OpenSSH_2.[5-9]*", 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");
     }
 
-    if (cfg.sshbug_dhgex2 == BUG_ON) {
+    if (ssh->cfg.sshbug_dhgex2 == BUG_ON) {
        /*
         * 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. */
     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"));
        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"));
        crReturn(0);
     }
 
-    if (s->proto2 && (cfg.sshprot >= 2 || !s->proto1)) {
+    if (s->proto2 && (ssh->cfg.sshprot >= 2 || !s->proto1)) {
        /*
         * 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;
        int 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/when we choose a cipher, warn about it */
                warn = 1;
@@ -2394,7 +2402,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
 
     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("login as: ",
                                  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");
            }
        } 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';
        }
 
@@ -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->tis_auth_refused = s->ccard_auth_refused = 0;
-    /* Load the public half of cfg.keyfile so we notice if it's in Pageant */
-    if (*cfg.keyfile) {
-       if (!rsakey_pubblob(cfg.keyfile,
+    /* Load the public half of ssh->cfg.keyfile so we notice if it's in Pageant */
+    if (*ssh->cfg.keyfile) {
+       if (!rsakey_pubblob(ssh->cfg.keyfile,
                            &s->publickey_blob, &s->publickey_bloblen))
            s->publickey_blob = NULL;
     } else
@@ -2577,10 +2585,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
            if (s->authed)
                break;
        }
-       if (*cfg.keyfile && !s->tried_publickey)
+       if (*ssh->cfg.keyfile && !s->tried_publickey)
            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->tis_auth_refused) {
            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';
            }
        }
-       if (cfg.try_tis_auth &&
+       if (ssh->cfg.try_tis_auth &&
            (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
            !s->ccard_auth_refused) {
            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];
            if (flags & FLAG_VERBOSE)
                c_write_str(ssh, "Trying public key authentication.\r\n");
-           logeventf(ssh, "Trying public key \"%s\"", cfg.keyfile);
-           type = key_type(cfg.keyfile);
+           logeventf(ssh, "Trying public key \"%s\"", ssh->cfg.keyfile);
+           type = key_type(ssh->cfg.keyfile);
            if (type != SSH_KEYTYPE_SSH1) {
                sprintf(msgbuf, "Key is of wrong type (%s)",
                        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;
                continue;
            }
-           if (!rsakey_encrypted(cfg.keyfile, &comment)) {
+           if (!rsakey_encrypted(ssh->cfg.keyfile, &comment)) {
                if (flags & FLAG_VERBOSE)
                    c_write_str(ssh, "No passphrase required.\r\n");
                goto tryauth;
@@ -2709,10 +2717,10 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
            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) {
                    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");
                    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)
        crReturnV;
 
-    if (cfg.agentfwd && agent_exists()) {
+    if (ssh->cfg.agentfwd && agent_exists()) {
        logevent("Requesting agent forwarding");
        send_packet(ssh, SSH1_CMSG_AGENT_REQUEST_FORWARDING, PKT_END);
        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];
        logevent("Requesting X11 forwarding");
        ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
-                                      data, sizeof(data), cfg.x11_auth);
-        x11_get_real_auth(ssh->x11auth, cfg.x11_display);
+                                      data, sizeof(data), ssh->cfg.x11_auth);
+        x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
        if (ssh->v1_local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER) {
            send_packet(ssh, SSH1_CMSG_X11_REQUEST_FORWARDING,
                        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);
        } else {
            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);
         /* Add port forwardings. */
-       ssh->portfwd_strptr = cfg.portfwd;
+       ssh->portfwd_strptr = ssh->cfg.portfwd;
        while (*ssh->portfwd_strptr) {
            type = *ssh->portfwd_strptr++;
            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,
-                   PKT_STR, cfg.termtype,
+                   PKT_STR, ssh->cfg.termtype,
                    PKT_INT, ssh->term_height,
                    PKT_INT, ssh->term_width,
                    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;
     }
 
-    if (cfg.compression) {
+    if (ssh->cfg.compression) {
        send_packet(ssh, SSH1_CMSG_REQUEST_COMPRESSION, PKT_INT, 6, PKT_END);
        do {
            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.
      */
     {
-       char *cmd = cfg.remote_cmd_ptr;
+       char *cmd = ssh->cfg.remote_cmd_ptr;
        
-       if (cfg.ssh_subsys && cfg.remote_cmd_ptr2) {
-           cmd = cfg.remote_cmd_ptr2;
+       if (ssh->cfg.ssh_subsys && ssh->cfg.remote_cmd_ptr2) {
+           cmd = ssh->cfg.remote_cmd_ptr2;
            ssh->fallback_cmd = TRUE;
        }
        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->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) {
                        logevent("opening X11 forward connection failed");
                        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;
        for (i = 0; i < CIPHER_MAX; i++) {
-           switch (cfg.ssh_cipherlist[i]) {
+           switch (ssh->cfg.ssh_cipherlist[i]) {
              case CIPHER_BLOWFISH:
                s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_blowfish;
                break;
              case CIPHER_DES:
-               if (cfg.ssh2_des_cbc) {
+               if (ssh->cfg.ssh2_des_cbc) {
                    s->preferred_ciphers[s->n_preferred_ciphers++] = &ssh2_des;
                }
                break;
@@ -3698,7 +3706,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int ispkt)
     /*
      * Set up preferred compression.
      */
-    if (cfg.compression)
+    if (ssh->cfg.compression)
        s->preferred_comp = &ssh_zlib;
     else
        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.
         */
-       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
             * with change_username turned off we don't try to get
             * 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("login as: ",
                                  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';
        } else {
            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';
            if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE)) {
                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_keyb_inter = FALSE;
        s->kbd_inter_running = FALSE;
-       /* Load the pub half of cfg.keyfile so we notice if it's in Pageant */
-       if (*cfg.keyfile) {
+       /* Load the pub half of ssh->cfg.keyfile so we notice if it's in Pageant */
+       if (*ssh->cfg.keyfile) {
            int keytype;
-           logeventf(ssh, "Reading private key file \"%.150s\"", cfg.keyfile);
-           keytype = key_type(cfg.keyfile);
+           logeventf(ssh, "Reading private key file \"%.150s\"", ssh->cfg.keyfile);
+           keytype = key_type(ssh->cfg.keyfile);
            if (keytype == SSH_KEYTYPE_SSH2) {
                s->publickey_blob =
-                   ssh2_userkey_loadpub(cfg.keyfile, NULL,
+                   ssh2_userkey_loadpub(ssh->cfg.keyfile, NULL,
                                         &s->publickey_bloblen);
            } else {
                char *msgbuf;
                logeventf(ssh, "Unable to use this key file (%s)",
                          key_type_to_str(keytype));
                msgbuf = dupprintf("Unable to use key file \"%.150s\""
-                                  " (%s)\r\n", cfg.keyfile,
+                                  " (%s)\r\n", ssh->cfg.keyfile,
                                   key_type_to_str(keytype));
                c_write_str(ssh, 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);
                s->can_passwd =
                    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);
            }
 
@@ -4682,7 +4690,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                 * willing to accept it.
                 */
                pub_blob =
-                   (unsigned char *)ssh2_userkey_loadpub(cfg.keyfile,
+                   (unsigned char *)ssh2_userkey_loadpub(ssh->cfg.keyfile,
                                                          &algorithm,
                                                          &pub_blob_len);
                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
                     * the key.
                     */
-                   if (ssh2_userkey_encrypted(cfg.keyfile, &comment)) {
+                   if (ssh2_userkey_encrypted(ssh->cfg.keyfile, &comment)) {
                        sprintf(s->pwprompt,
                                "Passphrase for key \"%.100s\": ",
                                comment);
@@ -4862,7 +4870,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                 */
                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) {
                        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.
      */
-    if (cfg.x11_forward) {
+    if (ssh->cfg.x11_forward) {
        char proto[20], data[64];
        logevent("Requesting X11 forwarding");
        ssh->x11auth = x11_invent_auth(proto, sizeof(proto),
-                                      data, sizeof(data), cfg.x11_auth);
-        x11_get_real_auth(ssh->x11auth, cfg.x11_display);
+                                      data, sizeof(data), ssh->cfg.x11_auth);
+        x11_get_real_auth(ssh->x11auth, ssh->cfg.x11_display);
        ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
        ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);
        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_addstring(ssh, proto);
        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);
 
        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);
         /* Add port forwardings. */
-       ssh->portfwd_strptr = cfg.portfwd;
+       ssh->portfwd_strptr = ssh->cfg.portfwd;
        while (*ssh->portfwd_strptr) {
            type = *ssh->portfwd_strptr++;
            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 */
                        if (*saddr)
                            ssh2_pkt_addstring(ssh, saddr);
-                       if (cfg.rport_acceptall)
+                       if (ssh->cfg.rport_acceptall)
                            ssh2_pkt_addstring(ssh, "0.0.0.0");
                        else
                            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.
      */
-    if (cfg.agentfwd && agent_exists()) {
+    if (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);
@@ -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.
      */
-    if (!cfg.nopty) {
+    if (!ssh->cfg.nopty) {
        ssh2_pkt_init(ssh, SSH2_MSG_CHANNEL_REQUEST);
        ssh2_pkt_adduint32(ssh, ssh->mainchan->remoteid);       /* recipient channel */
        ssh2_pkt_addstring(ssh, "pty-req");
        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_height);
        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;
 
        if (ssh->fallback_cmd) {
-           subsys = cfg.ssh_subsys2;
-           cmd = cfg.remote_cmd_ptr2;
+           subsys = ssh->cfg.ssh_subsys2;
+           cmd = ssh->cfg.remote_cmd_ptr2;
        } else {
-           subsys = cfg.ssh_subsys;
-           cmd = cfg.remote_cmd_ptr;
+           subsys = ssh->cfg.ssh_subsys;
+           cmd = ssh->cfg.remote_cmd_ptr;
        }
 
        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
             * 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");
                ssh->fallback_cmd = TRUE;
                continue;
@@ -5737,7 +5745,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
 
                    if (!ssh->X11_fwd_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) {
                        error = "Unable to open an X11 connection";
                    } 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.
  */
 static char *ssh_init(void *frontend_handle, void **backend_handle,
+                     Config *cfg,
                      char *host, int port, char **realhost, int nodelay)
 {
     char *p;
     Ssh ssh;
 
     ssh = smalloc(sizeof(*ssh));
+    ssh->cfg = *cfg;                  /* STRUCTURE COPY */
     ssh->s = NULL;
     ssh->cipher = NULL;
     ssh->v1_cipher_ctx = NULL;
@@ -5933,8 +5943,8 @@ static char *ssh_init(void *frontend_handle, void **backend_handle,
 #endif
 
     ssh->frontend = frontend_handle;
-    ssh->term_width = cfg.width;
-    ssh->term_height = cfg.height;
+    ssh->term_width = ssh->cfg.width;
+    ssh->term_height = ssh->cfg.height;
 
     ssh->send_ok = 0;
     ssh->editing = 0;
@@ -5952,6 +5962,21 @@ static char *ssh_init(void *frontend_handle, void **backend_handle,
     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.
  */
@@ -6018,7 +6043,7 @@ static void ssh_size(void *handle, int width, int height)
        ssh->size_needed = TRUE;       /* buffer for later */
        break;
       case SSH_STATE_SESSION:
-       if (!cfg.nopty) {
+       if (!ssh->cfg.nopty) {
            if (ssh->version == 1) {
                send_packet(ssh, SSH1_CMSG_WINDOW_SIZE,
                            PKT_INT, ssh->term_height,
@@ -6209,6 +6234,7 @@ extern int ssh_fallback_cmd(void *handle)
 
 Backend ssh_backend = {
     ssh_init,
+    ssh_reconfig,
     ssh_send,
     ssh_sendbuffer,
     ssh_size,
index f4ea82bae98dd182d3bcdf5072112081f72dd054..2d87b310e09bc47db6edbf0c1c9f61c1c29fa0ab 100644 (file)
--- a/telnet.c
+++ b/telnet.c
@@ -217,6 +217,7 @@ typedef struct telnet_tag {
            SEENSB, SUBNEGOT, SUBNEG_IAC, SEENCR
     } state;
 
+    Config cfg;
 } *Telnet;
 
 #define TELNET_MAX_BACKLOG 4096
@@ -386,13 +387,13 @@ static void process_subneg(Telnet telnet)
            b[1] = SB;
            b[2] = TELOPT_TSPEED;
            b[3] = TELQUAL_IS;
-           strcpy((char *)(b + 4), cfg.termspeed);
-           n = 4 + strlen(cfg.termspeed);
+           strcpy((char *)(b + 4), telnet->cfg.termspeed);
+           n = 4 + strlen(telnet->cfg.termspeed);
            b[n] = IAC;
            b[n + 1] = SE;
            telnet->bufsize = sk_write(telnet->s, (char *)b, n + 2);
            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);
            sfree(logbuf);
        } else
@@ -405,11 +406,11 @@ static void process_subneg(Telnet telnet)
            b[1] = SB;
            b[2] = TELOPT_TTYPE;
            b[3] = TELQUAL_IS;
-           for (n = 0; cfg.termtype[n]; n++)
-               b[n + 4] = (cfg.termtype[n] >= 'a'
-                           && cfg.termtype[n] <=
-                           'z' ? cfg.termtype[n] + 'A' -
-                           'a' : cfg.termtype[n]);
+           for (n = 0; telnet->cfg.termtype[n]; n++)
+               b[n + 4] = (telnet->cfg.termtype[n] >= 'a'
+                           && telnet->cfg.termtype[n] <=
+                           'z' ? telnet->cfg.termtype[n] + 'A' -
+                           'a' : telnet->cfg.termtype[n]);
            b[n + 4] = IAC;
            b[n + 5] = SE;
            telnet->bufsize = sk_write(telnet->s, (char *)b, n + 6);
@@ -432,7 +433,7 @@ static void process_subneg(Telnet telnet)
            logevent(telnet->frontend, logbuf);
            sfree(logbuf);
            if (telnet->sb_opt == TELOPT_OLD_ENVIRON) {
-               if (cfg.rfc_environ) {
+               if (telnet->cfg.rfc_environ) {
                    value = RFC_VALUE;
                    var = RFC_VAR;
                } else {
@@ -465,7 +466,7 @@ static void process_subneg(Telnet telnet)
            b[2] = telnet->sb_opt;
            b[3] = TELQUAL_IS;
            n = 4;
-           e = cfg.environmt;
+           e = telnet->cfg.environmt;
            while (*e) {
                b[n++] = var;
                while (*e && *e != '\t')
@@ -477,14 +478,14 @@ static void process_subneg(Telnet telnet)
                    b[n++] = *e++;
                e++;
            }
-           if (*cfg.username) {
+           if (*telnet->cfg.username) {
                b[n++] = var;
                b[n++] = 'U';
                b[n++] = 'S';
                b[n++] = 'E';
                b[n++] = 'R';
                b[n++] = value;
-               e = cfg.username;
+               e = telnet->cfg.username;
                while (*e)
                    b[n++] = *e++;
            }
@@ -652,6 +653,7 @@ static void telnet_sent(Plug plug, int bufsize)
  * freed by the caller.
  */
 static char *telnet_init(void *frontend_handle, void **backend_handle,
+                        Config *cfg,
                         char *host, int port, char **realhost, int nodelay)
 {
     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->fn = &fn_table;
+    telnet->cfg = *cfg;                       /* STRUCTURE COPY */
     telnet->s = NULL;
     telnet->echoing = TRUE;
     telnet->editing = TRUE;
@@ -672,8 +675,8 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
     telnet->sb_buf = NULL;
     telnet->sb_size = 0;
     telnet->frontend = frontend_handle;
-    telnet->term_width = cfg.width;
-    telnet->term_height = cfg.height;
+    telnet->term_width = telnet->cfg.width;
+    telnet->term_height = telnet->cfg.height;
     telnet->state = TOP_LEVEL;
     *backend_handle = telnet;
 
@@ -713,7 +716,7 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
     /*
      * Initialise option states.
      */
-    if (cfg.passive_telnet) {
+    if (telnet->cfg.passive_telnet) {
        const struct Opt *const *o;
 
        for (o = opts; *o; o++)
@@ -737,6 +740,17 @@ static char *telnet_init(void *frontend_handle, void **backend_handle,
     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.
  */
@@ -960,6 +974,7 @@ static int telnet_exitcode(void *handle)
 
 Backend telnet_backend = {
     telnet_init,
+    telnet_reconfig,
     telnet_send,
     telnet_sendbuffer,
     telnet_size,
index dbcb54553b0385b62e25ef44532785a0ba82cade..f0f71e8355b38661b9c0335ffd5f641f7afa71ae 100644 (file)
@@ -2411,7 +2411,8 @@ int main(int argc, char **argv)
     term_provide_logctx(inst->term, inst->logctx);
 
     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);
 
     term_provide_resize_fn(inst->term, inst->back->size, inst->backhandle);
index 0084e64a68d9a81c9935546a48755e881858dc05..1c213e869b1b08acbbcca5c4261c3bfa3f6d9d1a 100644 (file)
@@ -389,7 +389,7 @@ void pty_pre_init(void)
  * Also places the canonical host name into `realhost'. It must be
  * 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)
 {
     int slavefd;
@@ -398,8 +398,8 @@ static char *pty_init(void *frontend, void **backend_handle,
     pty_frontend = frontend;
     *backend_handle = NULL;           /* we can't sensibly use this, sadly */
 
-    pty_term_width = cfg.width;
-    pty_term_height = cfg.height;
+    pty_term_width = cfg->width;
+    pty_term_height = cfg->height;
 
     if (pty_master_fd < 0)
        pty_open_master();
@@ -411,7 +411,7 @@ static char *pty_init(void *frontend, void **backend_handle,
     {
        struct termios 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);
     }
 
@@ -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),
      * or not.
      */
-    if (!cfg.stamp_utmp)
+    if (!cfg->stamp_utmp)
        close(pty_utmp_helper_pipe);   /* just let the child process die */
     else {
        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++)
            close(i);
        {
-           char term_env_var[10 + sizeof(cfg.termtype)];
-           sprintf(term_env_var, "TERM=%s", cfg.termtype);
+           char term_env_var[10 + sizeof(cfg->termtype)];
+           sprintf(term_env_var, "TERM=%s", cfg->termtype);
            putenv(term_env_var);
        }
        /*
@@ -488,7 +488,7 @@ static char *pty_init(void *frontend, void **backend_handle,
        else {
            char *shell = getenv("SHELL");
            char *shellname;
-           if (cfg.login_shell) {
+           if (cfg->login_shell) {
                char *p = strrchr(shell, '/');
                shellname = smalloc(2+strlen(shell));
                p = p ? p+1 : shell;
@@ -511,6 +511,13 @@ static char *pty_init(void *frontend, void **backend_handle,
     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.
  */
@@ -617,6 +624,7 @@ static int pty_exitcode(void *handle)
 
 Backend pty_backend = {
     pty_init,
+    pty_reconfig,
     pty_send,
     pty_sendbuffer,
     pty_size,
index 5ca5bb2c2c1c516b00a8538ec2997673571fc950..295e80b34fe6f0d04c25fb746d5625b9a6bba5ab 100644 (file)
@@ -551,7 +551,7 @@ int main(int argc, char **argv)
        /* nodelay is only useful if stdin is a terminal device */
        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);
        if (error) {
            fprintf(stderr, "Unable to open connection:\n%s\n", error);
index 272a527430d26a0ab7a1ed79f310964985866114..ebf554ea26205de30f37f48fea033648a2537cd4 100644 (file)
--- a/window.c
+++ b/window.c
@@ -615,7 +615,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
        char msg[1024], *title;
        char *realhost;
 
-       error = back->init((void *)term, &backhandle,
+       error = back->init((void *)term, &backhandle, &cfg,
                           cfg.host, cfg.port, &realhost, cfg.tcp_nodelay);
        back->provide_logctx(backhandle, logctx);
        if (error) {
@@ -1782,6 +1782,9 @@ static LRESULT CALLBACK WndProc(HWND hwnd, UINT message,
                /* Pass new config data to the terminal */
                term_reconfig(term, &cfg);
 
+               /* Pass new config data to the back end */
+               back->reconfig(back, &cfg);
+
                /* Screen size changed ? */
                if (cfg.height != prev_cfg.height ||
                    cfg.width != prev_cfg.width ||