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