mirror of
https://github.com/upa/mscp.git
synced 2026-03-06 23:57:33 +08:00
add ssh keyboard interactive authentication
Supporting keyboard-interactive authentication enables login with Cisco DUO MFA (#2).
This commit is contained in:
58
src/ssh.c
58
src/ssh.c
@@ -11,6 +11,7 @@
|
|||||||
#include <strerrno.h>
|
#include <strerrno.h>
|
||||||
|
|
||||||
static int ssh_verify_known_hosts(ssh_session session);
|
static int ssh_verify_known_hosts(ssh_session session);
|
||||||
|
static int ssh_authenticate_kbdint(ssh_session session);
|
||||||
|
|
||||||
static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts)
|
static int ssh_set_opts(ssh_session ssh, struct mscp_ssh_opts *opts)
|
||||||
{
|
{
|
||||||
@@ -100,17 +101,18 @@ static int ssh_authenticate(ssh_session ssh, struct mscp_ssh_opts *opts)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
auth_bit_mask = ssh_userauth_list(ssh, NULL);
|
auth_bit_mask = ssh_userauth_list(ssh, NULL);
|
||||||
|
|
||||||
if (auth_bit_mask & SSH_AUTH_METHOD_NONE &&
|
if (auth_bit_mask & SSH_AUTH_METHOD_NONE &&
|
||||||
ssh_userauth_none(ssh, NULL) == SSH_AUTH_SUCCESS)
|
ssh_userauth_none(ssh, NULL) == SSH_AUTH_SUCCESS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
auth_bit_mask = ssh_userauth_list(ssh, NULL);
|
||||||
if (auth_bit_mask & SSH_AUTH_METHOD_PUBLICKEY) {
|
if (auth_bit_mask & SSH_AUTH_METHOD_PUBLICKEY) {
|
||||||
char *p = opts->passphrase ? opts->passphrase : NULL;
|
char *p = opts->passphrase ? opts->passphrase : NULL;
|
||||||
if (ssh_userauth_publickey_auto(ssh, NULL, p) == SSH_AUTH_SUCCESS)
|
if (ssh_userauth_publickey_auto(ssh, NULL, p) == SSH_AUTH_SUCCESS)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth_bit_mask = ssh_userauth_list(ssh, NULL);
|
||||||
if (auth_bit_mask & SSH_AUTH_METHOD_PASSWORD) {
|
if (auth_bit_mask & SSH_AUTH_METHOD_PASSWORD) {
|
||||||
if (!opts->password) {
|
if (!opts->password) {
|
||||||
char buf[128] = {};
|
char buf[128] = {};
|
||||||
@@ -128,6 +130,12 @@ static int ssh_authenticate(ssh_session ssh, struct mscp_ssh_opts *opts)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auth_bit_mask = ssh_userauth_list(ssh, NULL);
|
||||||
|
if (auth_bit_mask & SSH_AUTH_METHOD_INTERACTIVE) {
|
||||||
|
if (ssh_authenticate_kbdint(ssh) == SSH_AUTH_SUCCESS)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,6 +327,54 @@ static int ssh_verify_known_hosts(ssh_session session)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ssh_authenticate_kbdint(ssh_session ssh)
|
||||||
|
{
|
||||||
|
/* Copied and bit modified from
|
||||||
|
* https://api.libssh.org/stable/libssh_tutor_authentication.html */
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = ssh_userauth_kbdint(ssh, NULL, NULL);
|
||||||
|
while (rc == SSH_AUTH_INFO) {
|
||||||
|
const char *name, *instruction;
|
||||||
|
int nprompts, iprompt;
|
||||||
|
|
||||||
|
name = ssh_userauth_kbdint_getname(ssh);
|
||||||
|
instruction = ssh_userauth_kbdint_getinstruction(ssh);
|
||||||
|
nprompts = ssh_userauth_kbdint_getnprompts(ssh);
|
||||||
|
|
||||||
|
if (strlen(name) > 0)
|
||||||
|
printf("%s\n", name);
|
||||||
|
if (strlen(instruction) > 0)
|
||||||
|
printf("%s\n", instruction);
|
||||||
|
for (iprompt = 0; iprompt < nprompts; iprompt++) {
|
||||||
|
const char *prompt;
|
||||||
|
char echo;
|
||||||
|
|
||||||
|
prompt = ssh_userauth_kbdint_getprompt(ssh, iprompt, &echo);
|
||||||
|
if (echo) {
|
||||||
|
char buf[128], *ptr;
|
||||||
|
|
||||||
|
printf("%s", prompt);
|
||||||
|
if (fgets(buf, sizeof(buf), stdin) == NULL)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
buf[sizeof(buf) - 1] = '\0';
|
||||||
|
if ((ptr = strchr(buf, '\n')) != NULL)
|
||||||
|
*ptr = '\0';
|
||||||
|
if (ssh_userauth_kbdint_setanswer(ssh, iprompt, buf) < 0)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
memset(buf, 0, strlen(buf));
|
||||||
|
} else {
|
||||||
|
char *ptr;
|
||||||
|
ptr = getpass(prompt);
|
||||||
|
if (ssh_userauth_kbdint_setanswer(ssh, iprompt, ptr) < 0)
|
||||||
|
return SSH_AUTH_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rc = ssh_userauth_kbdint(ssh, NULL, NULL);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
void ssh_sftp_close(sftp_session sftp)
|
void ssh_sftp_close(sftp_session sftp)
|
||||||
{
|
{
|
||||||
ssh_session ssh = sftp_ssh(sftp);
|
ssh_session ssh = sftp_ssh(sftp);
|
||||||
|
|||||||
Reference in New Issue
Block a user