diff options
author | Rich Megginson <rmeggins@redhat.com> | 2005-03-05 04:29:24 +0000 |
---|---|---|
committer | Rich Megginson <rmeggins@redhat.com> | 2005-03-05 04:29:24 +0000 |
commit | b352660e243c7b9b7d050f1c38cff1c9faf278b1 (patch) | |
tree | ede08019beb931c3206609ab2377a015d510bdb4 /ldap/admin/lib/dsalib_pw.c | |
parent | f08951680ddfebc3f3df07e720ad0650fe473c0f (diff) | |
download | ds-b352660e243c7b9b7d050f1c38cff1c9faf278b1.tar.gz ds-b352660e243c7b9b7d050f1c38cff1c9faf278b1.tar.xz ds-b352660e243c7b9b7d050f1c38cff1c9faf278b1.zip |
clean up sprintf usage and many other flawfinder issues; clean up compiler warnings on Linux; remove pam_passthru from DS 7.1
Diffstat (limited to 'ldap/admin/lib/dsalib_pw.c')
-rw-r--r-- | ldap/admin/lib/dsalib_pw.c | 107 |
1 files changed, 106 insertions, 1 deletions
diff --git a/ldap/admin/lib/dsalib_pw.c b/ldap/admin/lib/dsalib_pw.c index 6b224514..4c560c92 100644 --- a/ldap/admin/lib/dsalib_pw.c +++ b/ldap/admin/lib/dsalib_pw.c @@ -20,7 +20,112 @@ #include "dsalib.h" #include "dsalib_pw.h" -extern char * salted_sha1_pw_enc(char *); +#include "prtime.h" +#include "prlong.h" +#include "prmem.h" + +#if defined(NET_SSL) +#include <pk11func.h> +#include <pk11pqg.h> +#endif /* NET_SSL */ + +#define SHA1_SALT_LENGTH 8 /* number of bytes of data in salt */ +#define PWD_HASH_PREFIX_START '{' +#define PWD_HASH_PREFIX_END '}' + +#define SALTED_SHA1_SCHEME_NAME "SSHA" +#define SALTED_SHA1_NAME_LEN 4 + +/* + WARNING: The following code is blatantly copied from the server + pwdstorage ssha_pwd.c plugin. It would be nice to share this + code with the server. The problem is that the server wants to + use slapi_ch_malloc to allocate the memory for the returned + password - this function is not available outside the server + (as in the setup programs that also want to hash the password) + We need to figure out a way to put this code into a library + in such a way that the memory allocation functions to use + can be passed in or set beforehand. +*/ + +static void +ssha_rand_array(void *randx, size_t len) +{ + PK11_RandomUpdate(randx, len); + PK11_GenerateRandom((unsigned char *)randx, (int)len); +} + +/* + * A salted SHA1 hash + * if salt is null, no salt is used (this is for backward compatibility) +*/ +SECStatus +sha1_salted_hash(unsigned char *hash_out, char *pwd, struct berval *salt) +{ + PK11Context *ctx; + unsigned int outLen; + SECStatus rc; + + if (salt && salt->bv_len) { + ctx = PK11_CreateDigestContext(SEC_OID_SHA1); + if (ctx == NULL) { + rc = SECFailure; + } + else { + PK11_DigestBegin(ctx); + PK11_DigestOp(ctx, (unsigned char*)pwd, strlen(pwd)); + PK11_DigestOp(ctx, (unsigned char*)(salt->bv_val), salt->bv_len); + PK11_DigestFinal(ctx, hash_out, &outLen, SHA1_LENGTH); + PK11_DestroyContext(ctx, 1); + if (outLen == SHA1_LENGTH) + rc = SECSuccess; + else + rc = SECFailure; + } + } + else { + /*backward compatibility*/ + rc = PK11_HashBuf(SEC_OID_SHA1, hash_out, (unsigned char *)pwd, strlen(pwd)); + } + + return rc; +} + +char * +salted_sha1_pw_enc( char *pwd ) +{ + unsigned char hash[ SHA1_LENGTH + SHA1_SALT_LENGTH ]; + unsigned char *salt = hash + SHA1_LENGTH; + struct berval saltval; + char *enc; + + saltval.bv_val = (void*)salt; + saltval.bv_len = SHA1_SALT_LENGTH; + + /* generate a new random salt */ + /* Note: the uninitialized salt array provides a little extra entropy + * to the random array generation, but it is not really needed since + * PK11_GenerateRandom takes care of seeding. In any case, it doesn't + * hurt. */ + ssha_rand_array( salt, SHA1_SALT_LENGTH ); + + /* SHA1 hash the user's key */ + if ( sha1_salted_hash( hash, pwd, &saltval ) != SECSuccess ) { + return( NULL ); + } + + if (( enc = PR_Malloc( 3 + SALTED_SHA1_NAME_LEN + + LDIF_BASE64_LEN(sizeof(hash)))) == NULL ) { + return( NULL ); + } + + sprintf( enc, "%c%s%c", PWD_HASH_PREFIX_START, SALTED_SHA1_SCHEME_NAME, + PWD_HASH_PREFIX_END ); + (void)ldif_base64_encode( hash, enc + 2 + SALTED_SHA1_NAME_LEN, + sizeof(hash), -1 ); + + return( enc ); +} DS_EXPORT_SYMBOL char * ds_salted_sha1_pw_enc (char* pwd) |