source: trunk/third/openssh/auth-passwd.c @ 18763

Revision 18763, 7.8 KB checked in by zacheiss, 22 years ago (diff)
Merge openssh 3.5p1.
Line 
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * Password authentication.  This file contains the functions to check whether
6 * the password is valid for the user.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose.  Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 *
14 * Copyright (c) 1999 Dug Song.  All rights reserved.
15 * Copyright (c) 2000 Markus Friedl.  All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 *    notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 *    notice, this list of conditions and the following disclaimer in the
24 *    documentation and/or other materials provided with the distribution.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "includes.h"
39RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $");
40
41#include "packet.h"
42#include "log.h"
43#include "servconf.h"
44#include "auth.h"
45
46#ifdef GSSAPI
47#include <gssapi.h>
48extern gss_cred_id_t   gssapi_client_creds;
49#endif
50
51#if !defined(USE_PAM) && !defined(HAVE_OSF_SIA)
52/* Don't need any of these headers for the PAM or SIA cases */
53# ifdef HAVE_CRYPT_H
54#  include <crypt.h>
55# endif
56# ifdef WITH_AIXAUTHENTICATE
57#  include <login.h>
58# endif
59# ifdef __hpux
60#  include <hpsecurity.h>
61#  include <prot.h>
62# endif
63# ifdef HAVE_SECUREWARE
64#  include <sys/security.h>
65#  include <sys/audit.h>
66#  include <prot.h>
67# endif /* HAVE_SECUREWARE */
68# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
69#  include <shadow.h>
70# endif
71# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
72#  include <sys/label.h>
73#  include <sys/audit.h>
74#  include <pwdadj.h>
75# endif
76# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT)
77#  include "md5crypt.h"
78# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */
79
80# ifdef HAVE_CYGWIN
81#  undef ERROR
82#  include <windows.h>
83#  include <sys/cygwin.h>
84#  define is_winnt       (GetVersion() < 0x80000000)
85# endif
86#endif /* !USE_PAM && !HAVE_OSF_SIA */
87
88extern ServerOptions options;
89#ifdef WITH_AIXAUTHENTICATE
90extern char *aixloginmsg;
91#endif
92
93/*
94 * Tries to authenticate the user using password.  Returns true if
95 * authentication succeeds.
96 */
97int
98auth_password(Authctxt *authctxt, const char *password)
99{
100#if defined(USE_PAM)
101        if (*password == '\0' && options.permit_empty_passwd == 0)
102                return 0;
103        return auth_pam_password(authctxt, password);
104#elif defined(HAVE_OSF_SIA)
105        if (*password == '\0' && options.permit_empty_passwd == 0)
106                return 0;
107        return auth_sia_password(authctxt, password);
108#else
109        struct passwd * pw = authctxt->pw;
110        char *encrypted_password;
111        char *pw_password;
112        char *salt;
113#if defined(__hpux) || defined(HAVE_SECUREWARE)
114        struct pr_passwd *spw;
115#endif /* __hpux || HAVE_SECUREWARE */
116#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
117        struct spwd *spw;
118#endif
119#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
120        struct passwd_adjunct *spw;
121#endif
122#ifdef WITH_AIXAUTHENTICATE
123        char *authmsg;
124        int authsuccess;
125        int reenter = 1;
126#endif
127#ifdef GSSAPI
128        OM_uint32 ms;
129#endif
130
131        /* If we're here, we either didn't try Kerberos/GSSAPI auth, or
132         * it failed.  In either case, we don't want to forward credentials.
133         *
134         * The v1 protocol code path calls this function with an empty
135         * password as a form of null authentication before trying any
136         * other auth types, so we need to check if we have a real password.
137         */
138        if (*password != '\0')
139          {
140#ifdef KRB5
141            options.kerberos_tgt_passing = 0;
142#endif
143#ifdef GSSAPI
144            if (gssapi_client_creds != GSS_C_NO_CREDENTIAL)
145              gss_release_cred(&ms, &gssapi_client_creds);
146#endif
147          }
148        /* deny if no user. */
149        if (pw == NULL)
150                return 0;
151#ifndef HAVE_CYGWIN
152       if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
153                return 0;
154#endif
155        if (*password == '\0' && options.permit_empty_passwd == 0)
156                return 0;
157#ifdef KRB5
158        if (options.kerberos_authentication == 1) {
159                int ret = auth_krb5_password(authctxt, password);
160                if (ret == 1 || ret == 0)
161                        return ret;
162                /* Fall back to ordinary passwd authentication. */
163        }
164#endif
165#ifdef HAVE_CYGWIN
166        if (is_winnt) {
167                HANDLE hToken = cygwin_logon_user(pw, password);
168
169                if (hToken == INVALID_HANDLE_VALUE)
170                        return 0;
171                cygwin_set_impersonation_token(hToken);
172                return 1;
173        }
174#endif
175#ifdef WITH_AIXAUTHENTICATE
176        authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0);
177
178        if (authsuccess)
179                /* We don't have a pty yet, so just label the line as "ssh" */
180                if (loginsuccess(authctxt->user,
181                        get_canonical_hostname(options.verify_reverse_mapping),
182                        "ssh", &aixloginmsg) < 0)
183                                aixloginmsg = NULL;
184
185        return(authsuccess);
186#endif
187#ifdef KRB4
188        if (options.kerberos_authentication == 1) {
189                int ret = auth_krb4_password(authctxt, password);
190                if (ret == 1 || ret == 0)
191                        return ret;
192                /* Fall back to ordinary passwd authentication. */
193        }
194#endif
195#ifdef BSD_AUTH
196        if (auth_userokay(pw->pw_name, authctxt->style, "auth-ssh",
197            (char *)password) == 0)
198                return 0;
199        else
200                return 1;
201#endif
202        pw_password = pw->pw_passwd;
203
204        /*
205         * Various interfaces to shadow or protected password data
206         */
207#if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW)
208        spw = getspnam(pw->pw_name);
209        if (spw != NULL)
210                pw_password = spw->sp_pwdp;
211#endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */
212
213#if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW)
214        if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL)
215                pw_password = spw->pwa_passwd;
216#endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */
217
218#ifdef HAVE_SECUREWARE
219        if ((spw = getprpwnam(pw->pw_name)) != NULL)
220                pw_password = spw->ufld.fd_encrypt;
221#endif /* HAVE_SECUREWARE */
222
223#if defined(__hpux) && !defined(HAVE_SECUREWARE)
224        if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL)
225                pw_password = spw->ufld.fd_encrypt;
226#endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */
227
228        /* Check for users with no password. */
229        if ((password[0] == '\0') && (pw_password[0] == '\0'))
230                return 1;
231
232        if (pw_password[0] != '\0')
233                salt = pw_password;
234        else
235                salt = "xx";
236
237#ifdef HAVE_MD5_PASSWORDS
238        if (is_md5_salt(salt))
239                encrypted_password = md5_crypt(password, salt);
240        else
241                encrypted_password = crypt(password, salt);
242#else /* HAVE_MD5_PASSWORDS */
243# if defined(__hpux) && !defined(HAVE_SECUREWARE)
244        if (iscomsec())
245                encrypted_password = bigcrypt(password, salt);
246        else
247                encrypted_password = crypt(password, salt);
248# else
249#  ifdef HAVE_SECUREWARE
250        encrypted_password = bigcrypt(password, salt);
251#  else
252        encrypted_password = crypt(password, salt);
253#  endif /* HAVE_SECUREWARE */
254# endif /* __hpux && !defined(HAVE_SECUREWARE) */
255#endif /* HAVE_MD5_PASSWORDS */
256
257        /* Authentication is accepted if the encrypted passwords are identical. */
258        return (strcmp(encrypted_password, pw_password) == 0);
259#endif /* !USE_PAM && !HAVE_OSF_SIA */
260}
Note: See TracBrowser for help on using the repository browser.