Blame examples/authentication.c

Packit Service 31306d
/*
Packit Service 31306d
 * authentication.c
Packit Service 31306d
 * This file contains an example of how to do an authentication to 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 <stdio.h>
Packit Service 31306d
#include <stdlib.h>
Packit Service 31306d
#include <string.h>
Packit Service 31306d
Packit Service 31306d
#include <libssh/libssh.h>
Packit Service 31306d
#include "examples_common.h"
Packit Service 31306d
Packit Service 31306d
int authenticate_kbdint(ssh_session session, const char *password)
Packit Service 31306d
{
Packit Service 31306d
    int err;
Packit Service 31306d
Packit Service 31306d
    err = ssh_userauth_kbdint(session, NULL, NULL);
Packit Service 31306d
    while (err == SSH_AUTH_INFO) {
Packit Service 31306d
        const char *instruction;
Packit Service 31306d
        const char *name;
Packit Service 31306d
        char buffer[128];
Packit Service 31306d
        int i, n;
Packit Service 31306d
Packit Service 31306d
        name = ssh_userauth_kbdint_getname(session);
Packit Service 31306d
        instruction = ssh_userauth_kbdint_getinstruction(session);
Packit Service 31306d
        n = ssh_userauth_kbdint_getnprompts(session);
Packit Service 31306d
Packit Service 31306d
        if (name && strlen(name) > 0) {
Packit Service 31306d
            printf("%s\n", name);
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        if (instruction && strlen(instruction) > 0) {
Packit Service 31306d
            printf("%s\n", instruction);
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        for (i = 0; i < n; i++) {
Packit Service 31306d
            const char *answer;
Packit Service 31306d
            const char *prompt;
Packit Service 31306d
            char echo;
Packit Service 31306d
Packit Service 31306d
            prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
Packit Service 31306d
            if (prompt == NULL) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
Packit Service 31306d
            if (echo) {
Packit Service 31306d
                char *p;
Packit Service 31306d
Packit Service 31306d
                printf("%s", prompt);
Packit Service 31306d
Packit Service 31306d
                if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit Service 31306d
                    return SSH_AUTH_ERROR;
Packit Service 31306d
                }
Packit Service 31306d
Packit Service 31306d
                buffer[sizeof(buffer) - 1] = '\0';
Packit Service 31306d
                if ((p = strchr(buffer, '\n'))) {
Packit Service 31306d
                    *p = '\0';
Packit Service 31306d
                }
Packit Service 31306d
Packit Service 31306d
                if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
Packit Service 31306d
                    return SSH_AUTH_ERROR;
Packit Service 31306d
                }
Packit Service 31306d
Packit Service 31306d
                memset(buffer, 0, strlen(buffer));
Packit Service 31306d
            } else {
Packit Service 31306d
                if (password && strstr(prompt, "Password:")) {
Packit Service 31306d
                    answer = password;
Packit Service 31306d
                } else {
Packit Service 31306d
                    buffer[0] = '\0';
Packit Service 31306d
Packit Service 31306d
                    if (ssh_getpass(prompt, buffer, sizeof(buffer), 0, 0) < 0) {
Packit Service 31306d
                        return SSH_AUTH_ERROR;
Packit Service 31306d
                    }
Packit Service 31306d
                    answer = buffer;
Packit Service 31306d
                }
Packit Service 31306d
                err = ssh_userauth_kbdint_setanswer(session, i, answer);
Packit Service 31306d
                memset(buffer, 0, sizeof(buffer));
Packit Service 31306d
                if (err < 0) {
Packit Service 31306d
                    return SSH_AUTH_ERROR;
Packit Service 31306d
                }
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
        err=ssh_userauth_kbdint(session,NULL,NULL);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return err;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static int auth_keyfile(ssh_session session, char* keyfile)
Packit Service 31306d
{
Packit Service 31306d
    ssh_key key = NULL;
Packit Service 31306d
    char pubkey[132] = {0}; // +".pub"
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    snprintf(pubkey, sizeof(pubkey), "%s.pub", keyfile);
Packit Service 31306d
Packit Service 31306d
    rc = ssh_pki_import_pubkey_file( pubkey, &key);
Packit Service 31306d
Packit Service 31306d
    if (rc != SSH_OK)
Packit Service 31306d
        return SSH_AUTH_DENIED;
Packit Service 31306d
Packit Service 31306d
    rc = ssh_userauth_try_publickey(session, NULL, key);
Packit Service 31306d
Packit Service 31306d
    ssh_key_free(key);
Packit Service 31306d
Packit Service 31306d
    if (rc!=SSH_AUTH_SUCCESS)
Packit Service 31306d
        return SSH_AUTH_DENIED;
Packit Service 31306d
Packit Service 31306d
    rc = ssh_pki_import_privkey_file(keyfile, NULL, NULL, NULL, &key);
Packit Service 31306d
Packit Service 31306d
    if (rc != SSH_OK)
Packit Service 31306d
        return SSH_AUTH_DENIED;
Packit Service 31306d
Packit Service 31306d
    rc = ssh_userauth_publickey(session, NULL, key);
Packit Service 31306d
Packit Service 31306d
    ssh_key_free(key);
Packit Service 31306d
Packit Service 31306d
    return rc;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
Packit Service 31306d
static void error(ssh_session session)
Packit Service 31306d
{
Packit Service 31306d
    fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
int authenticate_console(ssh_session session)
Packit Service 31306d
{
Packit Service 31306d
    int rc;
Packit Service 31306d
    int method;
Packit Service 31306d
    char password[128] = {0};
Packit Service 31306d
    char *banner;
Packit Service 31306d
Packit Service 31306d
    // Try to authenticate
Packit Service 31306d
    rc = ssh_userauth_none(session, NULL);
Packit Service 31306d
    if (rc == SSH_AUTH_ERROR) {
Packit Service 31306d
        error(session);
Packit Service 31306d
        return rc;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    method = ssh_userauth_list(session, NULL);
Packit Service 31306d
    while (rc != SSH_AUTH_SUCCESS) {
Packit Service 31306d
        if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
Packit Service 31306d
            rc = ssh_userauth_gssapi(session);
Packit Service 31306d
            if(rc == SSH_AUTH_ERROR) {
Packit Service 31306d
                error(session);
Packit Service 31306d
                return rc;
Packit Service 31306d
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
        // Try to authenticate with public key first
Packit Service 31306d
        if (method & SSH_AUTH_METHOD_PUBLICKEY) {
Packit Service 31306d
            rc = ssh_userauth_publickey_auto(session, NULL, NULL);
Packit Service 31306d
            if (rc == SSH_AUTH_ERROR) {
Packit Service 31306d
                error(session);
Packit Service 31306d
                return rc;
Packit Service 31306d
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
        {
Packit Service 31306d
            char buffer[128] = {0};
Packit Service 31306d
            char *p = NULL;
Packit Service 31306d
Packit Service 31306d
            printf("Automatic pubkey failed. "
Packit Service 31306d
                   "Do you want to try a specific key? (y/n)\n");
Packit Service 31306d
            if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
            if ((buffer[0]=='Y') || (buffer[0]=='y')) {
Packit Service 31306d
                printf("private key filename: ");
Packit Service 31306d
Packit Service 31306d
                if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit Service 31306d
                    return SSH_AUTH_ERROR;
Packit Service 31306d
                }
Packit Service 31306d
Packit Service 31306d
                buffer[sizeof(buffer) - 1] = '\0';
Packit Service 31306d
                if ((p = strchr(buffer, '\n'))) {
Packit Service 31306d
                    *p = '\0';
Packit Service 31306d
                }
Packit Service 31306d
Packit Service 31306d
                rc = auth_keyfile(session, buffer);
Packit Service 31306d
Packit Service 31306d
                if(rc == SSH_AUTH_SUCCESS) {
Packit Service 31306d
                    break;
Packit Service 31306d
                }
Packit Service 31306d
                fprintf(stderr, "failed with key\n");
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        // Try to authenticate with keyboard interactive";
Packit Service 31306d
        if (method & SSH_AUTH_METHOD_INTERACTIVE) {
Packit Service 31306d
            rc = authenticate_kbdint(session, NULL);
Packit Service 31306d
            if (rc == SSH_AUTH_ERROR) {
Packit Service 31306d
                error(session);
Packit Service 31306d
                return rc;
Packit Service 31306d
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
Packit Service 31306d
            return SSH_AUTH_ERROR;
Packit Service 31306d
        }
Packit Service 31306d
Packit Service 31306d
        // Try to authenticate with password
Packit Service 31306d
        if (method & SSH_AUTH_METHOD_PASSWORD) {
Packit Service 31306d
            rc = ssh_userauth_password(session, NULL, password);
Packit Service 31306d
            if (rc == SSH_AUTH_ERROR) {
Packit Service 31306d
                error(session);
Packit Service 31306d
                return rc;
Packit Service 31306d
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit Service 31306d
                break;
Packit Service 31306d
            }
Packit Service 31306d
        }
Packit Service 31306d
        memset(password, 0, sizeof(password));
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    banner = ssh_get_issue_banner(session);
Packit Service 31306d
    if (banner) {
Packit Service 31306d
        printf("%s\n",banner);
Packit Service 31306d
        SSH_STRING_FREE_CHAR(banner);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return rc;
Packit Service 31306d
}