mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
doc: Updated guided tour for knownhosts changes
Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
@@ -158,7 +158,7 @@ you just connected to is known and safe to use (remember, SSH is about security
|
|||||||
authentication).
|
authentication).
|
||||||
|
|
||||||
There are two ways of doing this:
|
There are two ways of doing this:
|
||||||
- The first way (recommended) is to use the ssh_is_server_known()
|
- The first way (recommended) is to use the ssh_session_is_known_server()
|
||||||
function. This function will look into the known host file
|
function. This function will look into the known host file
|
||||||
(~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
|
(~/.ssh/known_hosts on UNIX), look for the server hostname's pattern,
|
||||||
and determine whether this host is present or not in the list.
|
and determine whether this host is present or not in the list.
|
||||||
@@ -185,74 +185,89 @@ examples/ directory:
|
|||||||
|
|
||||||
int verify_knownhost(ssh_session session)
|
int verify_knownhost(ssh_session session)
|
||||||
{
|
{
|
||||||
int state, hlen;
|
enum ssh_known_hosts_e state;
|
||||||
unsigned char *hash = NULL;
|
unsigned char *hash = NULL;
|
||||||
char *hexa;
|
ssh_key srv_pubkey = NULL;
|
||||||
char buf[10];
|
size_t hlen;
|
||||||
|
char buf[10];
|
||||||
|
char *hexa;
|
||||||
|
char *p;
|
||||||
|
int cmp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
state = ssh_is_server_known(session);
|
rc = ssh_get_server_publickey(session, &srv_pubkey);
|
||||||
|
if (rc < 0) {
|
||||||
hlen = ssh_get_pubkey_hash(session, &hash);
|
|
||||||
if (hlen < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case SSH_SERVER_KNOWN_OK:
|
|
||||||
break; /* ok */
|
|
||||||
|
|
||||||
case SSH_SERVER_KNOWN_CHANGED:
|
|
||||||
fprintf(stderr, "Host key for server changed: it is now:\n");
|
|
||||||
ssh_print_hexa("Public key hash", hash, hlen);
|
|
||||||
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
|
||||||
free(hash);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case SSH_SERVER_FOUND_OTHER:
|
|
||||||
fprintf(stderr, "The host key for this server was not found but an other"
|
|
||||||
"type of key exists.\n");
|
|
||||||
fprintf(stderr, "An attacker might change the default server key to"
|
|
||||||
"confuse your client into thinking the key does not exist\n");
|
|
||||||
free(hash);
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
case SSH_SERVER_FILE_NOT_FOUND:
|
|
||||||
fprintf(stderr, "Could not find known host file.\n");
|
|
||||||
fprintf(stderr, "If you accept the host key here, the file will be"
|
|
||||||
"automatically created.\n");
|
|
||||||
/* fallback to SSH_SERVER_NOT_KNOWN behavior */
|
|
||||||
|
|
||||||
case SSH_SERVER_NOT_KNOWN:
|
|
||||||
hexa = ssh_get_hexa(hash, hlen);
|
|
||||||
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
|
||||||
fprintf(stderr, "Public key hash: %s\n", hexa);
|
|
||||||
free(hexa);
|
|
||||||
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
|
||||||
{
|
|
||||||
free(hash);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (strncasecmp(buf, "yes", 3) != 0)
|
|
||||||
{
|
|
||||||
free(hash);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (ssh_write_knownhost(session) < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Error %s\n", strerror(errno));
|
|
||||||
free(hash);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SSH_SERVER_ERROR:
|
rc = ssh_get_publickey_hash(srv_pubkey,
|
||||||
fprintf(stderr, "Error %s", ssh_get_error(session));
|
SSH_PUBLICKEY_HASH_SHA1,
|
||||||
free(hash);
|
&hash,
|
||||||
return -1;
|
&hlen);
|
||||||
}
|
ssh_key_free(srv_pubkey);
|
||||||
|
if (rc < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
free(hash);
|
state = ssh_session_is_known_server(session);
|
||||||
return 0;
|
switch (state) {
|
||||||
|
case SSH_KNOWN_HOSTS_OK:
|
||||||
|
/* OK */
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_KNOWN_HOSTS_CHANGED:
|
||||||
|
fprintf(stderr, "Host key for server changed: it is now:\n");
|
||||||
|
ssh_print_hexa("Public key hash", hash, hlen);
|
||||||
|
fprintf(stderr, "For security reasons, connection will be stopped\n");
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
case SSH_KNOWN_HOSTS_OTHER:
|
||||||
|
fprintf(stderr, "The host key for this server was not found but an other"
|
||||||
|
"type of key exists.\n");
|
||||||
|
fprintf(stderr, "An attacker might change the default server key to"
|
||||||
|
"confuse your client into thinking the key does not exist\n");
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
case SSH_KNOWN_HOSTS_NOT_FOUND:
|
||||||
|
fprintf(stderr, "Could not find known host file.\n");
|
||||||
|
fprintf(stderr, "If you accept the host key here, the file will be"
|
||||||
|
"automatically created.\n");
|
||||||
|
|
||||||
|
/* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */
|
||||||
|
|
||||||
|
case SSH_KNOWN_HOSTS_UNKNOWN:
|
||||||
|
hexa = ssh_get_hexa(hash, hlen);
|
||||||
|
fprintf(stderr,"The server is unknown. Do you trust the host key?\n");
|
||||||
|
fprintf(stderr, "Public key hash: %s\n", hexa);
|
||||||
|
ssh_string_free_char(hexa);
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
p = fgets(buf, sizeof(buf), stdin);
|
||||||
|
if (p == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmp = strncasecmp(buf, "yes", 3);
|
||||||
|
if (cmp != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = ssh_session_update_known_hosts(session);
|
||||||
|
if (rc < 0) {
|
||||||
|
fprintf(stderr, "Error %s\n", strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case SSH_KNOWN_HOSTS_ERROR:
|
||||||
|
fprintf(stderr, "Error %s", ssh_get_error(session));
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssh_clean_pubkey_hash(&hash);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
@endcode
|
@endcode
|
||||||
|
|
||||||
@@ -260,9 +275,10 @@ int verify_knownhost(ssh_session session)
|
|||||||
@see ssh_disconnect
|
@see ssh_disconnect
|
||||||
@see ssh_get_error
|
@see ssh_get_error
|
||||||
@see ssh_get_error_code
|
@see ssh_get_error_code
|
||||||
@see ssh_get_pubkey_hash
|
@see ssh_get_server_publickey
|
||||||
@see ssh_is_server_known
|
@see ssh_get_publickey_hash
|
||||||
@see ssh_write_knownhost
|
@see ssh_session_is_known_server
|
||||||
|
@see ssh_session_update_known_hosts
|
||||||
|
|
||||||
|
|
||||||
@subsection auth Authenticating the user
|
@subsection auth Authenticating the user
|
||||||
|
|||||||
Reference in New Issue
Block a user