aboutsummaryrefslogtreecommitdiff
path: root/libssh/keyfiles.c
diff options
context:
space:
mode:
authorAndreas Schneider <mail@cynapses.org>2009-04-27 18:08:46 +0000
committerAndreas Schneider <mail@cynapses.org>2009-04-27 18:08:46 +0000
commit8dbe59efde1cc316907fb7a049279db454fb3439 (patch)
treee5ad7d9c7cd2d2c918d16944d86486a460e3ff0c /libssh/keyfiles.c
parentb39fcd6470f7da6f3865120da5c4a37f2ac6dfcb (diff)
downloadlibssh-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.c136
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: