2 Commits

Author SHA1 Message Date
Adel I. Mirzazhanov
8087f2a5e4 APG v2.0.0a0 2023-07-12 10:57:50 +02:00
Adel I. Mirzazhanov
8b93e6095b APG v1.2.13 2023-07-12 10:51:00 +02:00
17 changed files with 1371 additions and 34 deletions

16
CHANGES
View File

@@ -1,5 +1,17 @@
apg-2.0.0a0
Added new algorithm (-b option) to check generated passwords
quality (Bloom filter).
Added utility apgbfm to manage Bloom filter.
Some code style fixes.
Added APG_TIPS file in documentation.
apg-1.2.13
Added support for NetBSD.
(Thanks to Tomasz Luchowski <zuntum@eik.pl>).
apg-1.2.12
Added support for AIX, and some compatibility reports
Added support for AIX, and some compatibility reports.
(Thanks to Philip Le Riche <pleriche@uk03.bull.co.uk>).
apg-1.2.11
Changed default owner of apg and apgd (now it is root).
@@ -13,7 +25,7 @@ apg-1.2.1b
before compilation.
Added option -M for new style password modes specification.
(see apg(1) apgd(8)).
Added support for IRIX
Added support for IRIX.
(Thanks to Andrew J. Caird <acaird@advance-inc.com>)
apg-1.2.1a2

View File

@@ -28,6 +28,9 @@ If you are reading this file, you probably have already done this!
% make all
During the make process compiler will generate some warnings
Just ignore this fact. I'm working to fix them.
4. install the binaries and man pages. You may need to be superuser
to do this (depending on where you are installing things):

View File

@@ -8,6 +8,10 @@ FLAGS = -Wall
# libraries
LIBS = -lcrypt
LIBM = -lm
# Use lines below for cygwin
# LIBS =
# LIBM =
# DO NOT EDIT THE LINE BELOW !!!
CRYPTED_PASS = APG_DONOTUSE_CRYPT
@@ -41,23 +45,33 @@ FIND_GROUP = `grep '^root:' /etc/passwd | awk -F: '{ print $$4 }'`
PROGNAME = apg
CS_PROGNAME = apgd
SOURCES = rnd.c ./cast/cast.c pronpass.c randpass.c restrict.c errors.c apg.c
BFM_PROGNAME = apgbfm
BFM_SOURCES = apgbfm.c bloom.c md5/md5.c errors.c
SOURCES = bloom.c md5/md5.c rnd.c ./cast/cast.c pronpass.c randpass.c restrict.c errors.c apg.c
HEADERS = owntypes.h pronpass.h randpass.h restrict.h errs.h rnd.h ./cast/cast.h ./cast/cast_sboxes.h
OBJECTS = rnd.o ./cast/cast.o pronpass.o randpass.o restrict.o apg.o errors.o
all: cliserv standalone
cliserv: apgd apgbfm
standalone: apg apgbfm
cygwin: standalone
cliserv: ${SOURCES} ${HEADERS}
${CC} ${FLAGS} ${CS_LIBS} -DCLISERV -o ${CS_PROGNAME} ${SOURCES}
apg:
${CC} ${FLAGS} ${LIBS} ${LIBM} -D${CRYPTED_PASS} -o ${PROGNAME} ${SOURCES}
standalone: ${SOURCES} ${HEADERS}
${CC} ${FLAGS} ${LIBS} -D${CRYPTED_PASS} -o ${PROGNAME} ${SOURCES}
apgd:
${CC} ${FLAGS} ${CS_LIBS} ${LIBM} -DCLISERV -o ${CS_PROGNAME} ${SOURCES}
apgbfm:
${CC} ${FLAGS} ${LIBM} -o ${BFM_PROGNAME} ${BFM_SOURCES}
strip:
strip ${PROGNAME}
strip ${CS_PROGNAME}
strip ${BFM_PROGNAME}
install:
if test -x ./apg; then \
@@ -71,6 +85,12 @@ fi
./mkinstalldirs ${INSTALL_PREFIX}${APGD_MAN_DIR}; \
./install-sh -c -m 0755 -o root -g ${FIND_GROUP} ./apgd ${INSTALL_PREFIX}${APGD_BIN_DIR}; \
./install-sh -c -m 0444 ./doc/man/apgd.8 ${INSTALL_PREFIX}${APGD_MAN_DIR}; \
fi
if test -x ./apgbfm; then \
./mkinstalldirs ${INSTALL_PREFIX}${APG_BIN_DIR}; \
./mkinstalldirs ${INSTALL_PREFIX}${APG_MAN_DIR}; \
./install-sh -c -m 0755 -o root -g ${FIND_GROUP} ./apgbfm ${INSTALL_PREFIX}${APG_BIN_DIR}; \
./install-sh -c -m 0444 ./doc/man/apgbfm.1 ${INSTALL_PREFIX}${APG_MAN_DIR}; \
fi
install-cygwin:
@@ -79,7 +99,13 @@ install-cygwin:
./mkinstalldirs ${INSTALL_PREFIX}${APG_MAN_DIR}; \
./install-sh -c -m 0755 ./apg.exe ${INSTALL_PREFIX}${APG_BIN_DIR}; \
./install-sh -c -m 0444 ./doc/man/apg.1 ${INSTALL_PREFIX}${APG_MAN_DIR}; \
fi
if test -x ./apgbfm.exe; then \
./mkinstalldirs ${INSTALL_PREFIX}${APG_BIN_DIR}; \
./mkinstalldirs ${INSTALL_PREFIX}${APG_MAN_DIR}; \
./install-sh -c -m 0755 ./apgbfm.exe ${INSTALL_PREFIX}${APG_BIN_DIR}; \
./install-sh -c -m 0444 ./doc/man/apgbfm.1 ${INSTALL_PREFIX}${APG_MAN_DIR}; \
fi
clean:
rm -f ${CS_PROGNAME} ${PROGNAME} ${OBJECTS} core*
rm -f ${CS_PROGNAME} ${PROGNAME} ${BFM_PROGNAME} ${OBJECTS} core*

