From 8a78d61361180445eb316f8738751cc6d845799b Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 17 Aug 2004 23:18:00 +0000 Subject: Initial implementation of mkha1 --- tools/mkha1.c | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) create mode 100644 tools/mkha1.c (limited to 'tools/mkha1.c') diff --git a/tools/mkha1.c b/tools/mkha1.c new file mode 100644 index 0000000..3124e48 --- /dev/null +++ b/tools/mkha1.c @@ -0,0 +1,177 @@ + +#include +#include +#include +#include + +#include "compat.h" +#include "buffer.h" +#include "md5.h" + +/* ---------------------------------------------------------------------------------- + * FORWARD DECLs + */ +static void usage(); +static void process_file(ha_buffer_t* buf, int simple, int in); +static void process_ha1(ha_buffer_t* buf, const char* user, const char* realm, + const char* password); +static char* check_value(ha_buffer_t* buf, char* value, const char* name); + + +/* ---------------------------------------------------------------------------------- + * USER INTERACTION + */ + +int main(int argc, char* argv[]) +{ + char* user = NULL; + char* realm = NULL; + char* password = NULL; + int delimited = 0; + int simple = 0; + ha_buffer_t buf; + int ch; + + while((ch = getopt(argc, argv, "dp:r:su:")) != -1) + { + switch(ch) + { + case 'd': + delimited = 1; + break; + case 'p': + password = optarg; + break; + case 'r': + realm = optarg; + break; + case 's': + simple = 1; + break; + case 'u': + user = optarg; + break; + case '?': + default: + usage(); + break; + }; + } + + argc -= optind; + argv += optind; + + if(argc != 0) + usage(); + + ha_bufinit(&buf); + + if(delimited) + { + process_file(&buf, simple, 0); + } + else + { + user = check_value(&buf, user, "username"); + realm = check_value(&buf, realm, "realm"); + password = check_value(&buf, password, "password"); + + process_ha1(&buf, user, realm, password); + } + + return 0; +} + +static void usage() +{ + fprintf(stderr, "usage: mkha1 [-u user] [-r realm] [-p password]\n"); + fprintf(stderr, " mkha1 -d [-s]\n"); + exit(2); +} + +static char* check_value(ha_buffer_t* buf, char* value, const char* name) +{ + if(!value) + { + char* t = (char*)ha_bufmalloc(buf, 256); + if(t == NULL) + err(1, "out of memory"); + + printf("%s: ", name); + fgets(t, 256, stdin); + value = t; + } + + if(value[0] == 0) + errx("%s is empty"); + if(strchr(value, ':') != NULL) + errx("%s must be a not contain colons"); + + return value; +} + + +/* ---------------------------------------------------------------------------------- + * FUNCTIONALITY + */ + +static void process_ha1(ha_buffer_t* buf, const char* user, const char* realm, + const char* password) +{ + unsigned char hash[MD5_LEN]; + md5_ctx_t md5; + const char* t; + + ASSERT(buf && user && realm && password); + + md5_init(&md5); + md5_update(&md5, user, strlen(user)); + md5_update(&md5, ":", 1); + md5_update(&md5, realm, strlen(realm)); + md5_update(&md5, ":", 1); + md5_update(&md5, password, strlen(password)); + md5_final(hash, &md5); + + t = ha_bufenchex(buf, hash, MD5_LEN); + printf("%s\n", t); +} + +static void process_file(ha_buffer_t* buf, int simple, int in) +{ + const char* user; + const char* realm; + const char* password; + int more = 1; + int r; + + ASSERT(buf); + + while(more) + { + r = ha_bufreadline(in, buf); + if(r < 0) + err(1, "error reading input"); + if(r == 0) + more = 0; + + user = ha_bufparseword(buf, ":"); + realm = ha_bufparseword(buf, ":"); + password = ha_bufparseline(buf, 0); + + if(ha_buferr(buf)) + err(1, "out of memory"); + + if(!user || !user[0] || !realm || !realm[0] || !password || + !password[0] || strchr(password, ':') != NULL) + { + warnx("invalid input line. Must be in the form \"user:realm:password\""); + continue; + } + + if(!simple) + printf("%s:%s:", user, realm); + + process_ha1(buf, user, realm, password); + ha_bufreset(buf); + } +} -- cgit v1.2.3