Created
February 7, 2016 13:13
-
-
Save mkmik/cc4b0cbf1e728cf38705 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include "common/md5.h" | |
// __builtin_types_compatible_p | |
///////////////////////////////////// | |
// some preprocessor magic | |
// double indirection needed to concatenate two macro expansions | |
#define M_CONCAT(x, y) M_PASTER(x, y) | |
#define M_PASTER(x, y) x##y | |
///////////////////////////////////// | |
// hack to detect empty vararg | |
// based on a majestic hack found in | |
// http://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ | |
// kudos to Jens Gustedt. | |
#define _ARG16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, \ | |
_14, _15, ...) \ | |
_15 | |
#define HAS_COMMA(...) \ | |
_ARG16(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0) | |
#define _TRIGGER_PARENTHESIS_(...) , | |
#define ISEMPTY(...) \ | |
_ISEMPTY(/* test if there is just one argument, eventually an empty \ | |
one */ \ | |
HAS_COMMA(__VA_ARGS__), /* test if _TRIGGER_PARENTHESIS_ together \ | |
with the argument \ | |
adds a comma */ \ | |
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__), /* test if the \ | |
argument together \ | |
with a parenthesis \ | |
adds a comma */ \ | |
HAS_COMMA(__VA_ARGS__(/*empty*/)), /* test if placing it between \ | |
_TRIGGER_PARENTHESIS_ and the \ | |
parenthesis adds a comma */ \ | |
HAS_COMMA(_TRIGGER_PARENTHESIS_ __VA_ARGS__(/*empty*/))) | |
#define _IS_EMPTY_CASE_0001 , | |
#define PASTE5(_0, _1, _2, _3, _4) _0##_1##_2##_3##_4 | |
#define _ISEMPTY(_0, _1, _2, _3) \ | |
HAS_COMMA(PASTE5(_IS_EMPTY_CASE_, _0, _1, _2, _3)) | |
////////// REAL CODE | |
#define _MD5_COND_1(iftrue, iffalse) iftrue | |
#define _MD5_COND_0(iftrue, iffalse) iffalse | |
#define _MD5_IF_LAST(iftrue, iffalse, eat, ...) \ | |
M_CONCAT(_MD5_COND_, ISEMPTY(__VA_ARGS__))(iftrue, iffalse) | |
#define _MD5_SENTINEL(...) NULL | |
#define _STATIC_ASSERT(COND, MSG) \ | |
typedef char static_assertion_##MSG[2 * (!!(COND)) - 1] | |
#define _MD5_CHECK_LEN(len) \ | |
({ \ | |
_STATIC_ASSERT(sizeof(typeof(len)) == sizeof(size_t), \ | |
LENGTH_MUST_BE_SIZE_T); \ | |
static_assertion_LENGTH_MUST_BE_SIZE_T dummy; \ | |
(void) dummy; \ | |
len; \ | |
}) | |
#define safe_md5_args_9(p, len, ...) ___BAD_ARGLIST_TOO_LONG | |
#define safe_md5_args_8(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_9, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_7(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_8, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_6(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_7, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_5(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_6, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_4(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_5, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_3(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_4, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_2(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_3, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args_1(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_2, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_md5_args(p, len, ...) \ | |
p, _MD5_CHECK_LEN(len), \ | |
_MD5_IF_LAST(_MD5_SENTINEL, safe_md5_args_1, __VA_ARGS__)(__VA_ARGS__) | |
#define safe_cs_md5(ha1, ...) cs_md5(ha1, safe_md5_args(__VA_ARGS__)) | |
static void add_pw_line(char ha1[33], const char *user, const char *domain, | |
const char *pass) { | |
safe_cs_md5(ha1, user, strlen(user), ":", (size_t)1, domain, strlen(domain), | |
":", (size_t)1, pass, strlen(pass), NULL); | |
printf("%s:%s:%s\n", user, domain, ha1); | |
} | |
int main() { | |
char ha1[33]; | |
add_pw_line(ha1, "joe", "cesanta.com", "bloggs"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment