|
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 |
}
|