diff --git a/ChangeLog b/ChangeLog index fa8ee2fbe..5676dafcb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +20030724 + - (bal) [auth-passwd.c openbsd-compat/Makefile.in openbsd-compat/xcrypt.c + openbsd-compat/xcrypt.h] Split off encryption into xcrypt() interface, + and isolate shadow password functions. Tested in Solaris, but should + not break other platforms too badly (except maybe HP =). Also brings + auth-passwd.c into full sync with OpenBSD tree. + 20030723 - (dtucker) [configure.ac] Back out change for bug #620. @@ -721,4 +728,4 @@ - Fix sshd BindAddress and -b options for systems using fake-getaddrinfo. Report from murple@murple.net, diagnosis from dtucker@zip.com.au -$Id: ChangeLog,v 1.2864 2003/07/23 04:33:10 dtucker Exp $ +$Id: ChangeLog,v 1.2865 2003/07/24 06:52:13 mouring Exp $ diff --git a/auth-passwd.c b/auth-passwd.c index f078eddd5..c0b7f725f 100644 --- a/auth-passwd.c +++ b/auth-passwd.c @@ -42,46 +42,14 @@ RCSID("$OpenBSD: auth-passwd.c,v 1.27 2002/05/24 16:45:16 stevesk Exp $"); #include "log.h" #include "servconf.h" #include "auth.h" -#include "buffer.h" -#include "xmalloc.h" -#include "canohost.h" - -#if !defined(HAVE_OSF_SIA) -/* Don't need any of these headers for the SIA cases */ -# ifdef HAVE_CRYPT_H -# include -# endif -# ifdef __hpux -# include -# include -# endif -# ifdef HAVE_SECUREWARE -# include -# include -# include -# endif /* HAVE_SECUREWARE */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) -# include -# endif -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) -# include -# include -# include -# endif -# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) -# include "md5crypt.h" -# endif /* defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) */ - -# ifdef HAVE_CYGWIN -# undef ERROR -# include -# include -# define is_winnt (GetVersion() < 0x80000000) -# endif -#endif /* !HAVE_OSF_SIA */ +#include "openbsd-compat/xcrypt.h" +#ifdef WITH_AIXAUTHENTICATE +# include "buffer.h" +# include "canohost.h" +extern Buffer loginmsg; +#endif extern ServerOptions options; -extern Buffer loginmsg; /* * Tries to authenticate the user using password. Returns true if @@ -92,25 +60,6 @@ auth_password(Authctxt *authctxt, const char *password) { struct passwd * pw = authctxt->pw; int ok = authctxt->valid; -#if !defined(HAVE_OSF_SIA) - char *encrypted_password; - char *pw_password; - char *salt; -# if defined(__hpux) || defined(HAVE_SECUREWARE) - struct pr_passwd *spw; -# endif /* __hpux || HAVE_SECUREWARE */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - struct spwd *spw; -# endif -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - struct passwd_adjunct *spw; -# endif -# ifdef WITH_AIXAUTHENTICATE - char *authmsg; - int authsuccess; - int reenter = 1; -# endif -#endif /* !defined(HAVE_OSF_SIA) */ /* deny if no user. */ if (pw == NULL) @@ -122,13 +71,12 @@ auth_password(Authctxt *authctxt, const char *password) if (*password == '\0' && options.permit_empty_passwd == 0) ok = 0; -#if defined(HAVE_OSF_SIA) if (!ok) return 0; + +#if defined(HAVE_OSF_SIA) return auth_sia_password(authctxt, password); #else - if (!ok) - return 0; # ifdef KRB5 if (options.kerberos_authentication == 1) { int ret = auth_krb5_password(authctxt, password); @@ -148,32 +96,40 @@ auth_password(Authctxt *authctxt, const char *password) } # endif # ifdef WITH_AIXAUTHENTICATE - authsuccess = (authenticate(pw->pw_name,password,&reenter,&authmsg) == 0); - aix_remove_embedded_newlines(authmsg); + { + char *authmsg; + int reenter = 1; + int authsuccess = (authenticate(pw->pw_name, password, + &reenter, &authmsg) == 0); + aix_remove_embedded_newlines(authmsg); - if (authsuccess) { - char *msg; - char *host = (char *)get_canonical_hostname(options.use_dns); + if (authsuccess) { + char *msg; + char *host = + (char *)get_canonical_hostname(options.use_dns); - debug3("AIX/authenticate succeeded for user %s: %.100s", - pw->pw_name, authmsg); + debug3("AIX/authenticate succeeded for user %s: %.100s", + pw->pw_name, authmsg); - /* We don't have a pty yet, so just label the line as "ssh" */ - if (loginsuccess(authctxt->user, host, "ssh", &msg) == 0){ - if (msg != NULL) { - debug("%s: msg %s", __func__, msg); - buffer_append(&loginmsg, msg, strlen(msg)); - xfree(msg); + /* No pty yet, so just label the line as "ssh" */ + if (loginsuccess(authctxt->user, host, "ssh", + &msg) == 0){ + if (msg != NULL) { + debug("%s: msg %s", __func__, msg); + buffer_append(&loginmsg, msg, + strlen(msg)); + xfree(msg); + } } - } - } else { - debug3("AIX/authenticate failed for user %s: %.100s", - pw->pw_name, authmsg); - } - if (authmsg != NULL) - xfree(authmsg); + } else + debug3("AIX/authenticate failed for user %s: %.100s", + pw->pw_name, authmsg); - return (authsuccess); + if (authmsg != NULL) + xfree(authmsg); + + return (authsuccess); + } # endif # ifdef KRB4 if (options.kerberos_authentication == 1) { @@ -189,63 +145,27 @@ auth_password(Authctxt *authctxt, const char *password) return 0; else return 1; -# endif - pw_password = pw->pw_passwd; - - /* - * Various interfaces to shadow or protected password data - */ -# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) - spw = getspnam(pw->pw_name); - if (spw != NULL) - pw_password = spw->sp_pwdp; -# endif /* defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) */ - -# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) - if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) - pw_password = spw->pwa_passwd; -# endif /* defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) */ - -# ifdef HAVE_SECUREWARE - if ((spw = getprpwnam(pw->pw_name)) != NULL) - pw_password = spw->ufld.fd_encrypt; -# endif /* HAVE_SECUREWARE */ - -# if defined(__hpux) && !defined(HAVE_SECUREWARE) - if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) - pw_password = spw->ufld.fd_encrypt; -# endif /* defined(__hpux) && !defined(HAVE_SECUREWARE) */ +# else + { + char *pw_password = shadow_pw(pw); /* Check for users with no password. */ - if ((password[0] == '\0') && (pw_password[0] == '\0')) + /* XXX Reverted back to OpenBSD, why was this changed again? */ + if (strcmp(pw_password, "") == 0 && strcmp(pw->pw_passwd, "") == 0) return 1; + else { + /* Encrypt the candidate password using the proper salt. */ + char *encrypted_password = xcrypt(password, + (pw_password[0] && pw_password[1]) ? pw_password : "xx"); - if (pw_password[0] != '\0') - salt = pw_password; - else - salt = "xx"; + /* + * Authentication is accepted if the encrypted passwords + * are identical. + */ + return (strcmp(encrypted_password, pw_password) == 0); + } -# ifdef HAVE_MD5_PASSWORDS - if (is_md5_salt(salt)) - encrypted_password = md5_crypt(password, salt); - else - encrypted_password = crypt(password, salt); -# else /* HAVE_MD5_PASSWORDS */ -# if defined(__hpux) && !defined(HAVE_SECUREWARE) - if (iscomsec()) - encrypted_password = bigcrypt(password, salt); - else - encrypted_password = crypt(password, salt); -# else -# ifdef HAVE_SECUREWARE - encrypted_password = bigcrypt(password, salt); -# else - encrypted_password = crypt(password, salt); -# endif /* HAVE_SECUREWARE */ -# endif /* __hpux && !defined(HAVE_SECUREWARE) */ -# endif /* HAVE_MD5_PASSWORDS */ - - /* Authentication is accepted if the encrypted passwords are identical. */ - return (strcmp(encrypted_password, pw_password) == 0); + } +# endif #endif /* !HAVE_OSF_SIA */ } diff --git a/openbsd-compat/Makefile.in b/openbsd-compat/Makefile.in index fb481efd2..c48593f7b 100644 --- a/openbsd-compat/Makefile.in +++ b/openbsd-compat/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.27 2003/06/05 08:52:48 djm Exp $ +# $Id: Makefile.in,v 1.28 2003/07/24 06:52:14 mouring Exp $ sysconfdir=@sysconfdir@ piddir=@piddir@ @@ -18,7 +18,7 @@ LDFLAGS=-L. @LDFLAGS@ OPENBSD=base64.o basename.o bindresvport.o daemon.o dirname.o getcwd.o getgrouplist.o getopt.o getrrsetbyname.o glob.o inet_aton.o inet_ntoa.o inet_ntop.o mktemp.o readpassphrase.o realpath.o rresvport.o setenv.o setproctitle.o sigact.o strlcat.o strlcpy.o strmode.o strsep.o vis.o -COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o +COMPAT=bsd-arc4random.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-snprintf.o bsd-waitpid.o fake-rfc2553.o xmmap.o xcrypt.o PORTS=port-irix.o port-aix.o diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c new file mode 100644 index 000000000..167a23513 --- /dev/null +++ b/openbsd-compat/xcrypt.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +#if !defined(HAVE_OSF_SIA) + +# ifdef HAVE_CRYPT_H +# include +# endif + +# ifdef __hpux +# include +# include +# endif + +# ifdef HAVE_SECUREWARE +# include +# include +# include +# endif + +# if defined(HAVE_SHADOW_H) && !defined(DISABLE_SHADOW) +# include +# endif + +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) +# include +# include +# include +# endif + +# if defined(HAVE_MD5_PASSWORDS) && !defined(HAVE_MD5_CRYPT) +# include "md5crypt.h" +# endif + +# ifdef HAVE_CYGWIN +# undef ERROR +# include +# include +# define is_winnt (GetVersion() < 0x80000000) +# endif + +char * +xcrypt(const char *password, const char *salt) +{ + char *crypted; + +# ifdef HAVE_MD5_PASSWORDS + if (is_md5_salt(salt)) + crypted = md5_crypt(password, salt); + else + crypted = crypt(password, salt); +# elsif defined(__hpux) && !defined(HAVE_SECUREWARE) + if (iscomsec()) + crypted = bigcrypt(password, salt); + else + crypted = crypt(password, salt); +# elsif defined(HAVE_SECUREWARE) + crypted = bigcrypt(password, salt); +# else + crypted = crypt(password, salt); +# endif + + return crypted; +} + +/* + * Handle shadowed password systems in a cleaner way for portable + * version. + */ + +char * +shadow_pw(struct passwd *pw) +{ + char *pw_password = pw->pw_passwd; + +# if defined(HAVE_SHADOW_H) && !defined(DISABLED_SHADOW) + struct spwd *spw = getspnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->sp_pwdp; +# endif +# if defined(HAVE_GETPWANAM) && !defined(DISABLE_SHADOW) + struct passwd_adjunct *spw; + if (issecure() && (spw = getpwanam(pw->pw_name)) != NULL) + pw_password = spw->pwa_passwd; +# elsif defined(HAVE_SECUREWARE) + struct pr_passwd *spw = getprpwnam(pw->pw_name); + + if (spw != NULL) + pw_password = spw->ufld.fd_encrypt; +# elsif defined(__hpux) && !defined(HAVE_SECUREWARE) + struct pr_passwd *spw; + if (iscomsec() && (spw = getprpwnam(pw->pw_name)) != NULL) + pw_password = spw->ufld.fd_encrypt; +# endif + + return pw_password; +} + +#endif /* !defined(HAVE_OSF_SIA) */ diff --git a/openbsd-compat/xcrypt.h b/openbsd-compat/xcrypt.h new file mode 100644 index 000000000..16c55fc67 --- /dev/null +++ b/openbsd-compat/xcrypt.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2003 Ben Lindstrom. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "includes.h" + +char *xcrypt(const char *password, const char *salt); +char *shadow_pw(struct passwd *pw);