diff options
author | Andreas Schneider <mail@cynapses.org> | 2009-04-27 18:08:46 +0000 |
---|---|---|
committer | Andreas Schneider <mail@cynapses.org> | 2009-04-27 18:08:46 +0000 |
commit | 8dbe59efde1cc316907fb7a049279db454fb3439 (patch) | |
tree | e5ad7d9c7cd2d2c918d16944d86486a460e3ff0c /libssh/keyfiles.c | |
parent | b39fcd6470f7da6f3865120da5c4a37f2ac6dfcb (diff) | |
download | libssh-8dbe59efde1cc316907fb7a049279db454fb3439.tar.gz libssh-8dbe59efde1cc316907fb7a049279db454fb3439.tar.xz libssh-8dbe59efde1cc316907fb7a049279db454fb3439.zip |
Improve match_hashed_host.
git-svn-id: svn+ssh://svn.berlios.de/svnroot/repos/libssh/trunk@633 7dcaeef0-15fb-0310-b436-a5af3365683c
Diffstat (limited to 'libssh/keyfiles.c')
-rw-r--r-- | libssh/keyfiles.c | 136 |
1 files changed, 83 insertions, 53 deletions
diff --git a/libssh/keyfiles.c b/libssh/keyfiles.c index 0caf5b75..9aafb689 100644 --- a/libssh/keyfiles.c +++ b/libssh/keyfiles.c @@ -1204,65 +1204,95 @@ static int check_public_key(SSH_SESSION *session, char **tokens) { 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 hashed hashed value * \returns 1 if it matches * \returns 0 otherwise */ -static int match_hashed_host(SSH_SESSION *session, char *host, char *sourcehash){ - /* Openssh hash structure : - * |1|base64 encoded salt|base64 encoded hash - * hash is produced that way : - * hash := HMAC_SHA1(key=salt,data=host) - */ - char *source; - char *b64hash; - BUFFER *salt; - BUFFER *hash; - HMACCTX mac; - int match; - unsigned char buffer[256]; - unsigned int size=sizeof(buffer); - - enter_function(); - if(strncmp(sourcehash,"|1|",3) != 0) - return 0; - source=strdup(sourcehash+3); - if (source == NULL) { - leave_function(); - return 0; - } - b64hash=strchr(source,'|'); - if(!b64hash){ - /* Invalid hash */ - SAFE_FREE(source); - leave_function(); - return 0; - } - *b64hash='\0'; - b64hash++; - salt=base64_to_bin(source); - hash=base64_to_bin(b64hash); - free(source); - mac=hmac_init(buffer_get(salt),buffer_get_len(salt),HMAC_SHA1); - if (mac == NULL) { - SAFE_FREE(source); - leave_function(); - return 0; - } - 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; +static int match_hashed_host(SSH_SESSION *session, const char *host, + const char *sourcehash) { + /* Openssh hash structure : + * |1|base64 encoded salt|base64 encoded hash + * hash is produced that way : + * hash := HMAC_SHA1(key=salt,data=host) + */ + unsigned char buffer[256] = {0}; + BUFFER *salt; + BUFFER *hash; + HMACCTX mac; + char *source; + char *b64hash; + int match; + unsigned int size; + + enter_function(); + + if (strncmp(sourcehash, "|1|", 3) != 0) { + return 0; + } + + source = strdup(sourcehash + 3); + if (source == NULL) { + leave_function(); + return 0; + } + + b64hash = strchr(source, '|'); + if (b64hash == NULL) { + /* Invalid hash */ + SAFE_FREE(source); + leave_function(); + return 0; + } + + *b64hash = '\0'; + b64hash++; + + salt = base64_to_bin(source); + if (salt == NULL) { + SAFE_FREE(source); + leave_function(); + return 0; + } + SAFE_FREE(source); + + hash = base64_to_bin(b64hash); + if (hash == NULL) { + buffer_free(salt); + leave_function(); + return 0; + } + + 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 : * 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: |