mirror of
https://github.com/tmate-io/tmate.git
synced 2024-12-12 01:40:54 +01:00
168 lines
4.4 KiB
C
168 lines
4.4 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 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_auth_list(session);
|
|
while (rc != SSH_AUTH_SUCCESS) {
|
|
// Try to authenticate with public key first
|
|
if (method & SSH_AUTH_METHOD_PUBLICKEY) {
|
|
rc = ssh_userauth_autopubkey(session, NULL);
|
|
if (rc == SSH_AUTH_ERROR) {
|
|
error(session);
|
|
return rc;
|
|
} else if (rc == SSH_AUTH_SUCCESS) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 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;
|
|
}
|