"Fossies" - the Fresh Open Source Software archive 
Member "httpauth-0.9.5/tools/mkha1.c" of archive httpauth-0.9.5.tar.gz:
/*
* Copyright (c) 2004, Stefan Walter
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the
* above copyright notice, this list of conditions and
* the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * The names of contributors to this software may not be
* used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*
* CONTRIBUTORS
* Stef Walter <stef@memberwebs.com>
*
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.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 batch = 0;
int simple = 0;
ha_buffer_t buf;
int ch;
while((ch = getopt(argc, argv, "bp:r:su:")) != -1)
{
switch(ch)
{
case 'b':
batch = 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(batch)
{
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 -b [-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;
t = value + strlen(value);
/* Remove any new lines from end */
while(t > value && (*(t - 1) == '\n' || *(t - 1) == '\r'))
*(--t) = 0;
}
if(value[0] == 0)
errx(1, "%s is empty", name);
if(strchr(value, ':') != NULL)
errx(1, "%s must be a not contain colons", name);
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);
}
}