+/* $OpenLDAP$ */\r
/*\r
* This file is derived from OpenLDAP Software. All of the modifications to\r
* OpenLDAP Software represented in the following file were developed by\r
* notice:\r
*\r
* Copyright 2011 Devin J. Pohly\r
+ * Portions Copyright 2011 Howard Chu\r
* Redistribution and use in source and binary forms, with or without\r
* modification, are permitted only as authorized by the OpenLDAP Public\r
* License. \r
*\r
* A portion of this code is used in accordance with the Beer-ware License,\r
* revision 42, as noted.\r
+ *\r
*/\r
#include <lber.h>\r
#include <lber_pvt.h>\r
\r
#include <assert.h>\r
\r
+/* the only difference between this and straight PHK is the magic */\r
static LUTIL_PASSWD_CHK_FUNC chk_apr1;\r
static LUTIL_PASSWD_HASH_FUNC hash_apr1;\r
-static const struct berval scheme = BER_BVC("{APR1}");\r
+static const struct berval scheme_apr1 = BER_BVC("{APR1}");\r
+static const struct berval magic_apr1 = BER_BVC("$apr1$");\r
+\r
+static LUTIL_PASSWD_CHK_FUNC chk_bsdmd5;\r
+static LUTIL_PASSWD_HASH_FUNC hash_bsdmd5;\r
+static const struct berval scheme_bsdmd5 = BER_BVC("{BSDMD5}");\r
+static const struct berval magic_bsdmd5 = BER_BVC("$1$");\r
\r
static const unsigned char apr64[] =\r
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";\r
\r
#define APR_SALT_SIZE 8\r
\r
-/* copied from liblutil/passwd.c */\r
-static int pw_string64(\r
- const struct berval *sc,\r
- const struct berval *hash,\r
- struct berval *b64,\r
- const struct berval *salt )\r
-{\r
- int rc;\r
- struct berval string;\r
- size_t b64len;\r
-\r
- if( salt ) {\r
- /* need to base64 combined string */\r
- string.bv_len = hash->bv_len + salt->bv_len;\r
- string.bv_val = ber_memalloc( string.bv_len + 1 );\r
-\r
- if( string.bv_val == NULL ) {\r
- return LUTIL_PASSWD_ERR;\r
- }\r
-\r
- AC_MEMCPY( string.bv_val, hash->bv_val,\r
- hash->bv_len );\r
- AC_MEMCPY( &string.bv_val[hash->bv_len], salt->bv_val,\r
- salt->bv_len );\r
- string.bv_val[string.bv_len] = '\0';\r
-\r
- } else {\r
- string = *hash;\r
- }\r
-\r
- b64len = LUTIL_BASE64_ENCODE_LEN( string.bv_len ) + 1;\r
- b64->bv_len = b64len + sc->bv_len;\r
- b64->bv_val = ber_memalloc( b64->bv_len + 1 );\r
-\r
- if( b64->bv_val == NULL ) {\r
- if( salt ) ber_memfree( string.bv_val );\r
- return LUTIL_PASSWD_ERR;\r
- }\r
-\r
- AC_MEMCPY(b64->bv_val, sc->bv_val, sc->bv_len);\r
-\r
- rc = lutil_b64_ntop(\r
- (unsigned char *) string.bv_val, string.bv_len,\r
- &b64->bv_val[sc->bv_len], b64len );\r
-\r
- if( salt ) ber_memfree( string.bv_val );\r
- \r
- if( rc < 0 ) {\r
- return LUTIL_PASSWD_ERR;\r
- }\r
-\r
- /* recompute length */\r
- b64->bv_len = sc->bv_len + rc;\r
- assert( strlen(b64->bv_val) == b64->bv_len );\r
- return LUTIL_PASSWD_OK;\r
-}\r
-\r
/* The algorithm implemented in this function was created by Poul-Henning\r
* Kamp and released under the following license:\r
* ----------------------------------------------------------------------------\r
* this stuff is worth it, you can buy me a beer in return Poul-Henning Kamp\r
* ----------------------------------------------------------------------------\r
*/\r
-static void do_apr_hash(\r
+static void do_phk_hash(\r
const struct berval *passwd,\r
const struct berval *salt,\r
+ const struct berval *magic,\r
unsigned char *digest)\r
{\r
lutil_MD5_CTX ctx, ctx1;\r
/* Start hashing */\r
lutil_MD5Init(&ctx);\r
lutil_MD5Update(&ctx, (const unsigned char *) passwd->bv_val, passwd->bv_len);\r
- lutil_MD5Update(&ctx, "$apr1$", 6);\r
+ lutil_MD5Update(&ctx, (const unsigned char *) magic->bv_val, magic->bv_len);\r
lutil_MD5Update(&ctx, (const unsigned char *) salt->bv_val, salt->bv_len);\r
/* Inner hash */\r
lutil_MD5Init(&ctx1);\r
}\r
}\r
\r
-static int chk_apr1(\r
- const struct berval *scheme,\r
+static int chk_phk(\r
+ const struct berval *magic,\r
const struct berval *passwd,\r
const struct berval *cred,\r
const char **text)\r
salt.bv_val = (char *) &orig_pass[sizeof(digest)];\r
salt.bv_len = rc - sizeof(digest);\r
\r
- /* the only difference between this and straight PHK is the magic */\r
- do_apr_hash(cred, &salt, digest);\r
+ do_phk_hash(cred, magic, &salt, digest);\r
\r
if (text)\r
*text = NULL;\r
return rc ? LUTIL_PASSWD_ERR : LUTIL_PASSWD_OK;\r
}\r
\r
-static int hash_apr1(\r
+static int chk_apr1(\r
+ const struct berval *scheme,\r
+ const struct berval *passwd,\r
+ const struct berval *cred,\r
+ const char **text)\r
+{\r
+ return chk_phk(&magic_apr1, passwd, cred, text);\r
+}\r
+\r
+static int chk_bsdmd5(\r
const struct berval *scheme,\r
const struct berval *passwd,\r
+ const struct berval *cred,\r
+ const char **text)\r
+{\r
+ return chk_phk(&magic_bsdmd5, passwd, cred, text);\r
+}\r
+\r
+static int hash_phk(\r
+ const struct berval *scheme,\r
+ const struct berval *magic,\r
+ const struct berval *passwd,\r
struct berval *hash,\r
const char **text)\r
{\r
for (n = 0; n < salt.bv_len; n++)\r
salt.bv_val[n] = apr64[salt.bv_val[n] % (sizeof(apr64) - 1)];\r
\r
- /* the only difference between this and straight PHK is the magic */\r
- do_apr_hash(passwd, &salt, digest_buf);\r
+ do_phk_hash(passwd, magic, &salt, digest_buf);\r
\r
if (text)\r
*text = NULL;\r
\r
- return pw_string64(scheme, &digest, hash, &salt);\r
+ return lutil_passwd_string64(scheme, &digest, hash, &salt);\r
+}\r
+\r
+static int hash_apr1(\r
+ const struct berval *scheme,\r
+ const struct berval *passwd,\r
+ struct berval *hash,\r
+ const char **text)\r
+{\r
+ return hash_phk(scheme, &magic_apr1, passwd, hash, text);\r
+}\r
+\r
+static int hash_bsdmd5(\r
+ const struct berval *scheme,\r
+ const struct berval *passwd,\r
+ struct berval *hash,\r
+ const char **text)\r
+{\r
+ return hash_phk(scheme, &magic_bsdmd5, passwd, hash, text);\r
}\r
\r
int init_module(int argc, char *argv[]) {\r
- return lutil_passwd_add((struct berval *) &scheme, chk_apr1, hash_apr1);\r
-}
\ No newline at end of file
+ int rc;\r
+ rc = lutil_passwd_add((struct berval *) &scheme_apr1, chk_apr1, hash_apr1);\r
+ if ( !rc )\r
+ rc = lutil_passwd_add((struct berval *) &scheme_bsdmd5,\r
+ chk_bsdmd5, hash_bsdmd5);\r
+ return rc;\r
+}\r