зеркало из https://github.com/github/putty.git
Ahem. Actually _checking_ that asynchronous askalg() worked would
have been helpful. Since async verify_ssh_host_key() worked, I didn't think anything else could go wrong. How wrong I was. [originally from svn r5331]
This commit is contained in:
Родитель
8574822b9b
Коммит
fceaa2e4a7
|
@ -320,7 +320,7 @@ static void askalg_callback(void *ctx, int result)
|
|||
{
|
||||
struct algstate *state = (struct algstate *)ctx;
|
||||
|
||||
state->callback(state->ctx, result == 0);
|
||||
state->callback(state->ctx, result == NSAlertFirstButtonReturn);
|
||||
sfree(state);
|
||||
}
|
||||
|
||||
|
@ -343,7 +343,7 @@ int askalg(void *frontend, const char *algtype, const char *algname,
|
|||
state->callback = callback;
|
||||
state->ctx = ctx;
|
||||
|
||||
alert = [NSAlert alloc];
|
||||
alert = [[NSAlert alloc] init];
|
||||
[alert setInformativeText:[NSString stringWithCString:text]];
|
||||
[alert addButtonWithTitle:@"Yes"];
|
||||
[alert addButtonWithTitle:@"No"];
|
||||
|
|
|
@ -794,8 +794,28 @@ printf("n=%d c=U+%04x cm=U+%04x m=%08x\n", n, c, cm, m);
|
|||
- (void)alertSheetDidEnd:(NSAlert *)alert returnCode:(int)returnCode
|
||||
contextInfo:(void *)contextInfo
|
||||
{
|
||||
alert_callback(alert_ctx, returnCode); /* transfers ownership of ctx */
|
||||
[self performSelectorOnMainThread:
|
||||
@selector(alertSheetDidFinishEnding:)
|
||||
withObject:[NSNumber numberWithInt:returnCode]
|
||||
waitUntilDone:NO];
|
||||
}
|
||||
|
||||
- (void)alertSheetDidFinishEnding:(id)object
|
||||
{
|
||||
int returnCode = [object intValue];
|
||||
void (*this_callback)(void *, int);
|
||||
void *this_ctx;
|
||||
|
||||
/*
|
||||
* We must save the values of our alert_callback and alert_ctx
|
||||
* fields, in case they are set up again by the callback
|
||||
* function!
|
||||
*/
|
||||
this_callback = alert_callback;
|
||||
this_ctx = alert_ctx;
|
||||
alert_ctx = NULL;
|
||||
|
||||
this_callback(this_ctx, returnCode); /* transfers ownership of ctx */
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
179
ssh.c
179
ssh.c
|
@ -4827,7 +4827,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
{
|
||||
unsigned char *in = (unsigned char *)vin;
|
||||
struct do_ssh2_transport_state {
|
||||
int nbits, pbits, warn;
|
||||
int nbits, pbits, warn_kex, warn_cscipher, warn_sccipher;
|
||||
Bignum p, g, e, f, K;
|
||||
int kex_init_value, kex_reply_value;
|
||||
const struct ssh_mac **maclist;
|
||||
|
@ -4851,6 +4851,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
struct Packet *pktout;
|
||||
int dlgret;
|
||||
int guessok;
|
||||
int ignorepkt;
|
||||
};
|
||||
crState(do_ssh2_transport_state);
|
||||
|
||||
|
@ -5063,7 +5064,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
* to.
|
||||
*/
|
||||
{
|
||||
char *str;
|
||||
char *str, *preferred;
|
||||
int i, j, len;
|
||||
|
||||
if (pktin->type != SSH2_MSG_KEXINIT) {
|
||||
|
@ -5078,41 +5079,23 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
s->scmac_tobe = NULL;
|
||||
s->cscomp_tobe = NULL;
|
||||
s->sccomp_tobe = NULL;
|
||||
s->warn_kex = s->warn_cscipher = s->warn_sccipher = FALSE;
|
||||
|
||||
pktin->savedpos += 16; /* skip garbage cookie */
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* key exchange algorithms */
|
||||
s->warn = 0;
|
||||
|
||||
preferred = NULL;
|
||||
for (i = 0; i < s->n_preferred_kex; i++) {
|
||||
const struct ssh_kex *k = s->preferred_kex[i];
|
||||
if (!k) {
|
||||
s->warn = 1;
|
||||
} else if (in_commasep_string(k->name, str, len)) {
|
||||
ssh->kex = k;
|
||||
s->warn_kex = TRUE;
|
||||
} else {
|
||||
if (!preferred) preferred = k->name;
|
||||
if (in_commasep_string(k->name, str, len))
|
||||
ssh->kex = k;
|
||||
}
|
||||
if (ssh->kex) {
|
||||
if (s->warn) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
|
||||
ssh->kex->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
if (ssh->kex)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ssh->kex) {
|
||||
bombout(("Couldn't agree a key exchange algorithm (available: %s)",
|
||||
|
@ -5124,8 +5107,7 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
* the first algorithm in our list, even if it's still the algorithm
|
||||
* we end up using.
|
||||
*/
|
||||
s->guessok =
|
||||
first_in_commasep_string(s->preferred_kex[0]->name, str, len);
|
||||
s->guessok = first_in_commasep_string(preferred, str, len);
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* host key algorithms */
|
||||
for (i = 0; i < lenof(hostkey_algs); i++) {
|
||||
if (in_commasep_string(hostkey_algs[i]->name, str, len)) {
|
||||
|
@ -5136,11 +5118,10 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
s->guessok = s->guessok &&
|
||||
first_in_commasep_string(hostkey_algs[0]->name, str, len);
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* client->server cipher */
|
||||
s->warn = 0;
|
||||
for (i = 0; i < s->n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = s->preferred_ciphers[i];
|
||||
if (!c) {
|
||||
s->warn = 1;
|
||||
s->warn_cscipher = TRUE;
|
||||
} else {
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
|
@ -5149,32 +5130,8 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (s->cscipher_tobe) {
|
||||
if (s->warn) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend,
|
||||
"client-to-server cipher",
|
||||
s->cscipher_tobe->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
if (s->cscipher_tobe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!s->cscipher_tobe) {
|
||||
bombout(("Couldn't agree a client-to-server cipher (available: %s)",
|
||||
|
@ -5183,11 +5140,10 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
}
|
||||
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* server->client cipher */
|
||||
s->warn = 0;
|
||||
for (i = 0; i < s->n_preferred_ciphers; i++) {
|
||||
const struct ssh2_ciphers *c = s->preferred_ciphers[i];
|
||||
if (!c) {
|
||||
s->warn = 1;
|
||||
s->warn_sccipher = TRUE;
|
||||
} else {
|
||||
for (j = 0; j < c->nciphers; j++) {
|
||||
if (in_commasep_string(c->list[j]->name, str, len)) {
|
||||
|
@ -5196,32 +5152,8 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (s->sccipher_tobe) {
|
||||
if (s->warn) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend,
|
||||
"server-to-client cipher",
|
||||
s->sccipher_tobe->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
if (s->sccipher_tobe)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!s->sccipher_tobe) {
|
||||
bombout(("Couldn't agree a server-to-client cipher (available: %s)",
|
||||
|
@ -5263,7 +5195,80 @@ static int do_ssh2_transport(Ssh ssh, void *vin, int inlen,
|
|||
}
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* client->server language */
|
||||
ssh_pkt_getstring(pktin, &str, &len); /* server->client language */
|
||||
if (ssh2_pkt_getbool(pktin) && !s->guessok) /* first_kex_packet_follows */
|
||||
s->ignorepkt = ssh2_pkt_getbool(pktin) && !s->guessok;
|
||||
|
||||
if (s->warn_kex) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend, "key-exchange algorithm",
|
||||
ssh->kex->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->warn_cscipher) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend,
|
||||
"client-to-server cipher",
|
||||
s->cscipher_tobe->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->warn_sccipher) {
|
||||
ssh_set_frozen(ssh, 1);
|
||||
s->dlgret = askalg(ssh->frontend,
|
||||
"server-to-client cipher",
|
||||
s->sccipher_tobe->name,
|
||||
ssh_dialog_callback, ssh);
|
||||
if (s->dlgret < 0) {
|
||||
do {
|
||||
crReturn(0);
|
||||
if (pktin) {
|
||||
bombout(("Unexpected data from server while"
|
||||
" waiting for user response"));
|
||||
crStop(0);
|
||||
}
|
||||
} while (pktin || inlen > 0);
|
||||
s->dlgret = ssh->user_response;
|
||||
}
|
||||
ssh_set_frozen(ssh, 0);
|
||||
if (s->dlgret == 0) {
|
||||
ssh->close_expected = TRUE;
|
||||
ssh_closing((Plug)ssh, NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (s->ignorepkt) /* first_kex_packet_follows */
|
||||
crWaitUntil(pktin); /* Ignore packet */
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче