summaryrefslogtreecommitdiff
path: root/auth-passwd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /auth-passwd.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'auth-passwd.c')
-rw-r--r--auth-passwd.c344
1 files changed, 170 insertions, 174 deletions
diff --git a/auth-passwd.c b/auth-passwd.c
index a08bab3af..d3914fca3 100644
--- a/auth-passwd.c
+++ b/auth-passwd.c
@@ -1,30 +1,22 @@
1/* 1/*
2 2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3auth-passwd.c 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 4 * All rights reserved
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Created: Sat Mar 18 05:11:38 1995 ylo
6 6 * Password authentication. This file contains the functions to check whether
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * the password is valid for the user.
8 All rights reserved 8 */
9
10Created: Sat Mar 18 05:11:38 1995 ylo
11
12Password authentication. This file contains the functions to check whether
13the password is valid for the user.
14
15*/
16 9
17#include "includes.h" 10#include "includes.h"
18 11
19#ifndef HAVE_PAM 12#ifndef HAVE_PAM
20 13
21RCSID("$Id: auth-passwd.c,v 1.5 1999/11/19 04:53:20 damien Exp $"); 14RCSID("$Id: auth-passwd.c,v 1.6 1999/11/24 13:26:21 damien Exp $");
22 15
23#include "packet.h" 16#include "packet.h"
24#include "ssh.h" 17#include "ssh.h"
25#include "servconf.h" 18#include "servconf.h"
26#include "xmalloc.h" 19#include "xmalloc.h"
27#include "config.h"
28 20
29#ifdef HAVE_SHADOW_H 21#ifdef HAVE_SHADOW_H
30#include <shadow.h> 22#include <shadow.h>
@@ -34,185 +26,189 @@ RCSID("$Id: auth-passwd.c,v 1.5 1999/11/19 04:53:20 damien Exp $");
34#include "md5crypt.h" 26#include "md5crypt.h"
35#endif 27#endif
36 28
37/* Don't need anything from here if we are using PAM */ 29/*
38 30 * Tries to authenticate the user using password. Returns true if
39/* Tries to authenticate the user using password. Returns true if 31 * authentication succeeds.
40 authentication succeeds. */ 32 */
41 33int
42int auth_password(struct passwd *pw, const char *password) 34auth_password(struct passwd * pw, const char *password)
43{ 35{
44 extern ServerOptions options; 36 extern ServerOptions options;
45 char *encrypted_password; 37 char *encrypted_password;
46#ifdef HAVE_SHADOW_H 38#ifdef HAVE_SHADOW_H
47 struct spwd *spw; 39 struct spwd *spw;
48#endif 40#endif
49 41
50 if (pw->pw_uid == 0 && options.permit_root_login == 2) 42 if (pw->pw_uid == 0 && options.permit_root_login == 2) {
51 { 43 /* Server does not permit root login with password */
52 /*packet_send_debug("Server does not permit root login with password.");*/ 44 return 0;
53 return 0; 45 }
54 } 46 if (*password == '\0' && options.permit_empty_passwd == 0) {
55 47 /* Server does not permit empty password login */
56 if (*password == '\0' && options.permit_empty_passwd == 0) 48 return 0;
57 { 49 }
58 /*packet_send_debug("Server does not permit empty password login.");*/ 50 /* deny if no user. */
59 return 0; 51 if (pw == NULL)
60 } 52 return 0;
61
62 /* deny if no user. */
63 if (pw == NULL)
64 return 0;
65 53
66#ifdef SKEY 54#ifdef SKEY
67 if (options.skey_authentication == 1) { 55 if (options.skey_authentication == 1) {
68 if (strncasecmp(password, "s/key", 5) == 0) { 56 if (strncasecmp(password, "s/key", 5) == 0) {
69 char *skeyinfo = skey_keyinfo(pw->pw_name); 57 char *skeyinfo = skey_keyinfo(pw->pw_name);
70 if(skeyinfo == NULL){ 58 if (skeyinfo == NULL) {
71 debug("generating fake skeyinfo for %.100s.", pw->pw_name); 59 debug("generating fake skeyinfo for %.100s.",
72 skeyinfo = skey_fake_keyinfo(pw->pw_name); 60 pw->pw_name);
73 } 61 skeyinfo = skey_fake_keyinfo(pw->pw_name);
74 if(skeyinfo != NULL) 62 }
75 packet_send_debug(skeyinfo); 63 if (skeyinfo != NULL)
76 /* Try again. */ 64 packet_send_debug(skeyinfo);
77 return 0; 65 /* Try again. */
78 } 66 return 0;
79 else if (skey_haskey(pw->pw_name) == 0 && 67 } else if (skey_haskey(pw->pw_name) == 0 &&
80 skey_passcheck(pw->pw_name, (char *)password) != -1) { 68 skey_passcheck(pw->pw_name, (char *) password) != -1) {
81 /* Authentication succeeded. */ 69 /* Authentication succeeded. */
82 return 1; 70 return 1;
83 } 71 }
84 /* Fall back to ordinary passwd authentication. */ 72 /* Fall back to ordinary passwd authentication. */
85 } 73 }
86#endif 74#endif
87 75
88#if defined(KRB4) 76#if defined(KRB4)
89 /* Support for Kerberos v4 authentication - Dug Song <dugsong@UMICH.EDU> */ 77 /* Support for Kerberos v4 authentication - Dug Song
90 if (options.kerberos_authentication) 78 <dugsong@UMICH.EDU> */
91 { 79 if (options.kerberos_authentication) {
92 AUTH_DAT adata; 80 AUTH_DAT adata;
93 KTEXT_ST tkt; 81 KTEXT_ST tkt;
94 struct hostent *hp; 82 struct hostent *hp;
95 unsigned long faddr; 83 unsigned long faddr;
96 char localhost[MAXHOSTNAMELEN]; 84 char localhost[MAXHOSTNAMELEN];
97 char phost[INST_SZ]; 85 char phost[INST_SZ];
98 char realm[REALM_SZ]; 86 char realm[REALM_SZ];
99 int r; 87 int r;
100 88
101 /* Try Kerberos password authentication only for non-root 89 /* Try Kerberos password authentication only for non-root
102 users and only if Kerberos is installed. */ 90 users and only if Kerberos is installed. */
103 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) { 91 if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
104 92
105 /* Set up our ticket file. */ 93 /* Set up our ticket file. */
106 if (!krb4_init(pw->pw_uid)) { 94 if (!krb4_init(pw->pw_uid)) {
107 log("Couldn't initialize Kerberos ticket file for %s!", pw->pw_name); 95 log("Couldn't initialize Kerberos ticket file for %s!",
108 goto kerberos_auth_failure; 96 pw->pw_name);
109 } 97 goto kerberos_auth_failure;
110 /* Try to get TGT using our password. */ 98 }
111 r = krb_get_pw_in_tkt((char *)pw->pw_name, "", realm, "krbtgt", realm, 99 /* Try to get TGT using our password. */
112 DEFAULT_TKT_LIFE, (char *)password); 100 r = krb_get_pw_in_tkt((char *) pw->pw_name, "",
113 if (r != INTK_OK) { 101 realm, "krbtgt", realm,
114 packet_send_debug("Kerberos V4 password authentication for %s " 102 DEFAULT_TKT_LIFE, (char *) password);
115 "failed: %s", pw->pw_name, krb_err_txt[r]); 103 if (r != INTK_OK) {
116 goto kerberos_auth_failure; 104 packet_send_debug("Kerberos V4 password "
105 "authentication for %s failed: %s",
106 pw->pw_name, krb_err_txt[r]);
107 goto kerberos_auth_failure;
108 }
109 /* Successful authentication. */
110 chown(tkt_string(), pw->pw_uid, pw->pw_gid);
111
112 /*
113 * Now that we have a TGT, try to get a local
114 * "rcmd" ticket to ensure that we are not talking
115 * to a bogus Kerberos server.
116 */
117 (void) gethostname(localhost, sizeof(localhost));
118 (void) strlcpy(phost, (char *) krb_get_phost(localhost),
119 INST_SZ);
120 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
121
122 if (r == KSUCCESS) {
123 if (!(hp = gethostbyname(localhost))) {
124 log("Couldn't get local host address!");
125 goto kerberos_auth_failure;
126 }
127 memmove((void *) &faddr, (void *) hp->h_addr,
128 sizeof(faddr));
129
130 /* Verify our "rcmd" ticket. */
131 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
132 faddr, &adata, "");
133 if (r == RD_AP_UNDEC) {
134 /*
135 * Probably didn't have a srvtab on
136 * localhost. Allow login.
137 */
138 log("Kerberos V4 TGT for %s unverifiable, "
139 "no srvtab installed? krb_rd_req: %s",
140 pw->pw_name, krb_err_txt[r]);
141 } else if (r != KSUCCESS) {
142 log("Kerberos V4 %s ticket unverifiable: %s",
143 KRB4_SERVICE_NAME, krb_err_txt[r]);
144 goto kerberos_auth_failure;
145 }
146 } else if (r == KDC_PR_UNKNOWN) {
147 /* Allow login if no rcmd service exists,
148 but log the error. */
149 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
150 "not registered, or srvtab is wrong?", pw->pw_name,
151 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
152 } else {
153 /* TGT is bad, forget it. Possibly
154 spoofed! */
155 packet_send_debug("WARNING: Kerberos V4 TGT "
156 "possibly spoofed for %s: %s",
157 pw->pw_name, krb_err_txt[r]);
158 goto kerberos_auth_failure;
159 }
160
161 /* Authentication succeeded. */
162 return 1;
163
164 kerberos_auth_failure:
165 krb4_cleanup_proc(NULL);
166
167 if (!options.kerberos_or_local_passwd)
168 return 0;
169 } else {
170 /* Logging in as root or no local Kerberos realm. */
171 packet_send_debug("Unable to authenticate to Kerberos.");
172 }
173 /* Fall back to ordinary passwd authentication. */
117 } 174 }
118 /* Successful authentication. */ 175#endif /* KRB4 */
119 chown(tkt_string(), pw->pw_uid, pw->pw_gid); 176
120 177 /* Check for users with no password. */
121 /* Now that we have a TGT, try to get a local "rcmd" ticket to 178 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) {
122 ensure that we are not talking to a bogus Kerberos server. */ 179 packet_send_debug("Login permitted without a password "
123 (void) gethostname(localhost, sizeof(localhost)); 180 "because the account has no password.");
124 (void) strlcpy(phost, (char *)krb_get_phost(localhost), INST_SZ); 181 return 1;
125 r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
126
127 if (r == KSUCCESS) {
128 if (!(hp = gethostbyname(localhost))) {
129 log("Couldn't get local host address!");
130 goto kerberos_auth_failure;
131 }
132 memmove((void *)&faddr, (void *)hp->h_addr, sizeof(faddr));
133
134 /* Verify our "rcmd" ticket. */
135 r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost, faddr, &adata, "");
136 if (r == RD_AP_UNDEC) {
137 /* Probably didn't have a srvtab on localhost. Allow login. */
138 log("Kerberos V4 TGT for %s unverifiable, no srvtab installed? "
139 "krb_rd_req: %s", pw->pw_name, krb_err_txt[r]);
140 }
141 else if (r != KSUCCESS) {
142 log("Kerberos V4 %s ticket unverifiable: %s",
143 KRB4_SERVICE_NAME, krb_err_txt[r]);
144 goto kerberos_auth_failure;
145 }
146 }
147 else if (r == KDC_PR_UNKNOWN) {
148 /* Allow login if no rcmd service exists, but log the error. */
149 log("Kerberos V4 TGT for %s unverifiable: %s; %s.%s "
150 "not registered, or srvtab is wrong?", pw->pw_name,
151 krb_err_txt[r], KRB4_SERVICE_NAME, phost);
152 }
153 else {
154 /* TGT is bad, forget it. Possibly spoofed! */
155 packet_send_debug("WARNING: Kerberos V4 TGT possibly spoofed for"
156 "%s: %s", pw->pw_name, krb_err_txt[r]);
157 goto kerberos_auth_failure;
158 } 182 }
159
160 /* Authentication succeeded. */
161 return 1;
162
163 kerberos_auth_failure:
164 krb4_cleanup_proc(NULL);
165
166 if (!options.kerberos_or_local_passwd)
167 return 0;
168 }
169 else {
170 /* Logging in as root or no local Kerberos realm. */
171 packet_send_debug("Unable to authenticate to Kerberos.");
172 }
173 /* Fall back to ordinary passwd authentication. */
174 }
175#endif /* KRB4 */
176
177 /* Check for users with no password. */
178 if (strcmp(password, "") == 0 && strcmp(pw->pw_passwd, "") == 0)
179 {
180 packet_send_debug("Login permitted without a password because the account has no password.");
181 return 1; /* The user has no password and an empty password was tried. */
182 }
183 183
184#ifdef HAVE_SHADOW_H 184#ifdef HAVE_SHADOW_H
185 spw = getspnam(pw->pw_name); 185 spw = getspnam(pw->pw_name);
186 if (spw == NULL) 186 if (spw == NULL)
187 return(0); 187 return(0);
188 188
189 if ((spw->sp_namp == NULL) || (strcmp(pw->pw_name, spw->sp_namp) != 0)) 189 if ((spw->sp_namp == NULL) || (strcmp(pw->pw_name, spw->sp_namp) != 0))
190 fatal("Shadow lookup returned garbage."); 190 fatal("Shadow lookup returned garbage.");
191 191
192 if (strlen(spw->sp_pwdp) < 3) 192 if (strlen(spw->sp_pwdp) < 3)
193 return(0); 193 return(0);
194 194
195 /* Encrypt the candidate password using the proper salt. */ 195 /* Encrypt the candidate password using the proper salt. */
196#ifdef HAVE_MD5_PASSWORDS 196#ifdef HAVE_MD5_PASSWORDS
197 if (is_md5_salt(spw->sp_pwdp)) 197 if (is_md5_salt(spw->sp_pwdp))
198 encrypted_password = md5_crypt(password, spw->sp_pwdp); 198 encrypted_password = md5_crypt(password, spw->sp_pwdp);
199 else 199 else
200 encrypted_password = crypt(password, spw->sp_pwdp); 200 encrypted_password = crypt(password, spw->sp_pwdp);
201#else /* HAVE_MD5_PASSWORDS */ 201#else /* HAVE_MD5_PASSWORDS */
202 encrypted_password = crypt(password, spw->sp_pwdp); 202 encrypted_password = crypt(password, spw->sp_pwdp);
203#endif /* HAVE_MD5_PASSWORDS */ 203#endif /* HAVE_MD5_PASSWORDS */
204 204 /* Authentication is accepted if the encrypted passwords are identical. */
205 /* Authentication is accepted if the encrypted passwords are identical. */ 205 return (strcmp(encrypted_password, spw->sp_pwdp) == 0);
206 return (strcmp(encrypted_password, spw->sp_pwdp) == 0);
207#else /* !HAVE_SHADOW_H */ 206#else /* !HAVE_SHADOW_H */
207 encrypted_password = crypt(password,
208 (pw->pw_passwd[0] && pw->pw_passwd[1]) ? pw->pw_passwd : "xx");
208 209
209 /* Encrypt the candidate password using the proper salt. */ 210 /* Authentication is accepted if the encrypted passwords are identical. */
210 encrypted_password = crypt(password, 211 return (strcmp(encrypted_password, pw->pw_passwd) == 0);
211 (pw->pw_passwd[0] && pw->pw_passwd[1]) ?
212 pw->pw_passwd : "xx");
213 /* Authentication is accepted if the encrypted passwords are identical. */
214 return (strcmp(encrypted_password, pw->pw_passwd) == 0);
215#endif /* !HAVE_SHADOW_H */ 212#endif /* !HAVE_SHADOW_H */
216} 213}
217
218#endif /* !HAVE_PAM */ 214#endif /* !HAVE_PAM */