Home | History | Annotate | Download | only in dropbear
      1 /*
      2  * Dropbear - a SSH2 server
      3  *
      4  * Copyright (c) 2002,2003 Matt Johnston
      5  * All rights reserved.
      6  *
      7  * Permission is hereby granted, free of charge, to any person obtaining a copy
      8  * of this software and associated documentation files (the "Software"), to deal
      9  * in the Software without restriction, including without limitation the rights
     10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     11  * copies of the Software, and to permit persons to whom the Software is
     12  * furnished to do so, subject to the following conditions:
     13  *
     14  * The above copyright notice and this permission notice shall be included in
     15  * all copies or substantial portions of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     23  * SOFTWARE. */
     24 
     25 /* Validates a user password */
     26 
     27 #include "includes.h"
     28 #include "session.h"
     29 #include "buffer.h"
     30 #include "dbutil.h"
     31 #include "auth.h"
     32 
     33 #ifdef ENABLE_SVR_PASSWORD_AUTH
     34 
     35 /* Process a password auth request, sending success or failure messages as
     36  * appropriate */
     37 void svr_auth_password() {
     38 
     39 #ifdef HAVE_SHADOW_H
     40 	struct spwd *spasswd = NULL;
     41 #endif
     42 	char * passwdcrypt = NULL; /* the crypt from /etc/passwd or /etc/shadow */
     43 	char * testcrypt = NULL; /* crypt generated from the user's password sent */
     44 	unsigned char * password;
     45 	unsigned int passwordlen;
     46 
     47 	unsigned int changepw;
     48 
     49 	passwdcrypt = ses.authstate.pw->pw_passwd;
     50 #ifdef HAVE_SHADOW_H
     51 	/* get the shadow password if possible */
     52 	spasswd = getspnam(ses.authstate.printableuser);
     53 	if (spasswd != NULL && spasswd->sp_pwdp != NULL) {
     54 		passwdcrypt = spasswd->sp_pwdp;
     55 	}
     56 #endif
     57 
     58 #ifdef DEBUG_HACKCRYPT
     59 	/* debugging crypt for non-root testing with shadows */
     60 	passwdcrypt = DEBUG_HACKCRYPT;
     61 #endif
     62 
     63 	/* check for empty password - need to do this again here
     64 	 * since the shadow password may differ to that tested
     65 	 * in auth.c */
     66 	if (passwdcrypt[0] == '\0') {
     67 		dropbear_log(LOG_WARNING, "user '%s' has blank password, rejected",
     68 				ses.authstate.printableuser);
     69 		send_msg_userauth_failure(0, 1);
     70 		return;
     71 	}
     72 
     73 	/* check if client wants to change password */
     74 	changepw = buf_getbool(ses.payload);
     75 	if (changepw) {
     76 		/* not implemented by this server */
     77 		send_msg_userauth_failure(0, 1);
     78 		return;
     79 	}
     80 
     81 	password = buf_getstring(ses.payload, &passwordlen);
     82 
     83 	/* the first bytes of passwdcrypt are the salt */
     84 	testcrypt = crypt((char*)password, passwdcrypt);
     85 	m_burn(password, passwordlen);
     86 	m_free(password);
     87 
     88 	if (strcmp(testcrypt, passwdcrypt) == 0) {
     89 		/* successful authentication */
     90 		dropbear_log(LOG_NOTICE,
     91 				"password auth succeeded for '%s' from %s",
     92 				ses.authstate.printableuser,
     93 				svr_ses.addrstring);
     94 		send_msg_userauth_success();
     95 	} else {
     96 		dropbear_log(LOG_WARNING,
     97 				"bad password attempt for '%s' from %s",
     98 				ses.authstate.printableuser,
     99 				svr_ses.addrstring);
    100 		send_msg_userauth_failure(0, 1);
    101 	}
    102 
    103 }
    104 
    105 #endif
    106