1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-30 13:01:23 +03:00

Improve ssh_is_server_known.

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

View File

@@ -1301,76 +1301,107 @@ static int match_hashed_host(SSH_SESSION *session, const char *host,
* - there's no match : no change
*/
/** checks the user's known host file for a previous connection to the
/**
* \brief Check if the server is known.
* Checks the user's known host file for a previous connection to the
* current server.
* \brief test if the server is known
*
* \param session ssh session
* \return SSH_SERVER_KNOWN_OK : the server is known and has not changed\n
* SSH_SERVER_KNOWN_CHANGED : The server key has changed. Either you are under
* attack or the administrator changed the key. you HAVE to warn the user about
*
* \return SSH_SERVER_KNOWN_OK: The server is known and has not changed\n
* SSH_SERVER_KNOWN_CHANGED: The server key has changed. Either you are
* under attack or the administrator changed
* the key. You HAVE to warn the user about
* a possible attack\n
* SSH_SERVER_FOUND_OTHER : the server gave use a key of a type while we
* had an other type recorded. It is a possible attack \n
* SSH_SERVER_NOT_KNOWN : the server is unknown. User should confirm the MD5 is correct\n
* SSH_SERVER_FOUND_OTHER: The server gave use a key of a type while
* we had an other type recorded. It is a
* possible attack \n
* SSH_SERVER_NOT_KNOWN: The server is unknown. User should confirm
* the MD5 is correct\n
* SSH_SERVER_ERROR: Some error happened
*
* \see ssh_options_set_wanted_algo()
* \see ssh_get_pubkey_hash()
* \bug there is no current way to remove or modify an entry into the known host table
*
* \bug There is no current way to remove or modify an entry into the known
* host table.
*/
int ssh_is_server_known(SSH_SESSION *session) {
FILE *file = NULL;
char **tokens;
char *host;
const char *type;
int match;
FILE *file=NULL;
int ret = SSH_SERVER_NOT_KNOWN;
enter_function();
ssh_options_default_known_hosts_file(session->options);
if(!session->options->host){
ssh_set_error(session,SSH_FATAL,"Can't verify host in known hosts if the hostname isn't known");
if (ssh_options_default_known_hosts_file(session->options) < 0) {
ssh_set_error(session, SSH_FATAL,
"Can't find a known_hosts file");
leave_function();
return SSH_SERVER_ERROR;
}
if (session->options->host == NULL) {
ssh_set_error(session, SSH_FATAL,
"Can't verify host in known hosts if the hostname isn't known");
leave_function();
return SSH_SERVER_ERROR;
}
host = lowercase(session->options->host);
if (host == NULL) {
ssh_set_error(session, SSH_FATAL, "Not enough space!");
leave_function();
return SSH_SERVER_ERROR;
}
do {
tokens=ssh_get_knownhost_line(session,&file,session->options->known_hosts_file,&type);
//
tokens = ssh_get_knownhost_line(session, &file,
session->options->known_hosts_file, &type);
/* End of file, return the current state */
if(tokens==NULL)
if (tokens == NULL) {
break;
}
match = match_hashed_host(session, host, tokens[0]);
if(!match)
if (match == 0) {
match = match_hostname(host, tokens[0], strlen(tokens[0]));
}
if (match) {
// We got a match. Now check the key type
/* We got a match. Now check the key type */
if (strcmp(session->current_crypto->server_pubkey_type, type) != 0) {
// different type. We don't override the known_changed error which is more important
/* Different type. We don't override the known_changed error which is
* more important */
if (ret != SSH_SERVER_KNOWN_CHANGED)
ret = SSH_SERVER_FOUND_OTHER;
tokens_free(tokens);
continue;
}
// so we know the key type is good. We may get a good key or a bad key.
/* so we know the key type is good. We may get a good key or a bad key. */
match = check_public_key(session, tokens);
tokens_free(tokens);
if (match < 0) {
ret = SSH_SERVER_ERROR;
break;
}
if(match==1){
} else if (match == 1) {
ret = SSH_SERVER_KNOWN_OK;
break;
}
if(match==0){
} else if(match == 0) {
/* We override the status with the wrong key state */
ret = SSH_SERVER_KNOWN_CHANGED;
}
}
} while (1);
SAFE_FREE(host);
if(file)
if (file != NULL) {
fclose(file);
}
/* Return the current state at end of file */
leave_function();
return ret;