version 1.112, 2015/11/13 04:39:35 |
version 1.113, 2015/12/04 16:41:28 |
|
|
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); |
ssh_dispatch_set(ssh, SSH2_MSG_KEXINIT, &kex_input_kexinit); |
} |
} |
|
|
|
static int |
|
kex_send_ext_info(struct ssh *ssh) |
|
{ |
|
int r; |
|
|
|
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 || |
|
(r = sshpkt_put_u32(ssh, 1)) != 0 || |
|
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 || |
|
(r = sshpkt_put_cstring(ssh, "rsa-sha2-256,rsa-sha2-512")) != 0 || |
|
(r = sshpkt_send(ssh)) != 0) |
|
return r; |
|
return 0; |
|
} |
|
|
int |
int |
kex_send_newkeys(struct ssh *ssh) |
kex_send_newkeys(struct ssh *ssh) |
{ |
{ |
|
|
debug("SSH2_MSG_NEWKEYS sent"); |
debug("SSH2_MSG_NEWKEYS sent"); |
debug("expecting SSH2_MSG_NEWKEYS"); |
debug("expecting SSH2_MSG_NEWKEYS"); |
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); |
ssh_dispatch_set(ssh, SSH2_MSG_NEWKEYS, &kex_input_newkeys); |
|
if (ssh->kex->ext_info_c) |
|
if ((r = kex_send_ext_info(ssh)) != 0) |
|
return r; |
return 0; |
return 0; |
} |
} |
|
|
|
int |
|
kex_input_ext_info(int type, u_int32_t seq, void *ctxt) |
|
{ |
|
struct ssh *ssh = ctxt; |
|
struct kex *kex = ssh->kex; |
|
u_int32_t i, ninfo; |
|
char *name, *val, *found; |
|
int r; |
|
|
|
debug("SSH2_MSG_EXT_INFO received"); |
|
ssh_dispatch_set(ssh, SSH2_MSG_EXT_INFO, &kex_protocol_error); |
|
if ((r = sshpkt_get_u32(ssh, &ninfo)) != 0) |
|
return r; |
|
for (i = 0; i < ninfo; i++) { |
|
if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0) |
|
return r; |
|
if ((r = sshpkt_get_cstring(ssh, &val, NULL)) != 0) { |
|
free(name); |
|
return r; |
|
} |
|
debug("%s: %s=<%s>", __func__, name, val); |
|
if (strcmp(name, "server-sig-algs") == 0) { |
|
found = match_list("rsa-sha2-256", val, NULL); |
|
if (found) { |
|
kex->rsa_sha2 = 256; |
|
free(found); |
|
} |
|
found = match_list("rsa-sha2-512", val, NULL); |
|
if (found) { |
|
kex->rsa_sha2 = 512; |
|
free(found); |
|
} |
|
} |
|
free(name); |
|
free(val); |
|
} |
|
return sshpkt_get_end(ssh); |
|
} |
|
|
static int |
static int |
kex_input_newkeys(int type, u_int32_t seq, void *ctxt) |
kex_input_newkeys(int type, u_int32_t seq, void *ctxt) |
{ |
{ |
|
|
free(kex->client_version_string); |
free(kex->client_version_string); |
free(kex->server_version_string); |
free(kex->server_version_string); |
free(kex->failed_choice); |
free(kex->failed_choice); |
|
free(kex->hostkey_alg); |
|
free(kex->name); |
free(kex); |
free(kex); |
} |
} |
|
|
|
|
static int |
static int |
choose_hostkeyalg(struct kex *k, char *client, char *server) |
choose_hostkeyalg(struct kex *k, char *client, char *server) |
{ |
{ |
char *hostkeyalg = match_list(client, server, NULL); |
k->hostkey_alg = match_list(client, server, NULL); |
|
|
debug("kex: host key algorithm: %s", |
debug("kex: host key algorithm: %s", |
hostkeyalg ? hostkeyalg : "(no match)"); |
k->hostkey_alg ? k->hostkey_alg : "(no match)"); |
if (hostkeyalg == NULL) |
if (k->hostkey_alg == NULL) |
return SSH_ERR_NO_HOSTKEY_ALG_MATCH; |
return SSH_ERR_NO_HOSTKEY_ALG_MATCH; |
k->hostkey_type = sshkey_type_from_name(hostkeyalg); |
k->hostkey_type = sshkey_type_from_name(k->hostkey_alg); |
if (k->hostkey_type == KEY_UNSPEC) |
if (k->hostkey_type == KEY_UNSPEC) |
return SSH_ERR_INTERNAL_ERROR; |
return SSH_ERR_INTERNAL_ERROR; |
k->hostkey_nid = sshkey_ecdsa_nid_from_name(hostkeyalg); |
k->hostkey_nid = sshkey_ecdsa_nid_from_name(k->hostkey_alg); |
free(hostkeyalg); |
|
return 0; |
return 0; |
} |
} |
|
|
|
|
if (roaming) { |
if (roaming) { |
kex->roaming = 1; |
kex->roaming = 1; |
free(roaming); |
free(roaming); |
|
} |
|
} |
|
|
|
/* Check whether client supports ext_info_c */ |
|
if (kex->server) { |
|
char *ext; |
|
|
|
ext = match_list("ext-info-c", peer[PROPOSAL_KEX_ALGS], NULL); |
|
if (ext) { |
|
kex->ext_info_c = 1; |
|
free(ext); |
} |
} |
} |
} |
|
|