Blame examples/authentication.c

Packit 6c0a39
/*
Packit 6c0a39
 * authentication.c
Packit 6c0a39
 * This file contains an example of how to do an authentication to a
Packit 6c0a39
 * SSH server using libssh
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
/*
Packit 6c0a39
Copyright 2003-2009 Aris Adamantiadis
Packit 6c0a39
Packit 6c0a39
This file is part of the SSH Library
Packit 6c0a39
Packit 6c0a39
You are free to copy this file, modify it in any way, consider it being public
Packit 6c0a39
domain. This does not apply to the rest of the library though, but it is
Packit 6c0a39
allowed to cut-and-paste working code from this file to any license of
Packit 6c0a39
program.
Packit 6c0a39
The goal is to show the API in action. It's not a reference on how terminal
Packit 6c0a39
clients must be made or how a client should react.
Packit 6c0a39
 */
Packit 6c0a39
Packit 6c0a39
#include <stdio.h>
Packit 6c0a39
#include <stdlib.h>
Packit 6c0a39
#include <string.h>
Packit 6c0a39
Packit 6c0a39
#include <libssh/libssh.h>
Packit 6c0a39
#include "examples_common.h"
Packit 6c0a39
Packit 6c0a39
int authenticate_kbdint(ssh_session session, const char *password)
Packit 6c0a39
{
Packit 6c0a39
    int err;
Packit 6c0a39
Packit 6c0a39
    err = ssh_userauth_kbdint(session, NULL, NULL);
Packit 6c0a39
    while (err == SSH_AUTH_INFO) {
Packit 6c0a39
        const char *instruction;
Packit 6c0a39
        const char *name;
Packit 6c0a39
        char buffer[128];
Packit 6c0a39
        int i, n;
Packit 6c0a39
Packit 6c0a39
        name = ssh_userauth_kbdint_getname(session);
Packit 6c0a39
        instruction = ssh_userauth_kbdint_getinstruction(session);
Packit 6c0a39
        n = ssh_userauth_kbdint_getnprompts(session);
Packit 6c0a39
Packit 6c0a39
        if (name && strlen(name) > 0) {
Packit 6c0a39
            printf("%s\n", name);
Packit 6c0a39
        }
Packit 6c0a39
Packit 6c0a39
        if (instruction && strlen(instruction) > 0) {
Packit 6c0a39
            printf("%s\n", instruction);
Packit 6c0a39
        }
Packit 6c0a39
Packit 6c0a39
        for (i = 0; i < n; i++) {
Packit 6c0a39
            const char *answer;
Packit 6c0a39
            const char *prompt;
Packit 6c0a39
            char echo;
Packit 6c0a39
Packit 6c0a39
            prompt = ssh_userauth_kbdint_getprompt(session, i, &echo);
Packit 6c0a39
            if (prompt == NULL) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
Packit 6c0a39
            if (echo) {
Packit 6c0a39
                char *p;
Packit 6c0a39
Packit 6c0a39
                printf("%s", prompt);
Packit 6c0a39
Packit 6c0a39
                if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit 6c0a39
                    return SSH_AUTH_ERROR;
Packit 6c0a39
                }
Packit 6c0a39
Packit 6c0a39
                buffer[sizeof(buffer) - 1] = '\0';
Packit 6c0a39
                if ((p = strchr(buffer, '\n'))) {
Packit 6c0a39
                    *p = '\0';
Packit 6c0a39
                }
Packit 6c0a39
Packit 6c0a39
                if (ssh_userauth_kbdint_setanswer(session, i, buffer) < 0) {
Packit 6c0a39
                    return SSH_AUTH_ERROR;
Packit 6c0a39
                }
Packit 6c0a39
Packit 6c0a39
                memset(buffer, 0, strlen(buffer));
Packit 6c0a39
            } else {
Packit 6c0a39
                if (password && strstr(prompt, "Password:")) {
Packit 6c0a39
                    answer = password;
Packit 6c0a39
                } else {
Packit 6c0a39
                    buffer[0] = '\0';
Packit 6c0a39
Packit 6c0a39
                    if (ssh_getpass(prompt, buffer, sizeof(buffer), 0, 0) < 0) {
Packit 6c0a39
                        return SSH_AUTH_ERROR;
Packit 6c0a39
                    }
Packit 6c0a39
                    answer = buffer;
Packit 6c0a39
                }
Packit 6c0a39
                err = ssh_userauth_kbdint_setanswer(session, i, answer);
Packit 6c0a39
                memset(buffer, 0, sizeof(buffer));
Packit 6c0a39
                if (err < 0) {
Packit 6c0a39
                    return SSH_AUTH_ERROR;
Packit 6c0a39
                }
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
        err=ssh_userauth_kbdint(session,NULL,NULL);
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return err;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
static int auth_keyfile(ssh_session session, char* keyfile)
Packit 6c0a39
{
Packit 6c0a39
    ssh_key key = NULL;
Packit 6c0a39
    char pubkey[132] = {0}; // +".pub"
Packit 6c0a39
    int rc;
Packit 6c0a39
Packit 6c0a39
    snprintf(pubkey, sizeof(pubkey), "%s.pub", keyfile);
Packit 6c0a39
Packit 6c0a39
    rc = ssh_pki_import_pubkey_file( pubkey, &key);
Packit 6c0a39
Packit 6c0a39
    if (rc != SSH_OK)
Packit 6c0a39
        return SSH_AUTH_DENIED;
Packit 6c0a39
Packit 6c0a39
    rc = ssh_userauth_try_publickey(session, NULL, key);
Packit 6c0a39
Packit 6c0a39
    ssh_key_free(key);
Packit 6c0a39
Packit 6c0a39
    if (rc!=SSH_AUTH_SUCCESS)
Packit 6c0a39
        return SSH_AUTH_DENIED;
Packit 6c0a39
Packit 6c0a39
    rc = ssh_pki_import_privkey_file(keyfile, NULL, NULL, NULL, &key);
Packit 6c0a39
Packit 6c0a39
    if (rc != SSH_OK)
Packit 6c0a39
        return SSH_AUTH_DENIED;
Packit 6c0a39
Packit 6c0a39
    rc = ssh_userauth_publickey(session, NULL, key);
Packit 6c0a39
Packit 6c0a39
    ssh_key_free(key);
Packit 6c0a39
Packit 6c0a39
    return rc;
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
Packit 6c0a39
static void error(ssh_session session)
Packit 6c0a39
{
Packit 6c0a39
    fprintf(stderr,"Authentication failed: %s\n",ssh_get_error(session));
Packit 6c0a39
}
Packit 6c0a39
Packit 6c0a39
int authenticate_console(ssh_session session)
Packit 6c0a39
{
Packit 6c0a39
    int rc;
Packit 6c0a39
    int method;
Packit 6c0a39
    char password[128] = {0};
Packit 6c0a39
    char *banner;
Packit 6c0a39
Packit 6c0a39
    // Try to authenticate
Packit 6c0a39
    rc = ssh_userauth_none(session, NULL);
Packit 6c0a39
    if (rc == SSH_AUTH_ERROR) {
Packit 6c0a39
        error(session);
Packit 6c0a39
        return rc;
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    method = ssh_userauth_list(session, NULL);
Packit 6c0a39
    while (rc != SSH_AUTH_SUCCESS) {
Packit 6c0a39
        if (method & SSH_AUTH_METHOD_GSSAPI_MIC){
Packit 6c0a39
            rc = ssh_userauth_gssapi(session);
Packit 6c0a39
            if(rc == SSH_AUTH_ERROR) {
Packit 6c0a39
                error(session);
Packit 6c0a39
                return rc;
Packit 6c0a39
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
        // Try to authenticate with public key first
Packit 6c0a39
        if (method & SSH_AUTH_METHOD_PUBLICKEY) {
Packit 6c0a39
            rc = ssh_userauth_publickey_auto(session, NULL, NULL);
Packit 6c0a39
            if (rc == SSH_AUTH_ERROR) {
Packit 6c0a39
                error(session);
Packit 6c0a39
                return rc;
Packit 6c0a39
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
        {
Packit 6c0a39
            char buffer[128] = {0};
Packit 6c0a39
            char *p = NULL;
Packit 6c0a39
Packit 6c0a39
            printf("Automatic pubkey failed. "
Packit 6c0a39
                   "Do you want to try a specific key? (y/n)\n");
Packit 6c0a39
            if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
            if ((buffer[0]=='Y') || (buffer[0]=='y')) {
Packit 6c0a39
                printf("private key filename: ");
Packit 6c0a39
Packit 6c0a39
                if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
Packit 6c0a39
                    return SSH_AUTH_ERROR;
Packit 6c0a39
                }
Packit 6c0a39
Packit 6c0a39
                buffer[sizeof(buffer) - 1] = '\0';
Packit 6c0a39
                if ((p = strchr(buffer, '\n'))) {
Packit 6c0a39
                    *p = '\0';
Packit 6c0a39
                }
Packit 6c0a39
Packit 6c0a39
                rc = auth_keyfile(session, buffer);
Packit 6c0a39
Packit 6c0a39
                if(rc == SSH_AUTH_SUCCESS) {
Packit 6c0a39
                    break;
Packit 6c0a39
                }
Packit 6c0a39
                fprintf(stderr, "failed with key\n");
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
Packit 6c0a39
        // Try to authenticate with keyboard interactive";
Packit 6c0a39
        if (method & SSH_AUTH_METHOD_INTERACTIVE) {
Packit 6c0a39
            rc = authenticate_kbdint(session, NULL);
Packit 6c0a39
            if (rc == SSH_AUTH_ERROR) {
Packit 6c0a39
                error(session);
Packit 6c0a39
                return rc;
Packit 6c0a39
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
Packit 6c0a39
        if (ssh_getpass("Password: ", password, sizeof(password), 0, 0) < 0) {
Packit 6c0a39
            return SSH_AUTH_ERROR;
Packit 6c0a39
        }
Packit 6c0a39
Packit 6c0a39
        // Try to authenticate with password
Packit 6c0a39
        if (method & SSH_AUTH_METHOD_PASSWORD) {
Packit 6c0a39
            rc = ssh_userauth_password(session, NULL, password);
Packit 6c0a39
            if (rc == SSH_AUTH_ERROR) {
Packit 6c0a39
                error(session);
Packit 6c0a39
                return rc;
Packit 6c0a39
            } else if (rc == SSH_AUTH_SUCCESS) {
Packit 6c0a39
                break;
Packit 6c0a39
            }
Packit 6c0a39
        }
Packit 6c0a39
        memset(password, 0, sizeof(password));
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    banner = ssh_get_issue_banner(session);
Packit 6c0a39
    if (banner) {
Packit 6c0a39
        printf("%s\n",banner);
Packit Service fcc0d2
        SSH_STRING_FREE_CHAR(banner);
Packit 6c0a39
    }
Packit 6c0a39
Packit 6c0a39
    return rc;
Packit 6c0a39
}