123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /*
- * Dropbear - a SSH2 server
- *
- * Copyright (c) 2002,2003 Matt Johnston
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE. */
- /* Validates a user password */
- #include "includes.h"
- #include "session.h"
- #include "buffer.h"
- #include "dbutil.h"
- #include "auth.h"
- #include "runopts.h"
- #ifdef ENABLE_SVR_PASSWORD_AUTH
- /* not constant time when strings are differing lengths.
- string content isn't leaked, and crypt hashes are predictable length. */
- static int constant_time_strcmp(const char* a, const char* b) {
- size_t la = strlen(a);
- size_t lb = strlen(b);
- if (la != lb) {
- return 1;
- }
- return constant_time_memcmp(a, b, la);
- }
- /* Process a password auth request, sending success or failure messages as
- * appropriate */
- void svr_auth_password() {
-
- char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */
- char * testcrypt = NULL; /* crypt generated from the user's password sent */
- char * password;
- unsigned int passwordlen;
- unsigned int changepw;
- passwdcrypt = ses.authstate.pw_passwd;
- #ifdef DEBUG_HACKCRYPT
- /* debugging crypt for non-root testing with shadows */
- passwdcrypt = DEBUG_HACKCRYPT;
- #endif
- /* check if client wants to change password */
- changepw = buf_getbool(ses.payload);
- if (changepw) {
- /* not implemented by this server */
- send_msg_userauth_failure(0, 1);
- return;
- }
- password = buf_getstring(ses.payload, &passwordlen);
- /* the first bytes of passwdcrypt are the salt */
- testcrypt = crypt(password, passwdcrypt);
- m_burn(password, passwordlen);
- m_free(password);
- if (testcrypt == NULL) {
- /* crypt() with an invalid salt like "!!" */
- dropbear_log(LOG_WARNING, "User account '%s' is locked",
- ses.authstate.pw_name);
- send_msg_userauth_failure(0, 1);
- return;
- }
- /* check for empty password */
- if (passwdcrypt[0] == '\0') {
- dropbear_log(LOG_WARNING, "User '%s' has blank password, rejected",
- ses.authstate.pw_name);
- send_msg_userauth_failure(0, 1);
- return;
- }
- 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();
- } else {
- dropbear_log(LOG_WARNING,
- "Bad password attempt for '%s' from %s",
- ses.authstate.pw_name,
- svr_ses.addrstring);
- send_msg_userauth_failure(0, 1);
- }
- }
- #endif
|