diff --git a/NOTES b/NOTES index 17943b1..2ef6306 100644 --- a/NOTES +++ b/NOTES @@ -393,5 +393,4 @@ Then we might even want a UI way to delete authorized_keys, perhaps even as a replacement for the current awkward UI. -XXX - if authorized_keys doesn't exist, generate a one-off password XXX - make a way to delete authorized_keys diff --git a/dropbear/auth.h b/dropbear/auth.h index 66f5b6a..0847711 100644 --- a/dropbear/auth.h +++ b/dropbear/auth.h @@ -39,6 +39,7 @@ void send_msg_userauth_success(); void send_msg_userauth_banner(buffer *msg); void svr_auth_password(); void svr_auth_pubkey(); +int authkeys_exists(void); void svr_auth_pam(); #ifdef ENABLE_SVR_PUBKEY_OPTIONS diff --git a/dropbear/common-session.c b/dropbear/common-session.c index bafd132..c2582fb 100644 --- a/dropbear/common-session.c +++ b/dropbear/common-session.c @@ -506,10 +506,10 @@ void fill_passwd(const char* username) { m_free(ses.authstate.pw_dir); if (ses.authstate.pw_shell) m_free(ses.authstate.pw_shell); +#if 0 if (ses.authstate.pw_passwd) m_free(ses.authstate.pw_passwd); -#if 0 pw = getpwnam(username); if (!pw) { return; @@ -540,7 +540,9 @@ void fill_passwd(const char* username) { ses.authstate.pw_name = m_strdup("user"); ses.authstate.pw_dir = m_strdup(conf_home); ses.authstate.pw_shell = m_strdup(conf_shell); - ses.authstate.pw_passwd = m_strdup("!!"); + if (!ses.authstate.pw_passwd) { /* password hack */ + ses.authstate.pw_passwd = m_strdup("!!"); + } #endif /* 0 */ } diff --git a/dropbear/svr-auth.c b/dropbear/svr-auth.c index 4fcfea6..023dad9 100644 --- a/dropbear/svr-auth.c +++ b/dropbear/svr-auth.c @@ -56,6 +56,7 @@ void svr_authinitialise() { static void authclear() { memset(&ses.authstate, 0, sizeof(ses.authstate)); +#if 0 #ifdef ENABLE_SVR_PUBKEY_AUTH ses.authstate.authtypes |= AUTH_TYPE_PUBKEY; #endif @@ -76,6 +77,24 @@ static void authclear() { if (ses.authstate.pw_passwd) { m_free(ses.authstate.pw_passwd); } +#else /* 0 - password hack */ + if (authkeys_exists()) { + ses.authstate.authtypes = AUTH_TYPE_PUBKEY; + } else { + static const char tab64[64] = +"abcdefghijk!mnopqrstuvwxyzABCDEFGH@JKLMN#PQRSTUVWXYZ$%23456789^&"; + char pw[9]; + int i; + ses.authstate.authtypes = AUTH_TYPE_PASSWORD; + genrandom(pw, 8); + for (i = 0; i < 8; i++) { + pw[i] = tab64[pw[i] & 63]; + } + pw[8] = 0; + fprintf(stderr, "no authorized keys, temporary password: %s\n", pw); + ses.authstate.pw_passwd = m_strdup(pw); + } +#endif /* 0 */ } @@ -169,6 +188,7 @@ void recv_msg_userauth_request() { } } +#if 0 #ifdef ENABLE_SVR_PASSWORD_AUTH if (!svr_opts.noauthpass && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ) { @@ -183,6 +203,15 @@ void recv_msg_userauth_request() { } } #endif +#else /* 0 - password hack */ + if ((ses.authstate.authtypes & AUTH_TYPE_PASSWORD) && + (methodlen == AUTH_METHOD_PASSWORD_LEN) && + !strncmp(methodname, AUTH_METHOD_PASSWORD, + AUTH_METHOD_PASSWORD_LEN)) { + svr_auth_password(); + goto out; + } +#endif /* 0 */ #ifdef ENABLE_SVR_PAM_AUTH if (!svr_opts.noauthpass && @@ -246,7 +275,9 @@ static int checkusername(unsigned char *username, unsigned int userlen) { svr_ses.addrstring); m_free(ses.authstate.username); } +#if 0 /* password hack - this would unecessarily reset the pw_passwd */ authclear(); +#endif /* 0 */ fill_passwd(username); ses.authstate.username = m_strdup(username); } diff --git a/dropbear/svr-authpasswd.c b/dropbear/svr-authpasswd.c index 7a5a121..3170fef 100644 --- a/dropbear/svr-authpasswd.c +++ b/dropbear/svr-authpasswd.c @@ -31,7 +31,7 @@ #include "auth.h" #include "runopts.h" -#ifdef ENABLE_SVR_PASSWORD_AUTH +#if 1 /* password hack - #ifdef ENABLE_SVR_PASSWORD_AUTH */ static int constant_time_strcmp(const char* a, const char* b) { size_t la = strlen(a); @@ -48,6 +48,7 @@ static int constant_time_strcmp(const char* a, const char* b) { * appropriate */ void svr_auth_password() { + char tmp[10]; char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */ char * testcrypt = NULL; /* crypt generated from the user's password sent */ unsigned char * password; @@ -72,8 +73,17 @@ void svr_auth_password() { password = buf_getstring(ses.payload, &passwordlen); +#if 0 /* the first bytes of passwdcrypt are the salt */ testcrypt = crypt((char*)password, passwdcrypt); +#else /* 0 - password hack */ + if (strlen(password) == 8) { + strcpy(tmp, password); + testcrypt = tmp; + } else { + testcrypt = NULL; + } +#endif /* 0 */ m_burn(password, passwordlen); m_free(password); diff --git a/dropbear/svr-authpubkey.c b/dropbear/svr-authpubkey.c index bbb0a45..b371ac1 100644 --- a/dropbear/svr-authpubkey.c +++ b/dropbear/svr-authpubkey.c @@ -447,3 +447,29 @@ static int checkfileperm(char * filename) { } #endif + +/* returns 1 iff authorized_keys exists and is longer than MIN_AUTHKEYS_LINE + * (10 bytes) - used for password hack */ +int +authkeys_exists(void) +{ + char *fn; + FILE *f; + int len = strlen(conf_path) + 40; + int i; + fn = m_malloc(len); + snprintf(fn, len, "%s/authorized_keys", conf_path); + f = fopen(fn, "r"); + m_free(fn); + if (!f) { + return 0; + } + for (i = 0; i < MIN_AUTHKEYS_LINE; i++) { + if (fgetc(f) == EOF) { + fclose(f); + return 0; + } + } + fclose(f); + return 1; +} diff --git a/jni/Android.mk b/jni/Android.mk index 3d8d35c..6c73c5e 100644 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -453,6 +453,7 @@ DROPBEAR_SRCS := $(DROPBEAR_PATH)/atomicio.c \ $(DROPBEAR_PATH)/sshpty.c \ $(DROPBEAR_PATH)/svr-agentfwd.c \ $(DROPBEAR_PATH)/svr-auth.c \ + $(DROPBEAR_PATH)/svr-authpasswd.c \ $(DROPBEAR_PATH)/svr-authpubkey.c \ $(DROPBEAR_PATH)/svr-authpubkeyoptions.c \ $(DROPBEAR_PATH)/svr-chansession.c \