1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-12-04 14:46:30 -05:00

Feature: Use more modern algo for password store

Closes: #2010
This commit is contained in:
Philipp Schafft 2023-02-21 22:47:40 +00:00
parent f2b3814b57
commit 0ef660bcde
3 changed files with 91 additions and 4 deletions

View File

@ -16,12 +16,16 @@
#include <rhash.h> #include <rhash.h>
#include <igloo/tap.h> #include <igloo/tap.h>
#include <igloo/ro.h>
#include "../util_crypt.h" #include "../util_crypt.h"
/* Workaround: Avoiding the need to add global.c */
igloo_ro_t igloo_instance = igloo_RO_NULL;
void test_md5_hash(const char *in, const char *expect, bool positive) void test_md5_hash(const char *in, const char *expect, bool positive)
{ {
char *out = util_crypt_hash(in); char *out = util_crypt_hash_oldstyle(in);
if (positive) { if (positive) {
igloo_tap_test("md5 positive vector", strcmp(out, expect) == 0); igloo_tap_test("md5 positive vector", strcmp(out, expect) == 0);

View File

@ -21,10 +21,13 @@
#include <crypt.h> #include <crypt.h>
#endif #endif
#if !defined(HAVE_CRYPT_R) && defined(HAVE_CRYPT) && defined(HAVE_PTHREAD) #if (defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT)) && defined(HAVE_PTHREAD)
#include <pthread.h> #include <pthread.h>
#endif #endif
#include <igloo/prng.h>
#include "global.h"
#include "util_crypt.h" #include "util_crypt.h"
#include "util_string.h" #include "util_string.h"
@ -34,7 +37,29 @@
static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t crypt_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif #endif
char * util_crypt_hash(const char *pw) #if (defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT)) && HAVE_PTHREAD
static pthread_once_t crypt_detect = PTHREAD_ONCE_INIT;
static const char *new_prefix;
static size_t new_saltlen;
void crypt_detect_run(void)
{
static const struct {
const char prefix[4];
const size_t saltlen;
} list[] = {{"$6$", 12}, {"$5$", 12}, {"$1$", 6}};
for (size_t i = 0; i < (sizeof(list)/sizeof(*list)); i++) {
if (util_crypt_is_supported(list[i].prefix)) {
new_prefix = list[i].prefix;
new_saltlen = list[i].saltlen;
return;
}
}
}
#endif
char * util_crypt_hash_oldstyle(const char *pw)
{ {
unsigned char digest[HASH_LEN]; unsigned char digest[HASH_LEN];
@ -44,6 +69,61 @@ char * util_crypt_hash(const char *pw)
return util_bin_to_hex(digest, HASH_LEN); return util_bin_to_hex(digest, HASH_LEN);
} }
char * util_crypt_hash(const char *pw)
{
#if (defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT)) && HAVE_PTHREAD
if (pthread_once(&crypt_detect, crypt_detect_run) != 0)
return NULL;
if (new_prefix) {
char input[128];
char salt[64];
char *salt_base64;
ssize_t len;
#ifdef HAVE_CRYPT_R
struct crypt_data data;
#elif defined(HAVE_CRYPT) && defined(HAVE_PTHREAD)
char *data;
#endif
/* if this is true, we have a bug */
if (new_saltlen > sizeof(salt))
return NULL;
len = igloo_prng_read(igloo_instance, salt, new_saltlen, igloo_PRNG_FLAG_NONE);
if (len != (ssize_t)new_saltlen)
return NULL;
salt_base64 = util_base64_encode(salt, new_saltlen);
if (!salt_base64)
return NULL;
snprintf(input, sizeof(input), "%s%s", new_prefix, salt_base64);
free(salt_base64);
#ifdef HAVE_CRYPT_R
memset(&data, 0, sizeof(data));
return strdup(crypt_r(pw, input, &data));
#elif defined(HAVE_CRYPT) && defined(HAVE_PTHREAD)
if (pthread_mutex_lock(&crypt_mutex) != 0)
return NULL;
data = strdup(crypt(pw, input));
pthread_mutex_unlock(&crypt_mutex);
return data;
#else
#error "BUG"
#endif
} else {
#endif
return util_crypt_hash_oldstyle(pw);
#if (defined(HAVE_CRYPT_R) || defined(HAVE_CRYPT)) && HAVE_PTHREAD
}
#endif
}
bool util_crypt_check(const char *plain, const char *crypted) bool util_crypt_check(const char *plain, const char *crypted)
{ {
size_t len; size_t len;
@ -58,7 +138,7 @@ bool util_crypt_check(const char *plain, const char *crypted)
/* below here we know that plain and crypted are non-null and that crypted is at least one byte long */ /* below here we know that plain and crypted are non-null and that crypted is at least one byte long */
if (len == (HASH_LEN*2) && crypted[0] != '$') { if (len == (HASH_LEN*2) && crypted[0] != '$') {
char *digest = util_crypt_hash(plain); char *digest = util_crypt_hash_oldstyle(plain);
bool res; bool res;
if (!digest) if (!digest)

View File

@ -15,4 +15,7 @@ char * util_crypt_hash(const char *pw);
bool util_crypt_check(const char *plain, const char *crypted); bool util_crypt_check(const char *plain, const char *crypted);
bool util_crypt_is_supported(const char *prefix); bool util_crypt_is_supported(const char *prefix);
/* Exported for tests only!: */
char * util_crypt_hash_oldstyle(const char *pw);
#endif /* __UTIL_CRYPT_H__ */ #endif /* __UTIL_CRYPT_H__ */