diff options
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.in | 2 | ||||
-rw-r--r-- | tools/.cvsignore | 4 | ||||
-rw-r--r-- | tools/Makefile.am | 8 | ||||
-rw-r--r-- | tools/mkha1.c | 177 |
5 files changed, 191 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am index 3f6293e..cd093df 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,6 @@ EXTRA_DIST = apache1x common config.sub acsite.m4 -SUBDIRS = daemon doc +SUBDIRS = daemon doc tools dist-hook: rm -rf `find $(distdir)/ -name CVS` diff --git a/configure.in b/configure.in index ebe14cd..87b485c 100644 --- a/configure.in +++ b/configure.in @@ -170,5 +170,5 @@ if test -n "$enable_ntlm"; then AC_DEFINE_UNQUOTED(WITH_NTLM, 1, [With NTLM Support] ) fi -AC_CONFIG_FILES([Makefile daemon/Makefile doc/Makefile]) +AC_CONFIG_FILES([Makefile daemon/Makefile doc/Makefile tools/Makefile]) AC_OUTPUT diff --git a/tools/.cvsignore b/tools/.cvsignore new file mode 100644 index 0000000..1bd9f34 --- /dev/null +++ b/tools/.cvsignore @@ -0,0 +1,4 @@ +Makefile +Makefile.in +mkha1 +.deps diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..aa3519f --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,8 @@ + +sbin_PROGRAMS = mkha1 + +mkha1_SOURCES = mkha1.c \ + ../common/compat.h ../common/compat.c ../common/buffer.h ../common/buffer.c \ + ../common/md5.h ../common/md5.c ../common/stringx.c ../common/stringx.h + +mkha1_CFLAGS = -I${top_srcdir}/common/ -I${top_srcdir} 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 <sys/types.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> + +#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); + } +} |