Date: Mon, 20 Apr 1998 20:22:51 +0300 (EEST) From: Penisoara Adrian <ady@warpnet.ro> To: freebsd-security@FreeBSD.ORG Cc: freebsd-bugs@FreeBSD.ORG Subject: Controlling MD5/DES use for passwd - Resumee Message-ID: <Pine.BSF.3.96.980420174045.7675B-100000@ady.warpnet.ro>
next in thread | raw e-mail | index | archive | help
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 security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.3.96.980420174045.7675B-100000>
