From owner-freebsd-bugs Mon Apr 20 07:25:25 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id HAA29131 for freebsd-bugs-outgoing; Mon, 20 Apr 1998 07:25:25 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: from ady.warpnet.ro (ady.warpnet.ro [193.230.201.1]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id OAA28984; Mon, 20 Apr 1998 14:23:36 GMT (envelope-from ady@warpnet.ro) Received: from localhost (ady@localhost) by ady.warpnet.ro (8.8.8/8.8.8) with SMTP id UAA08867; Mon, 20 Apr 1998 20:22:51 +0300 (EEST) (envelope-from ady@warpnet.ro) Date: Mon, 20 Apr 1998 20:22:51 +0300 (EEST) From: Penisoara Adrian Reply-To: Penisoara Adrian To: freebsd-security@FreeBSD.ORG cc: freebsd-bugs@FreeBSD.ORG Subject: Controlling MD5/DES use for passwd - Resumee Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Hi, First of all thanks goes to all who shared ideeas on this subject (wether in private or on the list). PROBLEM: Installing DES distribution changes the default behavior of the (non-DES) system to use MD5 for password encryption. WANTED: There should be a way to control which encryption scheme the system uses, wether MD5, DES or whatever else. BACKGROUND: The _passwd_ utility uses a crypt(3) call to encrypt the plain-text password it is given by the user. The code of this function resides in the _libcrypt_ library/libraries found in the /usr/lib directory. The standard crypt library which comes with FreeBSD (assuming that the "des" distribution is not installed) makes use of the MD5 encryption scheme and the code is found in the /usr/lib/libscrypt.* library, with libcrypt.* beeing sym-linked to it. Here it is the libscrypt content: # ar -t /usr/lib/libscrypt.a __.SYMDEF crypt.o md5c.o When the "des" distribution is installed a new _libdescrypt_ library appears and the libcrypt.* symlinks are updated to redirect to the new libdescrypt.* files. Note that this library contains the MD5 code too and the DES crypt() code is MD5 aware, recognisig the "$1$" MD5 signature in the salt and calling the MD5 code in that case. Here it is the libdescrypt content: # ar -t /usr/lib/libdescrypt.a __.SYMDEF crypt.o crypt-md5.o md5c.o Here it is the crypt() calling sequence in the passwd code found in the file usr.bin/passwd/local_passwd.c: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - #ifdef NEWSALT salt[0] = _PASSWORD_EFMT1; to64(&salt[1], (long)(29 * 25), 4); to64(&salt[5], random(), 4); salt[9] = '\0'; #else /* Make a good size salt for algoritms that can use it. */ gettimeofday(&tv,0); if (strncmp(pw->pw_passwd, "$1$", 3)) { /* DES Salt */ to64(&salt[0], random(), 3); to64(&salt[3], tv.tv_usec, 3); to64(&salt[6], tv.tv_sec, 2); salt[8] = '\0'; } else { /* MD5 Salt */ strncpy(&salt[0], "$1$", 3); to64(&salt[3], random(), 3); to64(&salt[6], tv.tv_usec, 3); salt[8] = '\0'; } #endif return (crypt(buf, salt)); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - In the current situation this is the behavior of passwd: * Creating a new user/password: uses de DES scheme * Changing a password: if the password was MD5 (it had the "$1$" signature) the new password will use the MD5 scheme, else will use the DES scheme FIX: The easy (& wrong) way: sym-linking the libcrypt.* files back to the libscrypt.* files when needing the new/changed passwords to be MD5 encrypted. This has the side-effect of making the already existing DES passwords useless (they will no longer be accepted/work). The hard (& good) way: making the passwd code multiple-scheme aware with posibility to control (the order of) the scheme(s) to use. SUGGESTIONS: For the config file it would probably make more sense using the login.conf database -- the current passwd already checks for two other settings (minpasswordlen and passwordperiod) in the login capability. Also, this will permit setting different schemes for different/special classes/users. Another option would be introducing an /etc/passwd.conf file. For the source-code implementation: either rely on the crypt() beeing multiple-scheme aware (choosing the scheme based on a signature in the salt, for example) and use the standard _libcrypt_ library, or try using the specific library for each encryption scheme requested -- making use of dlopen(3) ?. This depends also on the way password authentication will be done -- will it recognise the scheme from the signature contained in it or will it try every possible scheme ? Also, we should take care for other encryption schemes might appear. I believe using a standard crypt() makes the process of adding other new encryption schemes pretty hard -- the new crypt() function will have to incorporate hooks for every other scheme. Using specific libraries will (probably) cause some problems with static linked binaries. I would go for using specific dynamic libraries and including scheme-specific signatures in the encrypted password -- MD5 already makes a precedent. Also, passwd/the authentication routine should decide which scheme will be used and not the crypt() function -- you wouldn't like to have passwords encoded with not-approved-by-you schemes, would you ? Please note that currently I'm not in the position to suggest patches, I'm not (yet) such a skilled programmer and neither do I know very well the FreeBSD internals. Thank you, Adrian Penisoara Ady (@warpnet.ro) Warp Net Technologies To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message