Improve match_hashed_host.

git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@633 7dcaeef0-15fb-0310-b436-a5af3365683c
This commit is contained in:
Andreas Schneider
2009-04-27 18:08:46 +00:00
parent b39fcd6470
commit 8dbe59efde

View File

@@ -1204,65 +1204,95 @@ static int check_public_key(SSH_SESSION *session, char **tokens) {
return 1; return 1;
} }
/** \brief checks if a hostname matches a openssh-style hashed known host /**
* \brief checks if a hostname matches a openssh-style hashed known host
* \param host host to check * \param host host to check
* \param hashed hashed value * \param hashed hashed value
* \returns 1 if it matches * \returns 1 if it matches
* \returns 0 otherwise * \returns 0 otherwise
*/ */
static int match_hashed_host(SSH_SESSION *session, char *host, char *sourcehash){ static int match_hashed_host(SSH_SESSION *session, const char *host,
/* Openssh hash structure : const char *sourcehash) {
* |1|base64 encoded salt|base64 encoded hash /* Openssh hash structure :
* hash is produced that way : * |1|base64 encoded salt|base64 encoded hash
* hash := HMAC_SHA1(key=salt,data=host) * hash is produced that way :
*/ * hash := HMAC_SHA1(key=salt,data=host)
char *source; */
char *b64hash; unsigned char buffer[256] = {0};
BUFFER *salt; BUFFER *salt;
BUFFER *hash; BUFFER *hash;
HMACCTX mac; HMACCTX mac;
int match; char *source;
unsigned char buffer[256]; char *b64hash;
unsigned int size=sizeof(buffer); int match;
unsigned int size;
enter_function(); enter_function();
if(strncmp(sourcehash,"|1|",3) != 0)
return 0; if (strncmp(sourcehash, "|1|", 3) != 0) {
source=strdup(sourcehash+3); return 0;
if (source == NULL) { }
leave_function();
return 0; source = strdup(sourcehash + 3);
} if (source == NULL) {
b64hash=strchr(source,'|'); leave_function();
if(!b64hash){ return 0;
/* Invalid hash */ }
SAFE_FREE(source);
leave_function(); b64hash = strchr(source, '|');
return 0; if (b64hash == NULL) {
} /* Invalid hash */
*b64hash='\0'; SAFE_FREE(source);
b64hash++; leave_function();
salt=base64_to_bin(source); return 0;
hash=base64_to_bin(b64hash); }
free(source);
mac=hmac_init(buffer_get(salt),buffer_get_len(salt),HMAC_SHA1); *b64hash = '\0';
if (mac == NULL) { b64hash++;
SAFE_FREE(source);
leave_function(); salt = base64_to_bin(source);
return 0; if (salt == NULL) {
} SAFE_FREE(source);
hmac_update(mac,host,strlen(host)); leave_function();
hmac_final(mac,buffer,&size); return 0;
if(size == buffer_get_len(hash) && memcmp(buffer,buffer_get(hash),size)==0) }
match=1; SAFE_FREE(source);
else
match=0; hash = base64_to_bin(b64hash);
buffer_free(salt); if (hash == NULL) {
buffer_free(hash); buffer_free(salt);
ssh_log(session,SSH_LOG_PACKET,"Matching a hashed host : %s match=%d",host,match); leave_function();
leave_function(); return 0;
return match; }
mac = hmac_init(buffer_get(salt), buffer_get_len(salt), HMAC_SHA1);
if (mac == NULL) {
buffer_free(salt);
buffer_free(hash);
leave_function();
return 0;
}
size = sizeof(buffer);
hmac_update(mac, host, strlen(host));
hmac_final(mac, buffer, &size);
if (size == buffer_get_len(hash) &&
memcmp(buffer, buffer_get(hash), size) == 0) {
match = 1;
} else {
match = 0;
}
buffer_free(salt);
buffer_free(hash);
ssh_log(session, SSH_LOG_PACKET,
"Matching a hashed host: %s match=%d", host, match);
leave_function();
return match;
} }
/* How it's working : /* How it's working :
* 1- we open the known host file and bitch if it doesn't exist * 1- we open the known host file and bitch if it doesn't exist
* 2- we need to examine each line of the file, until going on state SSH_SERVER_KNOWN_OK: * 2- we need to examine each line of the file, until going on state SSH_SERVER_KNOWN_OK: