Two-factor authentication support (pubkey and password)

This commit is contained in:
Jackkal 2022-04-29 15:43:15 +02:00
parent 46654cda85
commit 0c9318a0b2
6 changed files with 59 additions and 18 deletions

View File

@ -53,6 +53,10 @@ Disable password logins.
.B \-g
Disable password logins for root.
.TP
.B \-t
Enable two-factor authentication. Both password login and public key authentication are
required. Should not be used with the '-s' option.
.TP
.B \-j
Disable local port forwarding.
.TP

View File

@ -105,6 +105,7 @@ typedef struct svr_runopts {
int noauthpass;
int norootpass;
int allowblankpass;
int multiauthmethod;
unsigned int maxauthtries;
#if DROPBEAR_SVR_REMOTETCPFWD

View File

@ -278,12 +278,22 @@ void svr_auth_pam(int valid_user) {
goto cleanup;
}
/* successful authentication */
dropbear_log(LOG_NOTICE, "PAM password auth succeeded for '%s' from %s",
ses.authstate.pw_name,
svr_ses.addrstring);
send_msg_userauth_success();
if (svr_opts.multiauthmethod && (ses.authstate.authtypes & ~AUTH_TYPE_PASSWORD)) {
/* successful PAM password authentication, but extra auth required */
dropbear_log(LOG_NOTICE,
"PAM password auth auth succeeded for '%s' from %s, extra auth required",
ses.authstate.pw_name,
svr_ses.addrstring);
ses.authstate.authtypes &= ~AUTH_TYPE_PASSWORD;
send_msg_userauth_failure(1, 0); /* Send partial success */
} else {
/* successful authentication */
dropbear_log(LOG_NOTICE, "PAM password auth succeeded for '%s' from %s",
ses.authstate.pw_name,
svr_ses.addrstring);
send_msg_userauth_success();
}
cleanup:
if (password != NULL) {
m_burn(password, passwordlen);

View File

@ -106,12 +106,22 @@ void svr_auth_password(int valid_user) {
}
if (constant_time_strcmp(testcrypt, passwdcrypt) == 0) {
/* successful authentication */
dropbear_log(LOG_NOTICE,
"Password auth succeeded for '%s' from %s",
ses.authstate.pw_name,
svr_ses.addrstring);
send_msg_userauth_success();
if (svr_opts.multiauthmethod && (ses.authstate.authtypes & ~AUTH_TYPE_PASSWORD)) {
/* successful password authentication, but extra auth required */
dropbear_log(LOG_NOTICE,
"Password auth succeeded for '%s' from %s, extra auth required",
ses.authstate.pw_name,
svr_ses.addrstring);
ses.authstate.authtypes &= ~AUTH_TYPE_PASSWORD;
send_msg_userauth_failure(1, 0); /* Send partial success */
} else {
/* successful authentication */
dropbear_log(LOG_NOTICE,
"Password auth succeeded for '%s' from %s",
ses.authstate.pw_name,
svr_ses.addrstring);
send_msg_userauth_success();
}
} else {
dropbear_log(LOG_WARNING,
"Bad password attempt for '%s' from %s",

View File

@ -64,6 +64,7 @@
#include "ssh.h"
#include "packet.h"
#include "algo.h"
#include "runopts.h"
#if DROPBEAR_SVR_PUBKEY_AUTH
@ -201,12 +202,22 @@ void svr_auth_pubkey(int valid_user) {
/* ... and finally verify the signature */
fp = sign_key_fingerprint(keyblob, keybloblen);
if (buf_verify(ses.payload, key, sigtype, signbuf) == DROPBEAR_SUCCESS) {
dropbear_log(LOG_NOTICE,
"Pubkey auth succeeded for '%s' with %s key %s from %s",
ses.authstate.pw_name,
signkey_name_from_type(keytype, NULL), fp,
svr_ses.addrstring);
send_msg_userauth_success();
if (svr_opts.multiauthmethod && (ses.authstate.authtypes & ~AUTH_TYPE_PUBKEY)) {
dropbear_log(LOG_NOTICE,
"Pubkey auth succeeded for '%s' with %s key %s from %s, extra auth required",
ses.authstate.pw_name,
signkey_name_from_type(keytype, NULL), fp,
svr_ses.addrstring);
ses.authstate.authtypes &= ~AUTH_TYPE_PUBKEY; /* pubkey auth ok, delete the method flag */
send_msg_userauth_failure(1, 0); /* Send partial success */
} else {
dropbear_log(LOG_NOTICE,
"Pubkey auth succeeded for '%s' with %s key %s from %s",
ses.authstate.pw_name,
signkey_name_from_type(keytype, NULL), fp,
svr_ses.addrstring);
send_msg_userauth_success();
}
#if DROPBEAR_PLUGIN
if ((ses.plugin_session != NULL) && (svr_ses.plugin_instance->auth_success != NULL)) {
/* Was authenticated through the external plugin. tell plugin that signature verification was ok */

View File

@ -81,6 +81,7 @@ static void printhelp(const char * progname) {
"-s Disable password logins\n"
"-g Disable password logins for root\n"
"-B Allow blank password logins\n"
"-t Enable two-factor authentication (both password and public key required)\n"
#endif
"-T Maximum authentication tries (default %d)\n"
#if DROPBEAR_SVR_LOCALTCPFWD
@ -158,6 +159,7 @@ void svr_getopts(int argc, char ** argv) {
svr_opts.noauthpass = 0;
svr_opts.norootpass = 0;
svr_opts.allowblankpass = 0;
svr_opts.multiauthmethod = 0;
svr_opts.maxauthtries = MAX_AUTH_TRIES;
svr_opts.inetdmode = 0;
svr_opts.portcount = 0;
@ -295,6 +297,9 @@ void svr_getopts(int argc, char ** argv) {
case 'B':
svr_opts.allowblankpass = 1;
break;
case 't':
svr_opts.multiauthmethod = 1;
break;
#endif
case 'h':
printhelp(argv[0]);