13
README
View File

@@ -1,7 +1,15 @@
APG v1.2.12 was tested and found working on:
APG v2.0.0a0 was tested and found working on:
i386 FreeBSD 4.0-RELEASE
i386 Linux-Mandrake 6.0
Intel Solaris 8 gcc-2.95.2
Intel Windows 2000+CYGWIN v1.1.4
APG v1.2.13 was tested and found working on:
i386 FreeBSD 4.0-RELEASE
NetBSD (reported by Tomasz Luchowski <zuntum@eik.pl>)
i386 Linux-Mandrake 6.0
i386 Linux-Redhat 7.0
i386 Linux-Mandrake 7.2 (reported by Andrew J. Caird <acaird@advance-inc.com>)
Intel Solaris 8 gcc-2.95.2
@@ -14,10 +22,11 @@ APG v1.2.12 was tested and found working on:
AIX 4.3.3+native cc (reported by Philip Le Riche <pleriche@uk03.bull.co.uk>)
AIX 4.3.3+gcc (reported by Philip Le Riche <pleriche@uk03.bull.co.uk>)
Any compatibility reports are welcom
Any compatibility reports are welcome
* For installation instructions see INSTALL
* For usage instructions see manpages
* For tips see doc/APG_TIPS
* For copying information see COPYING
See also APG Homepage at: http://www.adel.nursat.kz/apg/

2
THANKS
View File

@@ -8,3 +8,5 @@ Adrian Ho <lexfiend@usa.net>
Andrew J. Caird <acaird@advance-inc.com>
Alexander J Pierce <apierce@boi.hp.com>
Philip Le Riche <pleriche@uk03.bull.co.uk>
Tomasz Luchowski <zuntum@eik.pl>
Barton Hodges <barton@gcmcomputers.com>

43
apg.c
View File

@@ -35,14 +35,23 @@
#include <strings.h>
#include <string.h>
#include <time.h>
#define APG_VERSION "2.0.0a0"
#ifdef __NetBSD__
#include <unistd.h>
#endif
#define MAX_MODE_LENGTH 5
#ifndef _XOPEN_SOURCE
#define _XOPEN_SOURCE
#endif
#ifndef __NetBSD__
#include <unistd.h>
/*#include <crypt.h>*/
#endif
#ifdef __CYGWIN__
#include <getopt.h>
#undef APG_USE_CRYPT
@@ -60,6 +69,7 @@
#include "pronpass.h"
#include "randpass.h"
#include "restrict.h"
#include "bloom.h"
#include "rnd.h"
#include "errs.h"
@@ -89,6 +99,7 @@ main (int argc, char *argv[])
int algorithm = 0; /* algorithm for generation */
int restrictions_present = FALSE; /* restrictions flag */
int bloom_restrict_present = FALSE; /* bloom filter restrictions flag */
char *restrictions_file; /* dictionary file name */
unsigned int pass_mode = 0; /* password generation mode */
unsigned int pass_mode_present = FALSE; /* password generation mode flag */
@@ -137,12 +148,12 @@ main (int argc, char *argv[])
*/
#ifndef CLISERV
#ifdef APG_USE_CRYPT
while ((option = getopt (argc, argv, "SNCLRM:a:r:sdc:n:m:x:hvy")) != -1)
while ((option = getopt (argc, argv, "SNCLRM:a:r:b:sdc:n:m:x:hvy")) != -1)
#else /* APG_USE_CRYPT */
while ((option = getopt (argc, argv, "SNCLRM:a:r:sdc:n:m:x:hv")) != -1)
while ((option = getopt (argc, argv, "SNCLRM:a:r:b:sdc:n:m:x:hv")) != -1)
#endif /* APG_USE_CRYPT */
#else /* CLISERV */
while ((option = getopt (argc, argv, "SNCLRM:a:r:n:m:x:v")) != -1)
while ((option = getopt (argc, argv, "SNCLRM:a:r:b:n:m:x:v")) != -1)
#endif /* CLISERV */
{
switch (option)
@@ -182,6 +193,11 @@ main (int argc, char *argv[])
restrictions_present = TRUE;
restrictions_file = optarg;
break;
case 'b': /* bloom restrictions */
restrictions_present = TRUE;
bloom_restrict_present = TRUE;
restrictions_file = optarg;
break;
#ifndef CLISERV
case 's': /* user random seed required */
user_defined_seed = get_user_seq ();
@@ -220,7 +236,7 @@ main (int argc, char *argv[])
#endif /* CLISERV */
case 'v': /* print version */
printf ("APG (Automated Password Generator)");
printf ("\nversion 1.2.11");
printf ("\nversion %s", APG_VERSION);
printf ("\nCopyright (c) 1999, 2000, 2001 Adel I. Mirzazhanov\n");
return (0);
default: /* print help end exit */
@@ -277,9 +293,12 @@ main (int argc, char *argv[])
(void *)crypt_string, 255);
#endif /* APG_USE_CRYPT */
#endif /* CLISERV */
if (restrictions_present == 1)
if (restrictions_present == TRUE)
{
restrict_res = check_pass(pass_string, restrictions_file);
if (bloom_restrict_present == TRUE)
restrict_res = bloom_check_pass(pass_string, restrictions_file);
else
restrict_res = check_pass(pass_string, restrictions_file);
switch (restrict_res)
{
case 0:
@@ -344,9 +363,12 @@ main (int argc, char *argv[])
(void *)crypt_string, 255);
#endif /* APG_USE_CRYPT */
#endif /* CLISERV */
if (restrictions_present == 1)
if ( (restrictions_present == TRUE))
{
restrict_res = check_pass(pass_string, restrictions_file);
if (bloom_restrict_present == TRUE)
restrict_res = bloom_check_pass(pass_string, restrictions_file);
else
restrict_res = check_pass(pass_string, restrictions_file);
switch (restrict_res)
{
case 0:
@@ -464,6 +486,8 @@ print_help (void)
printf ("\n-S -N -C -L -R password modes\n");
printf ("-M mode new style pasword modes\n");
printf ("-r file apply dictionary check against file\n");
printf ("-b filter_file apply bloom filter check against filter_file\n");
printf (" (filter_file should be created with apgbfm(1) utility)\n");
printf ("-a algorithm choose algorithm\n");
printf (" 1 - random password generation according to\n");
printf (" password modes\n");
@@ -560,3 +584,4 @@ unsigned int construct_mode(char *s_mode)
}
return (mode);
}

298
apgbfm.c Normal file
View File

@@ -0,0 +1,298 @@
/*
** Copyright (c) 2001
** Adel I. Mirzazhanov. All rights reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1.Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2.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.
** 3.The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
#include <stdlib.h>
#include <unistd.h>
#include "bloom.h"
#include "errs.h"
#ifdef __CYGWIN__
#include <getopt.h>
#endif /* __CYGWIN__ */
#define VERSION "1.0.0a0"
int main (int argc, char *argv[]);
void print_help(void);
void checkopt(char *opt);
int
main (int argc, char *argv[])
{
int option = 0;
char *dictfile; /* dictionary filename */
FILE *f_dictfile; /* dictionary file descriptor */
char *filter; /* filter file name */
FILE *f_filter; /* filter file descriptor */
char *word; /* word to add or check */
h_val wc = 0L; /* amount of words to build dictionaty */
h_val filter_size =0L; /* filter size in bits */
int dummy_test = 0; /* variable to make dummy test for */
/* options correctness */
h_val i = 0L; /* cointer */
/* flags */
flag add_word_flag = FALSE; /* -a */
flag add_file_flag = FALSE; /* -A */
flag check_word_flag = FALSE; /* -c */
flag check_file_flag = FALSE; /* -C */
flag new_flag = FALSE; /* -n */
flag new_from_dict_flag = FALSE; /* -d */
flag filter_flag = FALSE; /* -f */
/* end of flags section */
/* Analize options */
if (argc < 2)
{
print_help();
exit(-1);
}
while ((option = getopt (argc, argv, "a:A:c:C:n:d:f:hv")) != -1)
{
switch(option)
{
case 'a':
word = optarg;
add_word_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'A':
dictfile = optarg;
add_file_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'c':
word = optarg;
check_word_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'C':
dictfile = optarg;
check_file_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'n':
checkopt(optarg);
wc = atoi(optarg);
new_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'd':
dictfile = optarg;
new_from_dict_flag = TRUE;
dummy_test = dummy_test + 2;
break;
case 'f':
filter = optarg;
filter_flag = TRUE;
dummy_test = dummy_test + 1;
break;
case 'h':
print_help();
return (0);
case 'v':
printf ("APG Bloom filter management programm");
printf ("\nversion %s", VERSION);
printf ("\nCopyright (c) 2001 Adel I. Mirzazhanov\n");
return (0);
default:
print_help();
exit(-1);
}
}
if (filter_flag != TRUE) err_app_fatal ("apg", "-f option is required");
if (dummy_test != 3) err_app_fatal ("apg", "too many options");
/* Main part */
/* At this point we can be sure that all options a correct */
if (add_word_flag == TRUE)
{
if ( (f_filter = open_filter(filter)) == NULL)
err_sys_fatal("open_filter");
filter_size = get_filtersize(f_filter);
if ( insert_word (word, f_filter, filter_size) == -1)
err_sys_fatal("insert_word");
printf ("Word %s added\n",word);
return (0);
}
if (add_file_flag == TRUE)
{
word = (char *) calloc(1,MAX_DICT_STRLEN);
if ( (f_dictfile = fopen(dictfile,"r")) == NULL)
err_sys_fatal("fopen");
if( (f_filter = open_filter(filter)) == NULL)
err_sys_fatal("open_filter");
filter_size = get_filtersize(f_filter);
while ((fgets(word, MAX_DICT_STRLEN, f_dictfile) != NULL))
{
word = (char *)strtok (word," \t\n\0");
if ( insert_word (word, f_filter, filter_size) == -1)
err_sys_fatal("insert_word");
i++;
if ( i % 100 == 0)
{
fprintf (stdout,".");
fflush (stdout);
}
bzero((void *)word, MAX_DICT_STRLEN);
}
printf ("\n");
free ( (void *)word);
fclose (f_dictfile);
fclose (f_filter);
return (0);
}
if (check_word_flag == TRUE)
{
if ( (f_filter = open_filter(filter)) == NULL)
err_sys_fatal("open_filter");
filter_size = get_filtersize(f_filter);
switch(check_word (word, f_filter, filter_size))
{
case -1:
err_sys_fatal("check_word");
break;
case 1:
printf ("%s: FOUND \n",word);
break;
case 0:
printf ("%s: NOT FOUND\n",word);
break;
}
return (0);
}
if (check_file_flag == TRUE)
{
word = (char *) calloc(1,MAX_DICT_STRLEN);
if ( (f_dictfile = fopen(dictfile,"r")) == NULL)
err_sys_fatal("fopen");
wc = count_words (f_dictfile);
if( (f_filter = open_filter(filter)) == NULL)
err_sys_fatal("open_filter");
filter_size = get_filtersize(f_filter);
while ((fgets(word, MAX_DICT_STRLEN, f_dictfile) != NULL))
{
word = (char *)strtok (word," \t\n\0");
switch(check_word (word, f_filter, filter_size))
{
case -1:
err_sys_fatal("check_word");
break;
case 1:
printf ("%s: FOUND \n",word);
break;
case 0:
printf ("%s: NOT FOUND\n",word);
break;
}
bzero((void *)word, MAX_DICT_STRLEN);
}
free ( (void *)word);
fclose (f_dictfile);
fclose (f_filter);
return (0);
}
if (new_flag == TRUE) /* -n nwords */
{
if ((f_filter = create_filter(filter, wc)) == NULL)
err_sys_fatal("create_filter");
fclose(f_filter);
return (0);
}
if (new_from_dict_flag == TRUE) /* -d dictfile */
{
word = (char *) calloc(1,MAX_DICT_STRLEN);
if ( (f_dictfile = fopen(dictfile,"r")) == NULL)
err_sys_fatal("fopen");
fprintf (stdout,"Counting words in dictionary. Please wait...\n");
fflush (stdout);
wc = count_words (f_dictfile);
if( (f_filter = create_filter(filter, wc)) == NULL)
err_sys_fatal("create_filter");
filter_size = get_filtersize(f_filter);
while ((fgets(word, MAX_DICT_STRLEN, f_dictfile) != NULL))
{
word = (char *)strtok (word," \t\n\0");
if ( insert_word (word, f_filter, filter_size) == -1)
err_sys_fatal("insert_word");
i++;
if ( i % 100 == 0)
{
fprintf (stdout, ".");
fflush (stdout);
}
bzero((void *)word, MAX_DICT_STRLEN);
}
printf ("\n");
free ( (void *)word);
fclose (f_dictfile);
fclose (f_filter);
return (0);
}
return (0);
}
/*
** print_help - prints short help info
** INPUT: NOTHING
** RETURN: NOTHING
*/
void
print_help(void)
{
printf ("\napgbfm APG Bloom filter management\n");
printf (" Copyright (c) 2001 Adel I. Mirzazhanov\n");
printf ("\napgbfm -f filter < [-a word] | [-A dictfile] | [-n numofwords] |\n");
printf (" [-c word] | [-C dictfile] | [-d dictfile] >\n");
printf ("apgbfm [-v] [-h]\n\n");
printf ("-a word add word to filter\n");
printf ("-A dictfile add words from dictfile to filter\n");
printf ("-c word check word against filter\n");
printf ("-C dictfile check dictfile against filter\n");
printf ("-n numofwords create new empty filter\n");
printf ("-d dictfile create new filter and add all words from dictfile\n");
printf ("-f filtername use filtername as the name for filter\n");
printf ("-v print version information\n");
printf ("-h print help (this screen)\n");
}
void
checkopt(char *opt)
{
int i;
for(i=0; i < strlen(opt);i++)
if(opt[i] != '0' && opt[i] != '1' && opt[i] != '2' && opt[i] != '3' &&
opt[i] != '4' && opt[i] != '5' && opt[i] != '6' && opt[i] != '7' &&
opt[i] != '8' && opt[i] != '9')
err_app_fatal ("checkopt", "wrong option format");
}

330
bloom.c Normal file
View File

@@ -0,0 +1,330 @@
/*
** Copyright (c) 2001
** Adel I. Mirzazhanov. All rights reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1.Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2.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.
** 3.The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
** C module for APG (Automated Password Generator)
** Bloom filter implementation.
** Functions:
** insert_word - insert word in the filter file
** check_word - check word
** create_filter - create initial(empty) filter file
** open_filter - open APG Bloom filter file
** get_filtersize - get APG Bloom filter size
** count_words - count words in plain dictionary file
***************************************************************************
** hash2bit - generates 4 values (should be 4 values of independent
** hash functions) from input string.
** getbit - get the bit value from file.
** putbit - put the bit in the file.
*/
#include "bloom.h"
h_val * hash2bit(char * word, h_val *b);
int getbit(FILE * f, h_val bitnum);
int putbit(FILE * f, h_val bitnum);
/*
** insert_word - insert word in the filter file
** INPUT:
** char *word - word to incert in the filter
** FILE *file - filter file descriptor
** h_val filter_size - filter size in bits
** RETURN:
** int
** 0 - everything OK
** -1 - something wrong
*/
int
insert_word(char *word, FILE *file, h_val filter_size)
{
h_val h[4];
int i = 0;
hash2bit (word, &h[0]);
for(i = 0; i < 4; i++)
if (putbit (file, h[i] % filter_size)== -1)
return (-1);
return(0);
}
/*
** check_word - check word
** INPUT:
** char *word - word to check
** FILE *file - filter file descriptor
** h_val filter_size - filter size in bits
** RETURN:
** int
** 0 - word is not in dictionary
** 1 - word is in dictionary
** -1 - something wrong
*/
int
check_word(char *word, FILE *file, h_val filter_size)
{
h_val h[4];
int i = 0;
hash2bit (word, &h[0]);
for(i = 0; i < 4; i++)
{
switch(getbit(file, h[i] % filter_size))
{
case 0:
return(0);
break;
case -1:
return(-1);
break;
default:
break;
}
}
return (1);
}
/*
** open_filter - open APG Bloom filter file
** open filter file and check is this the real bloom filter file
** INPUT:
** char * f_name - filter filename
** RETURN:
** FILE * - file pointer
** NULL - something wrong.
*/
FILE *
open_filter(char * f_name)
{
FILE *f;
struct apg_bf_hdr bf_hdr;
if ((f = fopen (f_name, "r+")) == NULL)
return(NULL);
if(fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) < APGBFHDRSIZE)
if (ferror (f) != 0)
return(NULL);
if( (bf_hdr.id[0] != 'A') || (bf_hdr.id[1] != 'P') ||
(bf_hdr.id[2] != 'G') || (bf_hdr.id[3] != 'B') ||
(bf_hdr.id[4] != 'F') || (bf_hdr.id[5] != '1') ||
(bf_hdr.id[6] != '0') || (bf_hdr.id[7] != '0') ) return (NULL);
else
{
if (fseek (f, 0, SEEK_SET) == -1)
return(NULL);
return(f);
}
}
/*
** get_filtersize - get APG Bloom filter size
** INPUT:
** FILE *f - filter file descriptor
** RETURN:
** h_val - size of APG Bloom filter.
*/
h_val
get_filtersize(FILE * f)
{
struct apg_bf_hdr bf_hdr;
fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f);
fseek (f, 0, SEEK_SET);
return( (h_val)bf_hdr.fs);
}
/*
** create_filter - create initial(empty) filter file
** 4 - number of hash functions
** 0.0001 (0.01%) - probability of false positives
** INPUT:
** char * f_name - filter filename
** unsigned long int n_words - number of words in filter
** RETURN:
** FILE * - filter file descriptor
** NULL - something wrong
***********************************************************
** n - number of words in the filter
** N - size of filter(?)
**
** a=(1-(4/N))^n
** 0.0001=(1-a)^4 ==> 1-a=0.1 ==> a=0.9 ==>
** 0.9=(1-(4/N))^n ==> 0.9^(1/n)=1-(4/N) ==>
**
** N=4/(1-[0.9^(1/n)])
**
** 4
** N = ----------
** 1/n
** 1 - 0.9
*/
FILE *
create_filter(char * f_name, unsigned long int n_words)
{
FILE *f;
char zero = 0x00;
long int i = 0L;
struct apg_bf_hdr bf_hdr;
bf_hdr.id[0] = 'A';
bf_hdr.id[1] = 'P';
bf_hdr.id[2] = 'G';
bf_hdr.id[3] = 'B';
bf_hdr.id[4] = 'F';
bf_hdr.id[5] = '1';
bf_hdr.id[6] = '0';
bf_hdr.id[7] = '0';
bf_hdr.fs = FSIZE_BIT(n_words);
if ((f = fopen (f_name, "w+")) == NULL)
return(NULL);
if (fwrite ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) < APGBFHDRSIZE)
if (ferror (f) != 0)
return(NULL);
for (i = 0; i < FSIZE_BYTE(n_words); i++)
if ( fwrite ( (void *)&zero, 1, 1, f) < 1)
if (ferror (f) != 0)
return(NULL);
if (fseek (f, 0, SEEK_SET) == -1)
return (NULL);
return (f);
}
/*
** count_words - count words in plain dictionary file
** INPUT:
** FILE *dict_file -plain dicionary file descriptor
** RETURN:
** h_val - amount of words in dictionary file
*/
h_val
count_words(FILE *dict_file)
{
h_val i = 0L; /* word counter */
char *string; /* temp string holder */
string = (char *) calloc(1,MAX_DICT_STRLEN);
while ((fgets(string, MAX_DICT_STRLEN, dict_file) != NULL))
i++;
fseek (dict_file, 0, SEEK_SET);
free ((void *) string);
return (i);
}
/*
** hash2bit - generates 4 values (should be 4 values of independent
** hash functions) from input string.
** INPUT:
** char *word - word to hash
** h_val *b - pointer to bitnumber array
** RETURN
** h_val * - pointer to bitnumber array
*/
h_val *
hash2bit(char * word, h_val *b)
{
struct apg_MD5Context context;
unsigned char cs[16];
apg_MD5Init (&context);
apg_MD5Update (&context, word, strlen(word));
apg_MD5Final (cs, &context);
return ( (h_val *)memcpy( (void *)b, (void *)&cs[0], 16));
}
/*
** getbit - get the bit value from file.
** INPUT:
** FILE *f - file descriptor
** h_val bitnum - bit number
** RETURN:
** int
** 0,1 - bit value
** -1 - something wrong
*/
int
getbit(FILE * f, h_val bitnum)
{
long int bytenum = 0L;
short int bit_in_byte = 0;
unsigned char read_byte = 0x00;
unsigned char test_byte = 0x01;
int i = 0;
bit_in_byte = bitnum % 8;
bytenum = APGBFHDRSIZE + (bitnum/8);
if (fseek (f, bytenum, SEEK_SET) == -1)
return(-1);
if (fread ((void*)&read_byte,1,1,f) < 1)
if (ferror(f) != 0)
return (-1);
for (i=0;i < bit_in_byte;i++)
test_byte = test_byte*2;
if ((read_byte & test_byte) > 0) return (1);
else return (0);
}
/*
** putbit - put the bit in the file.
** INPUT:
** FILE *f - file descriptor
** h_val bitnum - bit number
** RETURN:
** int
** 0 - everything OK
** -1 - something wrong
*/
int
putbit(FILE * f, h_val bitnum)
{
long int bytenum = 0L;
short int bit_in_byte = 0;
unsigned char read_byte = 0x00;
unsigned char test_byte = 0x01;
int i = 0;
bit_in_byte = bitnum % 8;
bytenum = APGBFHDRSIZE + (bitnum/8);
if (fseek (f, bytenum, SEEK_SET) == -1)
return(-1);
if (fread ((void*)&read_byte,1,1,f) < 1)
if (ferror(f) != 0)
return (-1);
for (i=0;i < bit_in_byte;i++)
test_byte = test_byte*2;
read_byte = read_byte | test_byte;
if (fseek (f, bytenum, SEEK_SET) == -1)
return(-1);
if (fwrite ((void*)&read_byte,1,1,f) < 1)
if (ferror(f) != 0)
return (-1);
return (0);
}
/* END OF bloom.c file */

80
bloom.h Normal file
View File

@@ -0,0 +1,80 @@
/*
** Copyright (c) 2001
** Adel I. Mirzazhanov. All rights reserved
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1.Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
** 2.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.
** 3.The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*/
/*
** Header file for bloom filter algorithm implementation
*/
#ifndef APG_BLOOM_H
#define APG_BLOOM_H 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <math.h>
/* Add prototype support. */
#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif
#include "md5/md5.h"
#define FSIZE_BIT(word_count) ((unsigned long int)(4.0/(1.0-pow( 0.9,1.0/((double)word_count)))))
#define FSIZE_BYTE(word_count) ((((unsigned long int)(4.0/(1.0-pow( 0.9,1.0/((double)word_count)))))/8)+1)
#define APGBFHDRSIZE 12
#define TRUE 1
#define FALSE 0
#define MAX_DICT_STRLEN 255
typedef unsigned long int h_val; /* should be 32-bit */
typedef unsigned short int flag;
struct apg_bf_hdr {
char id[8];
unsigned long int fs;
};
extern int insert_word(char *word, FILE *file, h_val filter_size);
extern int check_word(char *word, FILE *file, h_val filter_size);
extern FILE * create_filter(char * f_name, unsigned long int n_words);
extern FILE * open_filter(char * f_name);
extern h_val get_filtersize(FILE *f);
extern h_val count_words(FILE *dict_file);
#endif /* APG_BLOOM_H */

46
doc/APG_TIPS Normal file
View File

@@ -0,0 +1,46 @@
============================================================
= TIPS FOR APG =
============================================================
= This file contains some tips for APG. =
= =
= 1. If You wish to submit a tip please send an email to =
= <a-del@iname.com> and if i find it useful i'll put =
= Your tip in the APG_TIPS file of the next release. =
= I will also put Your tip on the APG website as soon =
= as it posible. =
= 2. If you wish to remove or update Your tip please send =
= en email to <a-del@iname.com>. I will remove/update =
= Your tip in the APG_TIPS file of the next release. =
= I'll remove/update Your tip on the APG website as =
= soon as it posible. =
= =
= Adel I Mirzazhanov =
= a-del@iname.com =
============================================================
######################################################
# 1. Elimination of certain characters from the output
# by Barton Hodges <barton@gcmcomputers.com>
######################################################
I don't like to use "o"'s or "l"'s in my passwords
because they looke like zeros and ones instead of O's
and L's.
I hacked together a little shell script to accomplish
the elimination of certain characters from the output.
----------[cut here]
#!/bin/sh
genpw () {
PW=$(/usr/local/bin/apg -L -m 10 -x 10 -n 1 | egrep -v [owl])
if [ "$PW" != "" ]; then
echo $PW
return 0;
else
return 1;
fi
}
until genpw; do : ; done
----------[cut here]

View File

@@ -2,14 +2,14 @@
.\" Licensed under BSD-like License.
.\" Created by Adel I. Mirzazhanov
.\"
.TH APG 1 "2001 Feb 13" "Automated Password Generator" "User Manual"
.TH APG 1 "2001 Mar 18" "Automated Password Generator" "User Manual"
.SH NAME
apg
\- generates several random passwords
.SH SYNOPSIS
.B apg
[\fB-r\fP \fIdictfile\fP]
[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP]
[\fB-a algorithm\fP] [\fB-C\fP] [\fB-L\fP] [\fB-S\fP] [\fB-N\fP] [\fB-R\fP]
[\fB-M mode\fP] [\fB-m min_pass_len\fP] [\fB-x max_pass_len\fP] [\fB-n num_of_pass\fP]
[\fB-s\fP] [\fB-c cl_seed\fP] [\fB-d\fP] [\fB-y\fP] [\fB-h\fP] [\fB-v\fP]
@@ -95,7 +95,7 @@ generation algorithm is used).
.TP
.B R[r]
the same as \fBS[s]\fP but it does not generate symbols \fB`\fP, \fB'\fP,
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Usefull for password generation in
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Useful for password generation in
a shell script. (For random character password generation algorithm only).
.RE
.RS
@@ -117,7 +117,7 @@ use special symbol set. For random character password generation algorithm only.
.TP
.B -R
the same as \fB-S\fP but it does not generate symbols \fB`\fP, \fB'\fP,
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Usefull for password generation in
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Useful for password generation in
a shell script. For random character password generation algorithm only.
(old style - use \fB-M mode\fP instead).
.TP
@@ -148,7 +148,12 @@ for password generation.
.TP
.B -r \fIdictfile\fP
check generated passwords for their appearance in
.B dictfile
.I dictfile
.TP
.B -b \fIfilter_file\fP
check generated passwords for their appearance in
\fIfilter_file\fP. \fIfilter_file\fP should be created with \fBapgbfm\fP(1)
utility.
.TP
.B -s
ask user for random sequence for password generation
@@ -219,8 +224,7 @@ message about it.
.B None.
If you've found one, please send bug description to the author.
.SH "SEE ALSO"
.B apgd
(8)
\fBapgd\fP(8), \fBapgbfm\fP(1)
.SH "AUTHOR"
Adel I. Mirzazhanov, <a-del@iname.com>
.br

113
doc/man/apgbfm.1 Normal file
View File

@@ -0,0 +1,113 @@
.\" Man page for apgbfm.
.\" Licensed under BSD-like License.
.\" Created by Adel I. Mirzazhanov
.\"
.TH APGBFM 1 "2001 Mar 18" "Automated Password Generator" "User Manual"
.SH NAME
apg
\- APG Bloom filter management program
.SH SYNOPSIS
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-n\fP \fBnumofwords\fP
.br
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-d\fP \fIdictfile\fP
.br
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-a\fP \fBword\fP
.br
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-A\fP \fIdictfile\fP
.br
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-c\fP \fBword\fP
.br
.B apgbfm
\fB-f\fP \fIfilter\fP \fB-C\fP \fIdictfile\fP
.br
.B apgbfm
[\fB-v\fP] [\fB-h\fP]
.PP
.SH DESCRIPTION
.B apgbfm
is used to manage Bloom filter that is used to restrict password generation
in \fBAPG\fP pasword generation software. Usage of the Bloom filter allows to speed
up password check for large dictionaries and has some other benefits.
.PP
The idea to use Bloom filter for that purpose is came from the description of
the \fBOPUS\fP project \fBOPUS: Preventing Weak Password Choices\fP
\fIPurdue Technical Report CSD-TR 92-028\fP writen by \fIEugene H. Spafford\fP.
.PP
You can obtain this article from:
.br
\fIhttp://www.cerias.purdue.edu/homes/spaf/tech-reps/9128.ps\fP
.br
It has very nice description of Bloom filter and it's advantages for password
checking systems.
.PP
In simple words, \fBapgbfm\fP generates \fIn\fP hash values for every word and
sets corresponding bits in filter file to 1. To check the word \fBapgbfm\fP
generates the same hash functions for that word and if all \fIn\fP corresponding
bits in filter file are set to 1 then it suppose that word exists in dicionary.
\fBapgbfm\fP uses \fBmd5\fP as a hash function.
.PP
\fBapgbfm\fP can be used as standalone utility, not only with \fBapg\fP, or
\fBapgd\fP.
.PP
.TP
.B WARNING !!!
This is the first release of \fBapgbfm\fP and filter file format can be changed
in the future. I'll try to make file formats compatible but i can not guaranty this.
.TP
.B WARNING !!!
\fBapgbfm\fP may slow down your computer during filter creation.
.SH "OPTIONS"
.TP
.B -f \fIfilter\fP
use \fIfilter\fP as the name for Bloom filter filename.
.TP
.B -n numofwords
create new empty filter for \fBnumofwords\fP number of words. Useful when you
want to fill filter dynamicaly.
.TP
.B -d \fIdictfile\fP
create new filter from \fIdictfile\fP. It may take a lot of time to
generate filter from a big dictionary. To indicate that program is working
\fBapgbfm\fP prints dot for every 100 words added in dictionary.
.TP
.B -a word
add \fBword\fP to the filter.
.TP
.B -A \fIdictfile\fP
add all words from \fIdictfile\fP to the filter.
.TP
.B -c word
check \fBword\fP for appearance in the filter.
.TP
.B -C \fIdictfile\fP
check every word from \fIdictfile\fP for appearance in the filter.
.TP
.B -v
print version information.
.TP
.B -h
print help information.
.SH "EXIT CODE"
On successful completion of its task,
.B apgbfm
will complete with exit code 0. An exit code of -1 indicates an error
occurred. Textual errors are written to the standard error stream.
.SH "FILES"
.B None.
.SH "BUGS"
.B None.
If you've found one, please send bug description to the author.
.PP
This man page is Alpha too.
.SH "SEE ALSO"
\fBapgd\fP(8), \fBapg\fP(1)
.SH "AUTHOR"
Adel I. Mirzazhanov, <a-del@iname.com>
.br
Project home page: http://www.adel.nursat.kz/apg/

View File

@@ -2,14 +2,14 @@
.\" Licensed under BSD-like License.
.\" Created by Adel I. Mirzazhanov
.\"
.TH APGD 8 "2001 Jan 8" "Automated Password Generator" "User Manual"
.TH APGD 8 "2001 Mar 18" "Automated Password Generator" "User Manual"
.SH NAME
apgd
\- server that generates several random passwords
.SH SYNOPSIS
.B apgd
[\fB-r\fP \fIdictfile\fP]
[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP]
[\fB-a algorithm\fP] [\fB-C\fP] [\fB-L\fP] [\fB-S\fP] [\fB-N\fP]
[\fB-m min_pass_len\fP] [\fB-x max_pass_len\fP] [\fB-n num_of_pass\fP]
.PP
@@ -131,7 +131,7 @@ generation algorithm is used).
.TP
.B R[r]
the same as \fBS[s]\fP but it does not generate symbols \fB`\fP, \fB'\fP,
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Usefull for password generation in
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Useful for password generation in
a shell script. (For random character password generation algorithm only).
.RE
.RS
@@ -153,7 +153,7 @@ use special symbol set. For random character password generation algorithm only.
.TP
.B -R
the same as \fB-S\fP but it does not generate symbols \fB`\fP, \fB'\fP,
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Usefull for password generation in
\fB"\fP, \fB|\fP, \fB$\fP, \fBbackslash\fP, \fB?\fP. Useful for password generation in
a shell script. For random character password generation algorithm only.
(old style - use \fB-M mode\fP instead).
.TP
@@ -186,6 +186,11 @@ for password generation.
check generated passwords for their appearance in
.B dictfile
.TP
.B -b \fIfilter_file\fP
check generated passwords for their appearance in
\fIfilter_file\fP. \fIfilter_file\fP should be created with \fBapgbfm\fP(1)
utility.
.TP
.B -n num_of_pass
generate
.B num_of_pass
@@ -222,7 +227,7 @@ All textual info is written to the
.B None.
If you've found one, please send bug description to the author.
.SH "SEE ALSO"
\fBapg\fP(1)
\fBapg\fP(1), \fBapgbfm\fP(1)
.SH "AUTHOR"
Adel I. Mirzazhanov, <a-del@iname.com>
.br

332
md5/md5.c Normal file
View File

@@ -0,0 +1,332 @@
/*
** 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.
*/
/*
** This code was modified in 1997 by Jim Kingdon of Cyclic Software to
** not require an integer type which is exactly 32 bits. This work
** draws on the changes for the same purpose by Tatu Ylonen
** <ylo@cs.hut.fi> as part of SSH, but since I didn't actually use
** that code, there is no copyright issue. I hereby disclaim
** copyright in any changes I have made; this code remains in the
** public domain.
*/
/*
** Note regarding apg_* namespace: this avoids potential conflicts
** with libraries such as some versions of Kerberos. No particular
** need to worry about whether the system supplies an MD5 library, as
** this file is only about 3k of object code.
*/
#include <string.h> /* for memcpy() and memset() */
/* Add prototype support. */
#ifndef PROTO
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
#define PROTO(ARGS) ARGS
#else
#define PROTO(ARGS) ()
#endif
#endif
#include "md5.h"
/* Little-endian byte-swapping routines. Note that these do not
depend on the size of datatypes such as apg_uint32, nor do they require
us to detect the endianness of the machine we are running on. It
is possible they should be macros for speed, but I would be
surprised if they were a performance bottleneck for MD5. */
static apg_uint32
getu32 (addr)
const unsigned char *addr;
{
return (((((unsigned long)addr[3] << 8) | addr[2]) << 8)
| addr[1]) << 8 | addr[0];
}
static void
putu32 (data, addr)
apg_uint32 data;
unsigned char *addr;
{
addr[0] = (unsigned char)data;
addr[1] = (unsigned char)(data >> 8);
addr[2] = (unsigned char)(data >> 16);
addr[3] = (unsigned char)(data >> 24);
}
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void
apg_MD5Init (ctx)
struct apg_MD5Context *ctx;
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void
apg_MD5Update (ctx, buf, len)
struct apg_MD5Context *ctx;
unsigned char const *buf;
unsigned len;
{
apg_uint32 t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = (t + ((apg_uint32)len << 3)) & 0xffffffff) < t)
ctx->bits[1]++; /* Carry from low to high */
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if ( t ) {
unsigned char *p = ctx->in + t;
t = 64-t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
apg_MD5Transform (ctx->buf, ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
apg_MD5Transform (ctx->buf, ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void
apg_MD5Final (digest, ctx)
unsigned char digest[16];
struct apg_MD5Context *ctx;
{
unsigned count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
apg_MD5Transform (ctx->buf, ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count-8);
}
/* Append length in bits and transform */
putu32(ctx->bits[0], ctx->in + 56);
putu32(ctx->bits[1], ctx->in + 60);
apg_MD5Transform (ctx->buf, ctx->in);
putu32(ctx->buf[0], digest);
putu32(ctx->buf[1], digest + 4);
putu32(ctx->buf[2], digest + 8);
putu32(ctx->buf[3], digest + 12);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
}
#ifndef ASM_MD5
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w &= 0xffffffff, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
void
apg_MD5Transform (buf, inraw)
apg_uint32 buf[4];
const unsigned char inraw[64];
{
register apg_uint32 a, b, c, d;
apg_uint32 in[16];
int i;
for (i = 0; i < 16; ++i)
in[i] = getu32 (inraw + 4 * i);
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
#endif
#ifdef TEST
/* Simple test program. Can use it to manually run the tests from
RFC1321 for example. */
#include <stdio.h>
int
main (int argc, char **argv)
{
struct apg_MD5Context context;
unsigned char checksum[16];
int i;
int j;
if (argc < 2)
{
fprintf (stderr, "usage: %s string-to-hash\n", argv[0]);
exit (1);
}
for (j = 1; j < argc; ++j)
{
printf ("MD5 (\"%s\") = ", argv[j]);
apg_MD5Init (&context);
apg_MD5Update (&context, argv[j], strlen (argv[j]));
apg_MD5Final (checksum, &context);
for (i = 0; i < 16; i++)
{
printf ("%02x", (unsigned int) checksum[i]);
}
printf ("\n");
}
return 0;
}
#endif /* TEST */

41
md5/md5.h Normal file
View File

@@ -0,0 +1,41 @@
/* See md5.c for explanation and copyright information. */
/*
* $FreeBSD: src/contrib/cvs/lib/md5.h,v 1.2 1999/12/11 15:10:02 peter Exp $
*/
#ifndef MD5_H
#define MD5_H
/*
#ifdef __FreeBSD__
#define apg_MD5Context MD5Context
#define apg_MD5Init MD5Init
#define apg_MD5Update MD5Update
#define apg_MD5Final MD5Final
#define apg_MD5Transform MD5Transform
#include <sys/md5.h>
#else
*/
/* Unlike previous versions of this code, uint32 need not be exactly
32 bits, merely 32 bits or more. Choosing a data type which is 32
bits instead of 64 is not important; speed is considerably more
important. ANSI guarantees that "unsigned long" will be big enough,
and always using it seems to have few disadvantages. */
typedef unsigned long apg_uint32;
struct apg_MD5Context {
apg_uint32 buf[4];
apg_uint32 bits[2];
unsigned char in[64];
};
void apg_MD5Init PROTO ((struct apg_MD5Context *context));
void apg_MD5Update PROTO ((struct apg_MD5Context *context,
unsigned char const *buf, unsigned len));
void apg_MD5Final PROTO ((unsigned char digest[16],
struct apg_MD5Context *context));
void apg_MD5Transform PROTO ((apg_uint32 buf[4], const unsigned char in[64]));
/*#endif*/
#endif /* !MD5_H */

View File

@@ -64,3 +64,14 @@ check_pass(char *pass, char *dict)
fclose (dct);
return (0);
}
int
bloom_check_pass (char *word, char *filter)
{
FILE *f_filter;
h_val filter_size = 0L;
if ( (f_filter = open_filter(filter)) == NULL)
return(-1);
filter_size = get_filtersize(f_filter);
return(check_word (word, f_filter, filter_size));
}

View File

@@ -33,9 +33,9 @@
#ifndef RESTRICT_H
#define RESTRICT_H 1
#include "bloom.h"
#define MAX_DICT_STRING_SIZE 255
extern int check_pass(char * pass, char *dict);
extern int make_db_dict(char *dict, char *bddict);
extern int construct_db_name(char *plain_filename, char * dbname);
extern int bloom_check_pass (char *word, char *filter);
#endif /* RESTRICT_H */