mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
parent
f2b3814b57
commit
0ef660bcde
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user