Blame examples/knownhosts.c

Packit Service 31306d
/*
Packit Service 31306d
 * knownhosts.c
Packit Service 31306d
 * This file contains an example of how verify the identity of a
Packit Service 31306d
 * SSH server using libssh
Packit Service 31306d
 */
Packit Service 31306d
Packit Service 31306d
/*
Packit Service 31306d
Copyright 2003-2009 Aris Adamantiadis
Packit Service 31306d
Packit Service 31306d
This file is part of the SSH Library
Packit Service 31306d
Packit Service 31306d
You are free to copy this file, modify it in any way, consider it being public
Packit Service 31306d
domain. This does not apply to the rest of the library though, but it is
Packit Service 31306d
allowed to cut-and-paste working code from this file to any license of
Packit Service 31306d
program.
Packit Service 31306d
The goal is to show the API in action. It's not a reference on how terminal
Packit Service 31306d
clients must be made or how a client should react.
Packit Service 31306d
 */
Packit Service 31306d
Packit Service 31306d
#include "config.h"
Packit Service 31306d
Packit Service 31306d
#include <errno.h>
Packit Service 31306d
#include <stdio.h>
Packit Service 31306d
#include <stdlib.h>
Packit Service 31306d
#include <string.h>
Packit Service 31306d
Packit Service 31306d
#include "libssh/priv.h"
Packit Service 31306d
#include <libssh/libssh.h>
Packit Service 31306d
#include "examples_common.h"
Packit Service 31306d
Packit Service 31306d
#ifdef _WIN32
Packit Service 31306d
#define strncasecmp _strnicmp
Packit Service 31306d
#endif
Packit Service 31306d
Packit Service 31306d
int verify_knownhost(ssh_session session)
Packit Service 31306d
{
Packit Service 31306d
    enum ssh_known_hosts_e state;
Packit Service 31306d
    char buf[10];
Packit Service 31306d
    unsigned char *hash = NULL;
Packit Service 31306d
    size_t hlen;
Packit Service 31306d
    ssh_key srv_pubkey;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    rc = ssh_get_server_publickey(session, &srv_pubkey);
Packit Service 31306d
    if (rc < 0) {
Packit Service 31306d
        return -1;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    rc = ssh_get_publickey_hash(srv_pubkey,
Packit Service 31306d
                                SSH_PUBLICKEY_HASH_SHA256,
Packit Service 31306d
                                &hash,
Packit Service 31306d
                                &hlen);
Packit Service 31306d
    ssh_key_free(srv_pubkey);
Packit Service 31306d
    if (rc < 0) {
Packit Service 31306d
        return -1;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    state = ssh_session_is_known_server(session);
Packit Service 31306d
Packit Service 31306d
    switch(state) {
Packit Service 31306d
    case SSH_KNOWN_HOSTS_CHANGED:
Packit Service 31306d
        fprintf(stderr,"Host key for server changed : server's one is now :\n");
Packit Service 31306d
        ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
Packit Service 31306d
        ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
        fprintf(stderr,"For security reason, connection will be stopped\n");
Packit Service 31306d
        return -1;
Packit Service 31306d
    case SSH_KNOWN_HOSTS_OTHER:
Packit Service 31306d
        fprintf(stderr,"The host key for this server was not found but an other type of key exists.\n");
Packit Service 31306d
        fprintf(stderr,"An attacker might change the default server key to confuse your client"
Packit Service 31306d
                "into thinking the key does not exist\n"
Packit Service 31306d
                "We advise you to rerun the client with -d or -r for more safety.\n");
Packit Service 31306d
        return -1;
Packit Service 31306d
    case SSH_KNOWN_HOSTS_NOT_FOUND:
Packit Service 31306d
        fprintf(stderr,"Could not find known host file. If you accept the host key here,\n");
Packit Service 31306d
        fprintf(stderr,"the file will be automatically created.\n");
Packit Service 31306d
        /* fallback to SSH_SERVER_NOT_KNOWN behavior */
Packit Service 31306d
        FALL_THROUGH;
Packit Service 31306d
    case SSH_SERVER_NOT_KNOWN:
Packit Service 31306d
        fprintf(stderr,
Packit Service 31306d
                "The server is unknown. Do you trust the host key (yes/no)?\n");
Packit Service 31306d
        ssh_print_hash(SSH_PUBLICKEY_HASH_SHA256, hash, hlen);
Packit Service 31306d
Packit Service 31306d
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
Packit Service 31306d
            ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
            return -1;
Packit Service 31306d
        }
Packit Service 31306d
        if(strncasecmp(buf,"yes",3)!=0){
Packit Service 31306d
            ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
            return -1;
Packit Service 31306d
        }
Packit Service 31306d
        fprintf(stderr,"This new key will be written on disk for further usage. do you agree ?\n");
Packit Service 31306d
        if (fgets(buf, sizeof(buf), stdin) == NULL) {
Packit Service 31306d
            ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
            return -1;
Packit Service 31306d
        }
Packit Service 31306d
        if(strncasecmp(buf,"yes",3)==0){
Packit Service 31306d
            rc = ssh_session_update_known_hosts(session);
Packit Service 31306d
            if (rc != SSH_OK) {
Packit Service 31306d
                ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
                fprintf(stderr, "error %s\n", strerror(errno));
Packit Service 31306d
                return -1;
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        break;
Packit Service 31306d
    case SSH_KNOWN_HOSTS_ERROR:
Packit Service 31306d
        ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
        fprintf(stderr,"%s",ssh_get_error(session));
Packit Service 31306d
        return -1;
Packit Service 31306d
    case SSH_KNOWN_HOSTS_OK:
Packit Service 31306d
        break; /* ok */
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    ssh_clean_pubkey_hash(&hash);
Packit Service 31306d
Packit Service 31306d
    return 0;
Packit Service 31306d
}