ssh: move the fingerprint checking code to a separate fnc

This commit is contained in:
Kamil Dudka 2012-09-12 16:06:18 +02:00
parent a34197ef77
commit ce515e993f
1 changed files with 39 additions and 32 deletions

View File

@ -639,6 +639,43 @@ static CURLcode ssh_knownhost(struct connectdata *conn)
return result;
}
static bool ssh_check_fingerprint(struct connectdata *conn)
{
struct ssh_conn *sshc = &conn->proto.sshc;
struct SessionHandle *data = conn->data;
const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
char md5buffer[33];
int i;
const char *fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
LIBSSH2_HOSTKEY_HASH_MD5);
/* The fingerprint points to static storage (!), don't free() it. */
for(i = 0; i < 16; i++)
snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
/* Before we authenticate we check the hostkey's MD5 fingerprint
* against a known fingerprint, if available.
*/
if(pubkey_md5 && strlen(pubkey_md5) == 32) {
if(!strequal(md5buffer, pubkey_md5)) {
failf(data,
"Denied establishing ssh session: mismatch md5 fingerprint. "
"Remote %s is not equal to %s", md5buffer, pubkey_md5);
state(conn, SSH_SESSION_FREE);
sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
return sshc->actualcode;
}
else {
infof(data, "MD5 checksum match!\n");
/* as we already matched, we skip the check for known hosts */
return CURLE_OK;
}
}
else
return ssh_knownhost(conn);
}
/*
* ssh_statemach_act() runs the SSH state machine as far as it can without
@ -654,10 +691,8 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
struct SSHPROTO *sftp_scp = data->state.proto.ssh;
struct ssh_conn *sshc = &conn->proto.sshc;
curl_socket_t sock = conn->sock[FIRSTSOCKET];
const char *fingerprint;
char md5buffer[33];
char *new_readdir_line;
int rc = LIBSSH2_ERROR_NONE, i;
int rc = LIBSSH2_ERROR_NONE;
int err;
int seekerr = CURL_SEEKFUNC_OK;
*block = 0; /* we're not blocking by default */
@ -698,35 +733,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block)
* against our known hosts. How that is handled (reading from file,
* whatever) is up to us.
*/
fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
LIBSSH2_HOSTKEY_HASH_MD5);
/* The fingerprint points to static storage (!), don't free() it. */
for(i = 0; i < 16; i++)
snprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
infof(data, "SSH MD5 fingerprint: %s\n", md5buffer);
/* Before we authenticate we check the hostkey's MD5 fingerprint
* against a known fingerprint, if available.
*/
if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
if(!strequal(md5buffer,
data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
failf(data,
"Denied establishing ssh session: mismatch md5 fingerprint. "
"Remote %s is not equal to %s",
md5buffer, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
state(conn, SSH_SESSION_FREE);
result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
}
else
infof(data, "MD5 checksum match!\n");
/* as we already matched, we skip the check for known hosts */
}
else
result = ssh_knownhost(conn);
result = ssh_check_fingerprint(conn);
if(!result)
state(conn, SSH_AUTHLIST);
break;