summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
3fe9213)
mid-session in SSH2: this forces an immediate rekey to activate the
new settings. I'm not sure exactly what this will be useful for
(except possibly it might make comparative performance testing
easier?), but it has wonderful James Bond value for being able to
switch to a more secure cipher before doing anything sensitive :-)
If, that is, you weren't using the most secure one to begin with...
git-svn-id: svn://svn.tartarus.org/sgt/putty@5051
cda61777-01e9-0310-a592-
d414129be87e
ctrl_settitle(b, "Connection/SSH",
"Options controlling SSH connections");
ctrl_settitle(b, "Connection/SSH",
"Options controlling SSH connections");
+ if (midsession && protcfginfo == 1) {
s = ctrl_getset(b, "Connection/SSH", "disclaimer", NULL);
ctrl_text(s, "Nothing on this panel may be reconfigured in mid-"
"session; it is only here so that sub-panels of it can "
s = ctrl_getset(b, "Connection/SSH", "disclaimer", NULL);
ctrl_text(s, "Nothing on this panel may be reconfigured in mid-"
"session; it is only here so that sub-panels of it can "
HELPCTX(ssh_noshell),
dlg_stdcheckbox_handler,
I(offsetof(Config,ssh_no_shell)));
HELPCTX(ssh_noshell),
dlg_stdcheckbox_handler,
I(offsetof(Config,ssh_no_shell)));
+ }
+
+ if (!midsession || protcfginfo != 1) {
+ s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
+
ctrl_checkbox(s, "Enable compression", 'e',
HELPCTX(ssh_compress),
dlg_stdcheckbox_handler,
I(offsetof(Config,compression)));
ctrl_checkbox(s, "Enable compression", 'e',
HELPCTX(ssh_compress),
dlg_stdcheckbox_handler,
I(offsetof(Config,compression)));
+ }
+
+ if (!midsession) {
+ s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
+
ctrl_radiobuttons(s, "Preferred SSH protocol version:", NO_SHORTCUT, 4,
HELPCTX(ssh_protocol),
dlg_stdradiobutton_handler,
ctrl_radiobuttons(s, "Preferred SSH protocol version:", NO_SHORTCUT, 4,
HELPCTX(ssh_protocol),
dlg_stdradiobutton_handler,
"1", '1', I(1),
"2", '2', I(2),
"2 only", 'y', I(3), NULL);
"1", '1', I(1),
"2", '2', I(2),
"2 only", 'y', I(3), NULL);
+ if (!midsession || protcfginfo != 1) {
s = ctrl_getset(b, "Connection/SSH", "encryption", "Encryption options");
c = ctrl_draglist(s, "Encryption cipher selection policy:", 's',
HELPCTX(ssh_ciphers),
s = ctrl_getset(b, "Connection/SSH", "encryption", "Encryption options");
c = ctrl_draglist(s, "Encryption cipher selection policy:", 's',
HELPCTX(ssh_ciphers),
unsigned long max_data_size;
int kex_in_progress;
long next_rekey, last_rekey;
unsigned long max_data_size;
int kex_in_progress;
long next_rekey, last_rekey;
+ char *deferred_rekey_reason; /* points to STATIC string; don't free */
};
#define logevent(s) logevent(ssh->frontend, s)
};
#define logevent(s) logevent(ssh->frontend, s)
int n_preferred_ciphers;
const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
const struct ssh_compress *preferred_comp;
int n_preferred_ciphers;
const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX];
const struct ssh_compress *preferred_comp;
+ int got_session_id, activated_authconn;
struct Packet *pktout;
};
crState(do_ssh2_transport_state);
struct Packet *pktout;
};
crState(do_ssh2_transport_state);
s->csmac_tobe = s->scmac_tobe = NULL;
s->cscomp_tobe = s->sccomp_tobe = NULL;
s->csmac_tobe = s->scmac_tobe = NULL;
s->cscomp_tobe = s->sccomp_tobe = NULL;
+ s->got_session_id = s->activated_authconn = FALSE;
+ /*
+ * Be prepared to work around the buggy MAC problem.
+ */
+ if (ssh->remote_bugs & BUG_SSH2_HMAC)
+ s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
+ else
+ s->maclist = macs, s->nmacs = lenof(macs);
+
+ begin_key_exchange:
+ int i, j, commalist_started;
+
/*
* Set up the preferred key exchange. (NULL => warn below here)
*/
/*
* Set up the preferred key exchange. (NULL => warn below here)
*/
/*
* Set up the preferred ciphers. (NULL => warn below here)
*/
/*
* Set up the preferred ciphers. (NULL => warn below here)
*/
- }
-
- /*
- * Set up preferred compression.
- */
- if (ssh->cfg.compression)
- s->preferred_comp = &ssh_zlib;
- else
- s->preferred_comp = &ssh_comp_none;
-
- /*
- * Be prepared to work around the buggy MAC problem.
- */
- if (ssh->remote_bugs & BUG_SSH2_HMAC)
- s->maclist = buggymacs, s->nmacs = lenof(buggymacs);
- else
- s->maclist = macs, s->nmacs = lenof(macs);
- begin_key_exchange:
- {
- int i, j, commalist_started;
+ /*
+ * Set up preferred compression.
+ */
+ if (ssh->cfg.compression)
+ s->preferred_comp = &ssh_zlib;
+ else
+ s->preferred_comp = &ssh_comp_none;
/*
* Enable queueing of outgoing auth- or connection-layer
/*
* Enable queueing of outgoing auth- or connection-layer
verify_ssh_host_key(ssh->frontend,
ssh->savedhost, ssh->savedport, ssh->hostkey->keytype,
s->keystr, s->fingerprint);
verify_ssh_host_key(ssh->frontend,
ssh->savedhost, ssh->savedport, ssh->hostkey->keytype,
s->keystr, s->fingerprint);
- if (s->first_kex) { /* don't bother logging this in rekeys */
+ if (!s->got_session_id) { /* don't bother logging this in rekeys */
logevent("Host key fingerprint is:");
logevent(s->fingerprint);
}
logevent("Host key fingerprint is:");
logevent(s->fingerprint);
}
* the session id, used in session key construction and
* authentication.
*/
* the session id, used in session key construction and
* authentication.
*/
+ if (!s->got_session_id) {
memcpy(ssh->v2_session_id, s->exchange_hash,
sizeof(s->exchange_hash));
memcpy(ssh->v2_session_id, s->exchange_hash,
sizeof(s->exchange_hash));
+ s->got_session_id = TRUE;
+ }
/*
* Send SSH2_MSG_NEWKEYS.
/*
* Send SSH2_MSG_NEWKEYS.
- * Key exchange is over. Schedule a timer for our next rekey.
+ * Key exchange is over. Loop straight back round if we have a
+ * deferred rekey reason.
+ */
+ if (ssh->deferred_rekey_reason) {
+ logevent(ssh->deferred_rekey_reason);
+ pktin = NULL;
+ ssh->deferred_rekey_reason = NULL;
+ goto begin_key_exchange;
+ }
+
+ /*
+ * Otherwise, schedule a timer for our next rekey.
*/
ssh->kex_in_progress = FALSE;
ssh->last_rekey = GETTICKCOUNT();
if (ssh->cfg.ssh_rekey_time != 0)
ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
ssh2_timer, ssh);
*/
ssh->kex_in_progress = FALSE;
ssh->last_rekey = GETTICKCOUNT();
if (ssh->cfg.ssh_rekey_time != 0)
ssh->next_rekey = schedule_timer(ssh->cfg.ssh_rekey_time*60*TICKSPERSEC,
ssh2_timer, ssh);
/*
* If this is the first key exchange phase, we must pass the
* SSH2_MSG_NEWKEYS packet to the next layer, not because it
/*
* If this is the first key exchange phase, we must pass the
* SSH2_MSG_NEWKEYS packet to the next layer, not because it
* exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
* it would only confuse the layer above.
*/
* exchange phases, we don't pass SSH2_MSG_NEWKEYS on, because
* it would only confuse the layer above.
*/
+ if (s->activated_authconn) {
+ s->activated_authconn = TRUE;
/*
* Now we're encrypting. Begin returning 1 to the protocol main
/*
* Now we're encrypting. Begin returning 1 to the protocol main
ssh->queuelen = ssh->queuesize = 0;
ssh->queueing = FALSE;
ssh->qhead = ssh->qtail = NULL;
ssh->queuelen = ssh->queuesize = 0;
ssh->queueing = FALSE;
ssh->qhead = ssh->qtail = NULL;
+ ssh->deferred_rekey_reason = NULL;
static void ssh_reconfig(void *handle, Config *cfg)
{
Ssh ssh = (Ssh) handle;
static void ssh_reconfig(void *handle, Config *cfg)
{
Ssh ssh = (Ssh) handle;
+ char *rekeying = NULL, rekey_mandatory = FALSE;
unsigned long old_max_data_size;
pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
unsigned long old_max_data_size;
pinger_reconfig(ssh->pinger, &ssh->cfg, cfg);
rekeying = "Initiating key re-exchange (data limit lowered)";
}
rekeying = "Initiating key re-exchange (data limit lowered)";
}
- if (rekeying && !ssh->kex_in_progress) {
- do_ssh2_transport(ssh, rekeying, -1, NULL);
+ if (ssh->cfg.compression != cfg->compression) {
+ rekeying = "Initiating key re-exchange (compression setting changed)";
+ rekey_mandatory = TRUE;
+ }
+
+ if (ssh->cfg.ssh2_des_cbc != cfg->ssh2_des_cbc ||
+ memcmp(ssh->cfg.ssh_cipherlist, cfg->ssh_cipherlist,
+ sizeof(ssh->cfg.ssh_cipherlist))) {
+ rekeying = "Initiating key re-exchange (cipher settings changed)";
+ rekey_mandatory = TRUE;
}
ssh->cfg = *cfg; /* STRUCTURE COPY */
}
ssh->cfg = *cfg; /* STRUCTURE COPY */
+
+ if (rekeying) {
+ if (!ssh->kex_in_progress) {
+ do_ssh2_transport(ssh, rekeying, -1, NULL);
+ } else if (rekey_mandatory) {
+ ssh->deferred_rekey_reason = rekeying;
+ }
+ }