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

Cleanup: Replaced final bit of MD5 code with something nice

This replaces the MD5 related code with something that is much nicer:
The new code consists of util_crypt_hash() that can be used to hash
a password and util_crypt_check() which is used to check the password
taking into account options and salts.
This commit is contained in:
Philipp Schafft 2023-02-20 23:05:51 +00:00
parent f1c32d7bf4
commit 898d38768c
10 changed files with 83 additions and 166 deletions

View File

@ -17,6 +17,7 @@ noinst_HEADERS = \
global.h \
util.h \
util_string.h \
util_crypt.h \
errors.h \
curl.h \
slave.h \
@ -29,7 +30,6 @@ noinst_HEADERS = \
fserve.h \
xslt.h \
yp.h \
md5.h \
digest.h \
prng.h \
matchfile.h \
@ -71,6 +71,7 @@ icecast_SOURCES = \
global.c \
util.c \
util_string.c \
util_crypt.c \
errors.c \
slave.c \
source.c \
@ -82,7 +83,6 @@ icecast_SOURCES = \
fserve.c \
admin.c \
resourcematch.c \
md5.c \
digest.c \
prng.c \
matchfile.c \

View File

@ -31,7 +31,7 @@
#include "client.h"
#include "cfgfile.h"
#include "common/httpp/httpp.h"
#include "md5.h"
#include "util_crypt.h"
#include "logging.h"
#define CATMODULE "auth_htpasswd"
@ -68,22 +68,6 @@ static void htpasswd_clear(auth_t *self)
}
/* md5 hash */
static char *get_hash(const char *data)
{
struct MD5Context context;
unsigned char digest[16];
MD5Init(&context);
MD5Update(&context, (const unsigned char *)data, strlen(data));
MD5Final(digest, &context);
return util_bin_to_hex(digest, 16);
}
static int compare_users(void *arg, void *a, void *b)
{
htpasswd_user *user1 = (htpasswd_user *)a;
@ -200,15 +184,11 @@ static auth_result htpasswd_auth (auth_client *auth_user)
entry.name = client->username;
if (avl_get_by_key (htpasswd->users, &entry, &result) == 0) {
htpasswd_user *found = result;
char *hashed_pw;
thread_rwlock_unlock (&htpasswd->file_rwlock);
hashed_pw = get_hash(client->password);
if (strcmp (found->pass, hashed_pw) == 0) {
free (hashed_pw);
if (util_crypt_check(client->password, found->pass)) {
return AUTH_OK;
}
free (hashed_pw);
ICECAST_LOG_DEBUG("incorrect password for client with username: %s", client->username);
return AUTH_FAILED;
}
@ -291,7 +271,7 @@ static auth_result htpasswd_adduser (auth_t *auth, const char *username, const c
return AUTH_FAILED;
}
hashed_password = get_hash(password);
hashed_password = util_crypt_hash(password);
if (hashed_password) {
fprintf(passwdfile, "%s:%s\n", username, hashed_password);
free(hashed_password);

View File

@ -17,7 +17,6 @@
#include <stdlib.h>
#include "digest.h"
#include "md5.h"
#include "logging.h"
#define CATMODULE "digest"
@ -32,7 +31,6 @@ struct digest_tag {
/* state */
int done;
union {
struct MD5Context md5;
struct {
/* 1600 bits algorithm hashing state */
uint64_t hash[25];
@ -328,9 +326,6 @@ const char *digest_algo_id2str(digest_algo_t algo)
{
switch (algo) {
case DIGEST_ALGO_MD5:
return "MD5";
break;
case DIGEST_ALGO_SHA3_224:
return "SHA3-224";
break;
@ -350,9 +345,6 @@ const char *digest_algo_id2str(digest_algo_t algo)
ssize_t digest_algo_length_bytes(digest_algo_t algo)
{
switch (algo) {
case DIGEST_ALGO_MD5:
return 16;
break;
case DIGEST_ALGO_SHA3_224:
return 224/8;
break;
@ -379,9 +371,6 @@ digest_t * digest_new(digest_algo_t algo)
digest->algo = algo;
switch (algo) {
case DIGEST_ALGO_MD5:
MD5Init(&(digest->state.md5));
break;
case DIGEST_ALGO_SHA3_224:
sha3_init(digest, 224);
break;
@ -427,10 +416,6 @@ ssize_t digest_write(digest_t *digest, const void *data, size_t len)
return -1;
switch (digest->algo) {
case DIGEST_ALGO_MD5:
MD5Update(&(digest->state.md5), (const unsigned char *)data, len);
return len;
break;
case DIGEST_ALGO_SHA3_224:
case DIGEST_ALGO_SHA3_256:
case DIGEST_ALGO_SHA3_384:
@ -455,17 +440,6 @@ ssize_t digest_read(digest_t *digest, void *buf, size_t len)
digest->done = 1;
switch (digest->algo) {
case DIGEST_ALGO_MD5:
if (len < HASH_LEN) {
unsigned char buffer[HASH_LEN];
MD5Final(buffer, &(digest->state.md5));
memcpy(buf, buffer, len);
return len;
} else {
MD5Final((unsigned char*)buf, &(digest->state.md5));
return HASH_LEN;
}
break;
case DIGEST_ALGO_SHA3_224:
case DIGEST_ALGO_SHA3_256:
case DIGEST_ALGO_SHA3_384:
@ -490,7 +464,6 @@ ssize_t digest_length_bytes(digest_t *digest)
static size_t __digest_algo_blocklength(digest_algo_t algo)
{
switch (algo) {
case DIGEST_ALGO_MD5: return 64; break;
case DIGEST_ALGO_SHA3_224: return 144; break;
case DIGEST_ALGO_SHA3_256: return 136; break;
case DIGEST_ALGO_SHA3_384: return 104; break;

View File

@ -15,7 +15,6 @@ REFOBJECT_FORWARD_TYPE(digest_t);
REFOBJECT_FORWARD_TYPE(hmac_t);
typedef enum {
DIGEST_ALGO_MD5,
DIGEST_ALGO_SHA3_224,
DIGEST_ALGO_SHA3_256,
DIGEST_ALGO_SHA3_384,

View File

@ -1,65 +0,0 @@
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2000-2004, Jack Moffitt <jack@xiph.org,
* Michael Smith <msmith@xiph.org>,
* oddsock <oddsock@xiph.org>,
* Karl Heyes <karl@xiph.org>
* and others (see AUTHORS for details).
* Copyright 2014-2015, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
/*
* md5.c
*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
/* Modified for icecast by Mike Smith <msmith@xiph.org>, mostly changing header
* and type definitions
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "compat.h"
#include "md5.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
/* The following are proxy functions. This will be removed once more updates have been done */
void MD5Init(struct MD5Context *ctx)
{
ctx->rhash = rhash_init(RHASH_MD5);
}
void MD5Update(struct MD5Context *ctx, unsigned char const *buf,
unsigned len)
{
rhash_update(ctx->rhash, buf, len);
}
void MD5Final(unsigned char digest[HASH_LEN], struct MD5Context *ctx)
{
rhash_final(ctx->rhash, digest);
rhash_free(ctx->rhash);
memset(ctx, 0, sizeof(*ctx));
}

View File

@ -1,34 +0,0 @@
/* Icecast
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*
* Copyright 2000-2004, Jack Moffitt <jack@xiph.org,
* Michael Smith <msmith@xiph.org>,
* oddsock <oddsock@xiph.org>,
* Karl Heyes <karl@xiph.org>
* and others (see AUTHORS for details).
*/
#ifndef __MD5_H__
#define __MD5_H__
#include "compat.h"
#include <rhash.h>
#define HASH_LEN 16
struct MD5Context {
rhash rhash;
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
unsigned len);
void MD5Final(unsigned char digest[HASH_LEN], struct MD5Context *context);
#endif

View File

@ -36,7 +36,7 @@ check_PROGRAMS += ctest_string_renderer.test
ctest_crypt_test_SOURCES = tests/ctest_crypt.c
ctest_crypt_test_LDADD = \
icecast-util_string.o \
icecast-md5.o
icecast-util_crypt.o
check_PROGRAMS += ctest_crypt.test
# Add all programs to TESTS

View File

@ -17,27 +17,18 @@
#include <igloo/tap.h>
#include "../md5.h"
#include "../util_string.h"
#include "../util_crypt.h"
void test_md5_hash(const char *in, const char *expect, bool positive)
{
struct MD5Context context;
unsigned char digest[16];
char *out;
MD5Init(&context);
MD5Update(&context, (const unsigned char *)in, strlen(in));
MD5Final(digest, &context);
out = util_bin_to_hex(digest, 16);
char *out = util_crypt_hash(in);
if (positive) {
igloo_tap_test("md5 positive vector", strcmp(out, expect) == 0);
igloo_tap_test("md5 positive match", util_crypt_check(in, expect));
} else {
igloo_tap_test("md5 negative vector", strcmp(out, expect) != 0);
igloo_tap_test("md5 negative match", !util_crypt_check(in, expect));
}
free(out);

56
src/util_crypt.c Normal file
View File

@ -0,0 +1,56 @@
/* Icecast
*
* Copyright 2023 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <rhash.h>
#include "util_crypt.h"
#include "util_string.h"
#define HASH_LEN 16
char * util_crypt_hash(const char *pw)
{
unsigned char digest[HASH_LEN];
if (rhash_msg(RHASH_MD5, pw, strlen(pw), digest) != 0)
return NULL;
return util_bin_to_hex(digest, HASH_LEN);
}
bool util_crypt_check(const char *plain, const char *crypted)
{
size_t len;
if (!plain || !crypted)
return false;
len = strlen(crypted);
if (len == (HASH_LEN*2) && crypted[0] != '$') {
char *digest = util_crypt_hash(plain);
bool res;
if (!digest)
return false;
res = strcmp(digest, crypted) == 0;
free(digest);
return res;
}
return false;
}

17
src/util_crypt.h Normal file
View File

@ -0,0 +1,17 @@
/* Icecast
*
* Copyright 2023 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
*
* This program is distributed under the GNU General Public License, version 2.
* A copy of this license is included with this source.
*/
#ifndef __UTIL_CRYPT_H__
#define __UTIL_CRYPT_H__
#include <stdbool.h>
char * util_crypt_hash(const char *pw);
bool util_crypt_check(const char *plain, const char *crypted);
#endif /* __UTIL_CRYPT_H__ */