diff --git a/CHANGES b/CHANGES index 483b2b2..89776be 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,16 @@ +apg-2.2.0 + Added polish translation for APG PHP frontend. + Added option -p (see apg(1) apgd(8)). + Added option -t (see apg(1) apgd(8)). + Added option -l (see apg(1)). + Changed format of the bloom-filter file. Added + converter utility to convert old format to the + new one (bfconvert). + Added option -i (see apgbfm(1)). + Fixed some bugs. + Some compatibility changes. + Changed default apg options. + apg-2.1.0 Some code cleanup. diff --git a/Makefile b/Makefile index fd5d17f..c8dab03 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,8 @@ FLAGS = -Wall ################################################################## # Libraries # -# You should comment the line below for OpenBSD 2.8 and above +# You should comment the line below ('LIBS= -lcrypt')for QNX RTP +# 6.1.0, OpenBSD 2.8 and above, WIN32 (+MinGW) LIBS = -lcrypt LIBM = -lm # Use lines below for cygwin @@ -24,6 +25,7 @@ LIBM = -lm # DO NOT EDIT THE LINE BELOW !!! CRYPTED_PASS = APG_DONOTUSE_CRYPT # Coment this if you do not want to use crypted passwords output +# or trying to build programm for win32 CRYPTED_PASS = APG_USE_CRYPT ################################################################## @@ -65,6 +67,12 @@ APGD_MAN_DIR = /man/man8 # Uncoment line below for Solaris #CS_LIBS = -lnsl -lsocket +#################################################################### +# QNX RTP 6.1.0 +# +# Uncoment line below for QNX RTP 6.1.0 +#CS_LIBS = -lsocket + # ====== YOU DO NOT NEED TO MODIFY ANYTHING BELOW THIS LINE ====== # Find group ID for user root FIND_GROUP = `grep '^root:' /etc/passwd | awk -F: '{ print $$4 }'` @@ -72,19 +80,19 @@ FIND_GROUP = `grep '^root:' /etc/passwd | awk -F: '{ print $$4 }'` PROGNAME = apg CS_PROGNAME = apgd BFM_PROGNAME = apgbfm -BFM_SOURCES = apgbfm.c bloom.c sha/sha.c errors.c getopt.c +BFM_SOURCES = apgbfm.c bloom.c sha/sha.c errors.c getopt.c convert.c SOURCES = bloom.c ./sha/sha.c ./cast/cast.c rnd.c pronpass.c \ -randpass.c restrict.c errors.c apg.c getopt.c +randpass.c restrict.c errors.c apg.c getopt.c convert.c HEADERS = owntypes.h pronpass.h randpass.h restrict.h errs.h rnd.h \ -./cast/cast.h ./cast/cast_sboxes.h getopt.h +./cast/cast.h ./cast/cast_sboxes.h getopt.h convert.h OBJECTS = rnd.o ./cast/cast.o pronpass.o randpass.o restrict.o apg.o errors.o +standalone: apg apgbfm + all: cliserv standalone cliserv: apgd apgbfm -standalone: apg apgbfm - cygwin: standalone apg: @@ -94,7 +102,7 @@ apgd: ${CC} ${FLAGS} -DCLISERV -D${USE_SHA} -o ${CS_PROGNAME} ${SOURCES} ${CS_LIBS} ${LIBM} apgbfm: - ${CC} ${FLAGS} -o ${BFM_PROGNAME} ${BFM_SOURCES} ${LIBM} + ${CC} ${FLAGS} -DAPGBFM -o ${BFM_PROGNAME} ${BFM_SOURCES} ${LIBM} strip: strip ${PROGNAME} @@ -136,4 +144,4 @@ fi fi clean: - rm -f ${CS_PROGNAME} ${PROGNAME} ${BFM_PROGNAME} ${OBJECTS} core* + rm -f ${CS_PROGNAME} ${PROGNAME} ${BFM_PROGNAME} ${OBJECTS} *core* diff --git a/README b/README index 2564092..5e644c0 100644 --- a/README +++ b/README @@ -1,30 +1,14 @@ -APG v2.1.0 was tested and found working on: +APG v2.2.0 was tested and found working on: - i386 FreeBSD 4.6-RELEASE + i386 FreeBSD 5.0-RELEASE Intel Solaris 8 gcc-2.95.2 - SPARC Solaris 8 gcc-2.95.2 + QNX PRP 6.0 RedHat Linux 7.2 - -APG v1.2.13 was tested and found working on: - - i386 FreeBSD 4.0-RELEASE - NetBSD (reported by Tomasz Luchowski ) - OpenBSD (reported by Rick VanNorman ) - i386 Linux-Mandrake 6.0 - i386 Linux-Redhat 7.0 - i386 Linux-Mandrake 7.2 (reported by Andrew J. Caird ) - Intel Solaris 8 gcc-2.95.2 - SPARC Solaris 8 gcc-2.95.2 - Intel Windows 2000+CYGWIN v1.1.4 - HP-UX 10.20 HP ANSI C Compilier (reported by Alexander J Pierce ) - HP-UX 11.00 HP ANSI C Compilier (reported by Alexander J Pierce ) - HP-UX 11.00 gcc-2.95.2 (reported by Andrew J. Caird ) - IRIX 6.5.8 gcc-2.95.2 (reported by Andrew J. Caird ) - AIX 4.3.3+native cc (reported by Philip Le Riche ) - AIX 4.3.3+gcc (reported by Philip Le Riche ) + Mandrake Linux 9.1 + Win 2000 Pro NOTE: -This release (APG v2.1.0b1) is NOT yet compatible with TkAPG (Tcl/Tk frontend for APG) +This release (APG v2.2.0) is NOT compatible with TkAPG (Tcl/Tk frontend for APG) Any compatibility reports are welcome diff --git a/THANKS b/THANKS index 854eaf8..4d471fa 100644 --- a/THANKS +++ b/THANKS @@ -24,3 +24,7 @@ Joseph P. Crotty Schlies, Peter Eugene Podkopaev Bill Plesko +Bartosz Sobolewski - Worthy +James Mancini +Arno Wilhelm +Michael Matthews diff --git a/apg.c b/apg.c index e911298..1e7ab0d 100644 --- a/apg.c +++ b/apg.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -32,21 +32,30 @@ */ #include #include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include +#endif #include #include #ifndef APG_USE_SHA -# define APG_VERSION "2.1.0 (PRNG: X9.17/CAST)" +#define APG_VERSION "2.2.0 (PRNG: X9.17/CAST)" #else /* APG_USE_SHA */ -# define APG_VERSION "2.1.0 (PRNG: X9.17/SHA-1)" +#define APG_VERSION "2.2.0 (PRNG: X9.17/SHA-1)" #endif /* APG_USE_SHA */ #ifdef __NetBSD__ #include #endif +#if defined(__sun) || defined(sun) || defined(linux) || defined(__linux) || defined(__linux__) +#include +#endif + #define MAX_MODE_LENGTH 4 +#define DEFAULT_MIN_PASS_LEN 8 +#define DEFAULT_MAX_PASS_LEN 10 +#define DEFAULT_NUM_OF_PASS 6 #ifndef _XOPEN_SOURCE #define _XOPEN_SOURCE @@ -61,11 +70,11 @@ #endif /* __CYGWIN__ */ #ifdef CLISERV -# include -# include -# include -# include -# define MAXSOCKADDDR 128 +#include +#include +#include +#include +#define MAXSOCKADDDR 128 #endif /* CLISERV */ #include "owntypes.h" @@ -76,6 +85,7 @@ #include "rnd.h" #include "errs.h" #include "getopt.h" +#include "convert.h" struct pass_m { unsigned int pass; /* password generation mode */ @@ -110,21 +120,29 @@ main (int argc, char *argv[]) int algorithm = 0; /* algorithm for generation */ int restrictions_present = FALSE; /* restrictions flag */ + int plain_restrictions_present = FALSE; /* dictionary restrictions_flag */ int bloom_restrict_present = FALSE; /* bloom filter restrictions flag */ + int paranoid_bloom_restrict_present = FALSE; /* paranoid bloom filter restrictions flag */ int filter_restrict_present = FALSE; /* filter restrictions flag */ int exclude_list_present = FALSE; /* exclude list present */ int quiet_present = FALSE; /* quiet mode flag */ + int hyph_req_present = FALSE; /* Request to print hyphenated password */ char *restrictions_file; /* dictionary file name */ + char *plain_restrictions_file; /* dictionary file name */ struct pass_m mode; unsigned int pass_mode_present = FALSE; /* password generation mode flag */ - USHORT min_pass_length = 6; /* min password length */ - USHORT max_pass_length = 8; /* max password length */ - int number_of_pass = 6; /* number of passwords to generate */ + USHORT min_pass_length = DEFAULT_MIN_PASS_LEN; /* min password length */ + USHORT max_pass_length = DEFAULT_MAX_PASS_LEN; /* max password length */ + USHORT min_substr_len = 0; /* min substring length to check if + ** paranoid check is used */ + int number_of_pass = DEFAULT_NUM_OF_PASS; /* number of passwords to generate */ UINT32 user_defined_seed = 0L; /* user defined random seed */ int user_defined_seed_present = FALSE; /* user defined random seed flag */ char *str_mode; /* string mode pointer */ #ifndef CLISERV char *com_line_seq; + char *spell_pass_string; + int spell_present = FALSE; /* spell password mode flag */ unsigned int delimiter_flag_present = FALSE; #ifdef APG_USE_CRYPT char *crypt_string; @@ -132,7 +150,7 @@ main (int argc, char *argv[]) #endif /* APG_USE_CRYPT */ #endif /* CLISERV */ #ifdef CLISERV -#ifdef sgi /* Thanks to Andrew J. Caird */ +#if defined(sgi) || defined(__APPLE__) || defined(__QNX__) /* Thanks to Andrew J. Caird */ typedef unsigned int socklen_t; #endif socklen_t len; @@ -162,12 +180,12 @@ main (int argc, char *argv[]) */ #ifndef CLISERV #ifdef APG_USE_CRYPT - while ((option = apg_getopt (argc, argv, "M:E:a:r:b:sdc:n:m:x:hvyq")) != -1) + while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:sdc:n:m:x:htvylq")) != -1) #else /* APG_USE_CRYPT */ - while ((option = apg_getopt (argc, argv, "M:E:a:r:b:sdc:n:m:x:hvq")) != -1) + while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:sdc:n:m:x:htvlq")) != -1) #endif /* APG_USE_CRYPT */ #else /* CLISERV */ - while ((option = apg_getopt (argc, argv, "M:E:a:r:b:n:m:x:v")) != -1) + while ((option = apg_getopt (argc, argv, "M:E:a:r:b:p:n:m:x:vt")) != -1) #endif /* CLISERV */ { switch (option) @@ -194,18 +212,29 @@ main (int argc, char *argv[]) break; case 'r': /* restrictions */ restrictions_present = TRUE; - restrictions_file = apg_optarg; + plain_restrictions_present = TRUE; + plain_restrictions_file = apg_optarg; break; case 'b': /* bloom restrictions */ restrictions_present = TRUE; bloom_restrict_present = TRUE; restrictions_file = apg_optarg; break; + case 'p': /* paranoid bloom restrictions */ + checkopt(apg_optarg); + min_substr_len = atoi (apg_optarg); + paranoid_bloom_restrict_present = TRUE; + break; #ifndef CLISERV + case 'l': + spell_present = TRUE; + break; +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) case 's': /* user random seed required */ user_defined_seed = get_user_seq (); user_defined_seed_present = TRUE; break; +#endif /* WIN32 */ case 'c': /* user random seed given in command line */ com_line_seq = apg_optarg; user_defined_seed = com_line_user_seq (com_line_seq); @@ -235,6 +264,9 @@ main (int argc, char *argv[]) checkopt(apg_optarg); max_pass_length = (USHORT) atoi (apg_optarg); break; + case 't': /* request to print hyphenated password */ + hyph_req_present = TRUE; + break; #ifndef CLISERV case 'h': /* print help */ print_help (); @@ -243,7 +275,7 @@ main (int argc, char *argv[]) case 'v': /* print version */ printf ("APG (Automated Password Generator)"); printf ("\nversion %s", APG_VERSION); - printf ("\nCopyright (c) 1999, 2000, 2001, 2002 Adel I. Mirzazhanov\n"); + printf ("\nCopyright (c) 1999, 2000, 2001, 2002, 2003 Adel I. Mirzazhanov\n"); return (0); default: /* print help end exit */ #ifndef CLISERV @@ -302,31 +334,56 @@ main (int argc, char *argv[]) (void *)crypt_passstring (pass_string), 255); #endif /* APG_USE_CRYPT */ #endif /* CLISERV */ + /*************************************** + ** ALGORITHM = 0 RESTRICTIONS = PRESENT + ****************************************/ if (restrictions_present == TRUE) { + /* Filter check */ if (filter_restrict_present == TRUE) - restrict_res = filter_check_pass(pass_string, mode.filter); - else if (bloom_restrict_present == TRUE) - restrict_res = bloom_check_pass(pass_string, restrictions_file); - else - restrict_res = check_pass(pass_string, restrictions_file); + restrict_res = filter_check_pass(pass_string, mode.filter); + /* Bloom-filter check */ + if (restrict_res == 0) + { + if (bloom_restrict_present == TRUE) + { + if(paranoid_bloom_restrict_present != TRUE) + restrict_res = bloom_check_pass(pass_string, restrictions_file); + else + restrict_res = paranoid_bloom_check_pass(pass_string, restrictions_file, min_substr_len); + } + } + /* Dictionary check */ + if (restrict_res == 0) + if (plain_restrictions_present == TRUE) + restrict_res = check_pass(pass_string, plain_restrictions_file); + + switch (restrict_res) { case 0: #ifndef CLISERV + fprintf (stdout, "%s", pass_string); + if (hyph_req_present == TRUE) + fprintf (stdout, " (%s)", hyph_pass_string); #ifdef APG_USE_CRYPT if (show_crypt_text == TRUE) - fprintf (stdout, "%s (%s) %s", pass_string, hyph_pass_string, - crypt_string); - else + fprintf (stdout, " %s", crypt_string); #endif /* APG_USE_CRYPT */ - fprintf (stdout, "%s (%s)", pass_string, hyph_pass_string); + if (spell_present == TRUE) + { + spell_pass_string = spell_word(pass_string, spell_pass_string); + fprintf (stdout, (" %s"), spell_pass_string); + free((void*)spell_pass_string); + } if ( delimiter_flag_present == FALSE ) fprintf (stdout, "\n"); fflush (stdout); #else /* CLISERV */ - snprintf(out_pass, max_pass_length*19 + 4, - "%s (%s)", pass_string, hyph_pass_string); + if (hyph_req_present == TRUE) + snprintf(out_pass, max_pass_length*19 + 4, "%s (%s)", pass_string, hyph_pass_string); + else + snprintf(out_pass, max_pass_length*19 + 4, "%s", pass_string); write (0, (void*) out_pass, strlen(out_pass)); write (0, (void*)&delim[0],2); #endif /* CLISERV */ @@ -340,28 +397,42 @@ main (int argc, char *argv[]) break; } /* switch */ } - else /* if (restrictions_present == 0) */ + /****************************************** + ** ALGORITHM = 0 RESTRICTIONS = NOT_PRESENT + *******************************************/ + else { #ifndef CLISERV + fprintf (stdout, "%s", pass_string); + if (hyph_req_present == TRUE) + fprintf (stdout, " (%s)", hyph_pass_string); #ifdef APG_USE_CRYPT if (show_crypt_text == TRUE) - fprintf (stdout, "%s (%s) %s", pass_string, hyph_pass_string, - crypt_string); - else + fprintf (stdout, " %s", crypt_string); #endif /* APG_USE_CRYPT */ - fprintf (stdout, "%s (%s)", pass_string, hyph_pass_string); + if (spell_present == TRUE) + { + spell_pass_string = spell_word(pass_string, spell_pass_string); + fprintf (stdout, (" %s"), spell_pass_string); + free((void*)spell_pass_string); + } if ( delimiter_flag_present == FALSE ) fprintf (stdout, "\n"); fflush (stdout); #else /* CLISERV */ - snprintf(out_pass, max_pass_length*19 + 4, - "%s (%s)", pass_string, hyph_pass_string); + if (hyph_req_present == TRUE) + snprintf(out_pass, max_pass_length*19 + 4, "%s (%s)", pass_string, hyph_pass_string); + else + snprintf(out_pass, max_pass_length*19 + 4, "%s", pass_string); write (0, (void*) out_pass, strlen(out_pass)); write (0, (void*)&delim[0],2); #endif /* CLISERV */ i++; } - } /* end of if (algorithm == 0) */ + } + /*************************************** + ** ALGORITHM = 1 + ****************************************/ else if (algorithm == 1) { if (gen_rand_pass(pass_string, min_pass_length, @@ -374,14 +445,31 @@ main (int argc, char *argv[]) (void *)crypt_passstring(pass_string), 255); #endif /* APG_USE_CRYPT */ #endif /* CLISERV */ + /*************************************** + ** ALGORITHM = 1 RESTRICTIONS = PRESENT + ****************************************/ if ( (restrictions_present == TRUE)) { + /* Filter check */ if (filter_restrict_present == TRUE) - restrict_res = filter_check_pass(pass_string, mode.filter); - else if (bloom_restrict_present == TRUE) - restrict_res = bloom_check_pass(pass_string, restrictions_file); - else - restrict_res = check_pass(pass_string, restrictions_file); + restrict_res = filter_check_pass(pass_string, mode.filter); + /* Bloom-filter check */ + if (restrict_res == 0) + { + if (bloom_restrict_present == TRUE) + { + if(paranoid_bloom_restrict_present != TRUE) + restrict_res = bloom_check_pass(pass_string, restrictions_file); + else + restrict_res = paranoid_bloom_check_pass(pass_string, restrictions_file, min_substr_len); + } + } + /* Dictionary check */ + if (restrict_res == 0) + if (plain_restrictions_present == TRUE) + restrict_res = check_pass(pass_string, plain_restrictions_file); + + switch (restrict_res) { case 0: @@ -392,6 +480,12 @@ main (int argc, char *argv[]) else #endif /* APG_USE_CRYPT */ fprintf (stdout, "%s", pass_string); + if (spell_present == TRUE) + { + spell_pass_string = spell_word(pass_string, spell_pass_string); + fprintf (stdout, (" %s"), spell_pass_string); + free((void*)spell_pass_string); + } if ( delimiter_flag_present == FALSE ) fprintf (stdout, "\n"); fflush (stdout); @@ -409,7 +503,10 @@ main (int argc, char *argv[]) break; } /* switch */ } - else /* if (restrictions_present == 0) */ + /*************************************** + ** ALGORITHM = 1 RESTRICTIONS = PRESENT + ****************************************/ + else { #ifndef CLISERV #ifdef APG_USE_CRYPT @@ -418,6 +515,12 @@ main (int argc, char *argv[]) else #endif /* APG_USE_CRYPT */ fprintf (stdout, "%s", pass_string); + if (spell_present == TRUE) + { + spell_pass_string = spell_word(pass_string, spell_pass_string); + fprintf (stdout, (" %s"), spell_pass_string); + free((void*)spell_pass_string); + } if ( delimiter_flag_present == FALSE ) fprintf (stdout, "\n"); fflush (stdout); @@ -451,6 +554,7 @@ main (int argc, char *argv[]) } /* end of main */ #ifndef CLISERV +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) /* ** get_user_seq() - Routine that gets user random sequense ** and generates sutable random seed according to it. @@ -476,7 +580,7 @@ get_user_seq (void) sdres = prom[0]^prom[1]; return (sdres); } - +#endif /* WIN32 */ /* ** com_line_user_seq() - Routine that gets user random sequense ** from command line and generates sutable random seed according to it @@ -522,6 +626,7 @@ print_help (void) 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 ("-p substr_len paranoid modifier for bloom filter check\n"); printf ("-a algorithm choose algorithm\n"); printf (" 1 - random password generation according to\n"); printf (" password modes\n"); @@ -529,10 +634,14 @@ print_help (void) printf ("-n num_of_pass generate num_of_pass passwords\n"); printf ("-m min_pass_len minimum password length\n"); printf ("-x max_pass_len maximum password length\n"); +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) printf ("-s ask user for a random seed for password\n"); printf (" generation\n"); +#endif /* WIN32 */ printf ("-c cl_seed use cl_seed as a random seed for password\n"); printf ("-d do NOT use any delimiters between generated passwords\n"); + printf ("-l spell generated password\n"); + printf ("-t print pronunciation for generated pronounceable password\n"); #ifdef APG_USE_CRYPT printf ("-y print crypted passwords\n"); #endif /* APG_USE_CRYPT */ diff --git a/apgbfm.c b/apgbfm.c index 7a25ea2..89b0a62 100644 --- a/apgbfm.c +++ b/apgbfm.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 2001, 2002 +** Copyright (c) 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -35,7 +35,7 @@ #include "getopt.h" -#define VERSION "2.1.0" +#define VERSION "2.2.0" #define FOUND "FOUND" @@ -48,35 +48,38 @@ int main (int argc, char *argv[]); void print_help(void); void checkopt(char *opt); +void print_filter_info(char * filter); int main (int argc, char *argv[]) { int option = 0; - char *dictfile; /* dictionary filename */ - FILE *f_dictfile; /* dictionary file descriptor */ + char *dictfile; /* dictionary filename */ + FILE *f_dictfile; /* dictionary file descriptor */ - char *filter; /* filter file name */ - FILE *f_filter; /* filter file descriptor */ + char *filter; /* filter file name */ + FILE *f_filter; /* filter file descriptor */ - char *word; /* word to add or check */ - char *tmp; /* just tmp char pointer */ - 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 */ + char *word; /* word to add or check */ + char *tmp; /* just tmp char pointer */ + 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; /* counter */ + f_mode flt_mode = 0x00; /* filter mode */ /* 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 */ - flag silent_flag = FALSE; /* -s */ + 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 */ + flag silent_flag = FALSE; /* -q */ + flag case_insensitive_flag = FALSE; /* -q */ /* end of flags section */ /* Analize options */ @@ -86,7 +89,7 @@ main (int argc, char *argv[]) exit(-1); } - while ((option = apg_getopt (argc, argv, "a:A:c:C:n:d:f:hvq")) != -1) + while ((option = apg_getopt (argc, argv, "a:A:c:C:n:d:f:i:hvqs")) != -1) { switch(option) { @@ -132,11 +135,18 @@ main (int argc, char *argv[]) case 'v': printf ("APG Bloom filter management programm"); printf ("\nversion %s", VERSION); - printf ("\nCopyright (c) 2001, 2002 Adel I. Mirzazhanov\n"); + printf ("\nCopyright (c) 2001, 2002, 2003 Adel I. Mirzazhanov\n"); + return (0); + case 'i': + print_filter_info(apg_optarg); return (0); case 'q': silent_flag = TRUE; break; + case 's': + flt_mode = flt_mode | BF_CASE_INSENSITIVE; + case_insensitive_flag = TRUE; + break; default: print_help(); exit(-1); @@ -151,8 +161,9 @@ main (int argc, char *argv[]) if ( (f_filter = open_filter(filter, "r+")) == NULL) err_sys_fatal("open_filter"); filter_size = get_filtersize(f_filter); + flt_mode = get_filtermode(f_filter); if (filter_size == 0) err_sys_fatal("get_filtersize"); - if ( insert_word (word, f_filter, filter_size) == -1) + if ( insert_word (word, f_filter, filter_size, flt_mode) == -1) err_sys_fatal("insert_word"); if (silent_flag != TRUE) printf ("Word %s added\n",word); @@ -166,19 +177,15 @@ main (int argc, char *argv[]) if( (f_filter = open_filter(filter,"r+")) == NULL) err_sys_fatal("open_filter"); filter_size = get_filtersize(f_filter); + flt_mode = get_filtermode(f_filter); if (filter_size == 0) err_sys_fatal("get_filtersize"); while ((fgets(word, MAX_DICT_STRLEN, f_dictfile) != NULL)) { tmp = (char *)strtok (word," \t\n\0"); if( tmp != NULL) - { word = tmp; - } - else - { - continue; - } - if ( insert_word (word, f_filter, filter_size) == -1) + else continue; + if ( insert_word (word, f_filter, filter_size, flt_mode) == -1) err_sys_fatal("insert_word"); i++; if (silent_flag != TRUE) @@ -202,8 +209,10 @@ main (int argc, char *argv[]) if ( (f_filter = open_filter(filter, "r")) == NULL) err_sys_fatal("open_filter"); filter_size = get_filtersize(f_filter); + flt_mode = get_filtermode(f_filter); + if (filter_size == 0) err_sys_fatal("get_filtersize"); - switch(check_word (word, f_filter, filter_size)) + switch(check_word (word, f_filter, filter_size, flt_mode)) { case -1: err_sys_fatal("check_word"); @@ -227,19 +236,16 @@ main (int argc, char *argv[]) if( (f_filter = open_filter(filter, "r")) == NULL) err_sys_fatal("open_filter"); filter_size = get_filtersize(f_filter); + flt_mode = get_filtermode(f_filter); + if (filter_size == 0) err_sys_fatal("get_filtersize"); while ((fgets(word, MAX_DICT_STRLEN, f_dictfile) != NULL)) { tmp = (char *)strtok (word," \t\n\0"); if( tmp != NULL) - { word = tmp; - } - else - { - continue; - } - switch(check_word (word, f_filter, filter_size)) + else continue; + switch(check_word (word, f_filter, filter_size, flt_mode)) { case -1: err_sys_fatal("check_word"); @@ -260,8 +266,8 @@ main (int argc, char *argv[]) } if (new_flag == TRUE) /* -n nwords */ { - if ((f_filter = create_filter(filter, wc)) == NULL) - err_sys_fatal("create_filter"); + if ((f_filter = create_filter(filter, wc, flt_mode)) == NULL) + err_sys_fatal("create_filter"); close_filter(f_filter); return (0); } @@ -277,7 +283,7 @@ main (int argc, char *argv[]) } wc = count_words (f_dictfile); if (wc == 0) err_sys_fatal("count_words"); - if( (f_filter = create_filter(filter, wc)) == NULL) + if( (f_filter = create_filter(filter, wc, flt_mode)) == NULL) err_sys_fatal("create_filter"); filter_size = get_filtersize(f_filter); if (filter_size == 0) err_sys_fatal("get_filtersize"); @@ -292,7 +298,7 @@ main (int argc, char *argv[]) { continue; } - if ( insert_word (word, f_filter, filter_size) == -1) + if ( insert_word (word, f_filter, filter_size, flt_mode) == -1) err_sys_fatal("insert_word"); i++; if (silent_flag != TRUE) @@ -329,6 +335,7 @@ print_help(void) 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] > [-s]\n"); + printf ("apgbfm -i filter\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"); @@ -338,6 +345,8 @@ print_help(void) 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 ("-q quiet mode (do not print dots for -A and -d)\n"); + printf ("-s create case insentive filter\n"); + printf ("-i filter print filter information\n"); printf ("-v print version information\n"); printf ("-h print help (this screen)\n"); } @@ -362,3 +371,24 @@ checkopt(char *opt) opt[i] != '8' && opt[i] != '9') err_app_fatal ("checkopt", "wrong option format"); } + +/* +** print_filter_info(char * filter) - print filter information +** INPUT: +** char * - filter file name. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +print_filter_info(char * filter) +{ +FILE * f_filter; + +if ( (f_filter = open_filter(filter, "r")) == NULL) + err_sys_fatal("open_filter"); +if (( print_flt_info(f_filter)) == -1) + err_sys_fatal("print_flt_info"); +close_filter(f_filter); +} diff --git a/bfconvert/Makefile b/bfconvert/Makefile new file mode 100644 index 0000000..63e8343 --- /dev/null +++ b/bfconvert/Makefile @@ -0,0 +1,29 @@ +################################################################## +# You can modify CC variable if you have compiler other than GCC +# But the code was designed and tested with GCC +CC = gcc + +################################################################## +# Compilation flags +# You should comment the line below for AIX+native cc +FLAGS = -Wall + +ECHO = echo +PROGNAME = bfconvert +SOURCES = bfconvert.c + +all: + ${CC} ${FLAGS} -o ${PROGNAME} ${SOURCES} + +strip: + strip ${PROGNAME} + +install: + @${ECHO} "**********************************************" + @${ECHO} "* This program shold be used to convert your *" + @${ECHO} "* filters once. So if you want to install *" + @${ECHO} "* this program you have to do it manualy :-) *" + @${ECHO} "**********************************************" + +clean: + rm -f ${PROGNAME} *.o *core diff --git a/bfconvert/README b/bfconvert/README new file mode 100644 index 0000000..fe951ae --- /dev/null +++ b/bfconvert/README @@ -0,0 +1,24 @@ +NAME + bfconvert + +DESCRIPTION + Convert APG Bloom-filter version 1.0.1 to + version 1.1.0 + +BUILD + Just type `make' and hit [Enter] at the + command prompt. + +USAGE + bfconvert old_bf_file_name new_bf_file_name + +RETURN + 0 - success + -1 - something wrong + +NOTE + Converted filter will be case sensitive. + + Conversion to the case insensitive filter + is impossible because of the bloom-filter + nature. diff --git a/bfconvert/bfconvert.c b/bfconvert/bfconvert.c new file mode 100644 index 0000000..0b34250 --- /dev/null +++ b/bfconvert/bfconvert.c @@ -0,0 +1,168 @@ +/* +** Copyright (c) 2003 +** 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. +*/ + +/* +*************************************************************** +** NAME : BFCONVERT ** +** DESCRIPTION : convert APG Bloom-filter version 1.0.1 to ** +** version 1.1.0 ** +** USAGE : bfconvert old_bf_file_name new_bf_file_name ** +** RETURN : 0 - success ** +** -1 - something wrong ** +*************************************************************** +*/ + +#include + +#define OLD_APGBF_HEADER_LEN 12 +#define OLD_APGBF_HEADER_ID "APGBF101" + +#define NEW_APGBF_HEADER_LEN 13 +#define NEW_APGBF_HEADER_ID "APGBF" +#define NEW_APGBF_HEADER_VER "110" +#define NEW_APGBF_HEADER_MODE 0x00 + + +int main (int argc, char *argv[]); + +int +main(int argc, char *argv[]) +{ + typedef unsigned char f_mode; + + struct new_apg_bf_hdr { + char id[5]; /* filter ID */ + char version[3]; /* filter version */ + unsigned long int fs; /* filter size */ + f_mode mode; /* filter flags */ + }; + + struct old_apg_bf_hdr { + char id[8]; /* ID */ + unsigned long int fs; /* filter size */ + }; + struct new_apg_bf_hdr new_bf_hdr; + struct old_apg_bf_hdr old_bf_hdr; + + char old_etalon_bf_id[] = OLD_APGBF_HEADER_ID; + + char new_etalon_bf_id[] = NEW_APGBF_HEADER_ID; + char new_etalon_bf_ver[] = NEW_APGBF_HEADER_VER; + + FILE *old_f; /* old filter file descriptor */ + FILE *new_f; /* new filter file descriptor */ + + unsigned char tmp_buf; /* Temporary buffer */ + + /* Checking arguments */ + if (argc != 3) + { + printf ("Usage: bfconvert old_bf_file_name new_bf_file_name\n"); + return(-1); + } + + /* Opening input and output files */ + if ((old_f = fopen (argv[1], "r")) == NULL) + { + perror("open the old bloom-filter file"); + return(-1); + } + if ((new_f = fopen (argv[2], "w")) == NULL) + { + perror("open the new bloom-filter file"); + return(-1); + } + if (fread ( (void *)&old_bf_hdr, OLD_APGBF_HEADER_LEN, 1, old_f) != 1) + if (ferror (old_f) != 0) + { + perror("read from the old bloom-filter file"); + return(-1); + } + + /* Checking input file */ + if ((old_bf_hdr.id[0] != old_etalon_bf_id[0]) || (old_bf_hdr.id[1] != old_etalon_bf_id[1]) || + (old_bf_hdr.id[2] != old_etalon_bf_id[2]) || (old_bf_hdr.id[3] != old_etalon_bf_id[3]) || + (old_bf_hdr.id[4] != old_etalon_bf_id[4]) || (old_bf_hdr.id[5] != old_etalon_bf_id[5]) || + (old_bf_hdr.id[6] != old_etalon_bf_id[6]) || (old_bf_hdr.id[7] != old_etalon_bf_id[7]) ) + { + fprintf(stderr,"Input file is not APG bloom filter file v1.0.1\n"); + fflush (stderr); + return (-1); + } + + /* Constructing output BF file header */ + new_bf_hdr.id[0] = new_etalon_bf_id[0]; + new_bf_hdr.id[1] = new_etalon_bf_id[1]; + new_bf_hdr.id[2] = new_etalon_bf_id[2]; + new_bf_hdr.id[3] = new_etalon_bf_id[3]; + new_bf_hdr.id[4] = new_etalon_bf_id[4]; + new_bf_hdr.version[0] = new_etalon_bf_ver[0]; + new_bf_hdr.version[1] = new_etalon_bf_ver[1]; + new_bf_hdr.version[2] = new_etalon_bf_ver[2]; + new_bf_hdr.fs = old_bf_hdr.fs; + new_bf_hdr.mode = NEW_APGBF_HEADER_MODE; + + /* Writing new filter header to output file */ + if (fwrite ( (void *)&new_bf_hdr, NEW_APGBF_HEADER_LEN, 1, new_f) != 1) + { + perror("write to the new bloom-filter file"); + return(-1); + } + /* Reading filter content from the old BF file and writing it to the new BF file */ + while (fread ( (void *)&tmp_buf, 1, 1, old_f) == 1) + { + if(fwrite( (void *)&tmp_buf, 1, 1, new_f) != 1) + { + perror("write to the new bloom-filter file"); + return(-1); + } + } + if (ferror (old_f) != 0) + { + perror("read from the old bloom-filter file"); + return(-1); + } + /* Close input and output files */ + if (fclose(old_f) == EOF) + { + perror("close old bloom-filter file"); + return(-1); + } + if (fclose(new_f) == EOF) + { + perror("close new bloom-filter file"); + return(-1); + } + + printf("\nInput file has been successfuly converted\n"); + return(0); +} diff --git a/bloom.c b/bloom.c index 6d7e572..639339b 100644 --- a/bloom.c +++ b/bloom.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 2001, 2002 +** Copyright (c) 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -37,7 +37,9 @@ ** create_filter - create initial(empty) filter file ** open_filter - open APG Bloom filter file ** get_filtersize - get APG Bloom filter size +** get_filtermode - get APG Bloom filter mode ** count_words - count words in plain dictionary file +** print_flt_info - print filter info **============================================================= ** hash2bit - generates 5 values (should be 5 values of independent ** hash functions) from input string. @@ -46,28 +48,91 @@ */ #include "bloom.h" +#include "convert.h" + +#define FSIZE_BIT(word_count) ((unsigned long int)(5.0/(1.0-pow( 0.84151068, 1.0/((double)word_count))))) +#define FSIZE_BYTE(word_count) ((((unsigned long int)(5.0/(1.0-pow( 0.84151068, 1.0/((double)word_count)))))/8)+1) h_val * hash2bit(char * word, h_val *b); int getbit(FILE * f, h_val bitnum); int putbit(FILE * f, h_val bitnum); +#ifdef APGBFM +/* +** print_flt_info - print filter information +** INPUT: +** FILE * filter - filter file descriptor +** OUTPUT: +** int +** 0 - everything OK +** -1 - something wrong +*/ +int +print_flt_info(FILE * filter) +{ + struct apg_bf_hdr bf_hdr; + int i = 0; + + if (fseek (filter, 0, SEEK_SET) == -1) + return(-1); + if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, filter) != 1) + if (ferror (filter) != 0) + return(-1); + printf ("**************************************\n"); + printf ("** APGBFM: Bloom-filter information **\n"); + printf ("**************************************\n"); + printf ("Filter ID : "); + for (i=0; i < sizeof(bf_hdr.id); i++) + printf ("%c", bf_hdr.id[i]); + printf ("\n"); + printf ("Filter Version: "); + printf ("%c.", bf_hdr.version[0]); + printf ("%c.", bf_hdr.version[1]); + printf ("%c", bf_hdr.version[2]); + printf ("\n"); + printf ("Filter size : %lu bits\n", (unsigned long int)bf_hdr.fs); + printf ("Filter mode : "); + if (bf_hdr.mode == 0x00) printf ("PLAIN\n"); + if (bf_hdr.mode == 0x01) printf ("CASE_INSENSITIVE\n"); + printf ("**************************************\n"); + if (fseek (filter, 0, SEEK_SET) == -1) + return(-1); + return(0); +} +#endif /* APGBFM */ + /* ** 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 +** f_mode mode - filter mode ** OUTPUT: ** int ** 0 - everything OK ** -1 - something wrong */ int -insert_word(char *word, FILE *file, h_val filter_size) +insert_word(char *word, FILE *file, h_val filter_size, f_mode mode) { h_val h[H_NUM]; int i = 0; +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> insert_word: word to insert: %s\n", word); + fflush (stdout); +#endif /* APG_DEBUG */ + + if ((mode & BF_CASE_INSENSITIVE) > 0) + { + decapitalize(word); +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> insert_word: decapitalized word: %s\n", word); + fflush (stdout); +#endif /* APG_DEBUG */ + } + hash2bit (word, &h[0]); for(i = 0; i < H_NUM; i++) if (putbit (file, h[i] % filter_size)== -1) @@ -81,6 +146,7 @@ insert_word(char *word, FILE *file, h_val filter_size) ** char *word - word to check ** FILE *file - filter file descriptor ** h_val filter_size - filter size in bits +** f_mode - filter mode ** OUTPUT: ** int ** 0 - word is not in dictionary @@ -88,12 +154,33 @@ insert_word(char *word, FILE *file, h_val filter_size) ** -1 - something wrong */ int -check_word(char *word, FILE *file, h_val filter_size) +check_word(char *word, FILE *file, h_val filter_size, f_mode mode) { h_val h[H_NUM]; int i = 0; + char * tmp_word; + + if ((tmp_word = (char *) calloc(1,MAX_DICT_STRLEN)) == NULL) + return(-1); + (void)memcpy ((void *) tmp_word, (void *) word, strlen(word)); + +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> check_word: word to check: %s\n", word); + fflush (stdout); +#endif /* APG_DEBUG */ + if ((mode & BF_CASE_INSENSITIVE) > 0) + { + decapitalize(tmp_word); +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> check_word: decapitalized word: %s\n", tmp_word); + fflush (stdout); +#endif /* APG_DEBUG */ + } + + hash2bit (tmp_word, &h[0]); + + free ((void *)tmp_word); - hash2bit (word, &h[0]); for(i = 0; i < H_NUM; i++) { switch(getbit(file, h[i] % filter_size)) @@ -125,16 +212,23 @@ FILE * open_filter(char * f_name, const char *mode) { FILE *f; + char etalon_bf_id[] = APGBF_ID; + char etalon_bf_ver[] = APGBF_VERSION; struct apg_bf_hdr bf_hdr; + if ((f = fopen (f_name, mode)) == NULL) return(NULL); - if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) < APGBFHDRSIZE) + if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) != 1) 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] != '1') ) return (NULL); + if ((bf_hdr.id[0] != etalon_bf_id[0]) || (bf_hdr.id[1] != etalon_bf_id[1]) || + (bf_hdr.id[2] != etalon_bf_id[2]) || (bf_hdr.id[3] != etalon_bf_id[3]) || + (bf_hdr.id[4] != etalon_bf_id[4]) ) + return (NULL); + if ((bf_hdr.version[0] != etalon_bf_ver[0]) || + (bf_hdr.version[1] != etalon_bf_ver[1]) || + (bf_hdr.version[2] != etalon_bf_ver[2]) ) + return (NULL); else { if (fseek (f, 0, SEEK_SET) == -1) @@ -169,7 +263,9 @@ h_val get_filtersize(FILE * f) { struct apg_bf_hdr bf_hdr; - if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) < APGBFHDRSIZE) + if (fseek (f, 0, SEEK_SET) == -1) + return(0); + if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) != 1) if (ferror (f) != 0) return(0); if (fseek (f, 0, SEEK_SET) == -1) @@ -177,6 +273,28 @@ get_filtersize(FILE * f) return( (h_val)bf_hdr.fs); } +/* +** get_filtermode - get APG Bloom filter mode +** INPUT: +** FILE *f - filter file descriptor +** OUTPUT: +** f_mode - APG Bloom filter mode. +** 0 - something wrong +*/ +f_mode +get_filtermode(FILE *f) +{ + struct apg_bf_hdr bf_hdr; + if (fseek (f, 0, SEEK_SET) == -1) + return(0); + if (fread ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) != 1) + if (ferror (f) != 0) + return(0); + if (fseek (f, 0, SEEK_SET) == -1) + return(0); + return( (f_mode)bf_hdr.mode); +} + /* ** create_filter - create initial(empty) filter file ** 5 - number of hash functions @@ -203,27 +321,33 @@ get_filtersize(FILE * f) ** 1 - 0.84151068 */ FILE * -create_filter(char * f_name, unsigned long int n_words) +create_filter(char * f_name, unsigned long int n_words, f_mode mode) { FILE *f; char zero = 0x00; long int i = 0L; + char etalon_bf_id[] = APGBF_ID; + char etalon_bf_ver[] = APGBF_VERSION; 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] = '1'; + bf_hdr.id[0] = etalon_bf_id[0]; + bf_hdr.id[1] = etalon_bf_id[1]; + bf_hdr.id[2] = etalon_bf_id[2]; + bf_hdr.id[3] = etalon_bf_id[3]; + bf_hdr.id[4] = etalon_bf_id[4]; + + bf_hdr.version[0] = etalon_bf_ver[0]; + bf_hdr.version[1] = etalon_bf_ver[1]; + bf_hdr.version[2] = etalon_bf_ver[2]; + bf_hdr.fs = FSIZE_BIT(n_words); + + bf_hdr.mode = mode; if ((f = fopen (f_name, "w+")) == NULL) return(NULL); - if (fwrite ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) < APGBFHDRSIZE) + if (fwrite ( (void *)&bf_hdr, APGBFHDRSIZE, 1, f) != 1) if (ferror (f) != 0) return(NULL); diff --git a/bloom.h b/bloom.h index 0271060..1480645 100644 --- a/bloom.h +++ b/bloom.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2001, 2002 +** Copyright (c) 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -38,15 +38,27 @@ #include #include #include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include +#endif #include #include "sha/sha.h" -#define FSIZE_BIT(word_count) ((unsigned long int)(5.0/(1.0-pow( 0.84151068, 1.0/((double)word_count))))) -#define FSIZE_BYTE(word_count) ((((unsigned long int)(5.0/(1.0-pow( 0.84151068, 1.0/((double)word_count)))))/8)+1) +#define APGBF_ID "APGBF" +#define APGBF_VERSION "110" /* Version 1.1.0 */ -#define APGBFHDRSIZE 12 +/* Bloom filter modes flags */ +#define BF_CASE_INSENSITIVE 0x01 +#define BF_RESERVED1 0x02 +#define BF_RESERVED2 0x04 +#define BF_RESERVED3 0x08 +#define BF_RESERVED4 0x10 +#define BF_RESERVED5 0x20 +#define BF_RESERVED6 0x40 +#define BF_RESERVED7 0x80 + +#define APGBFHDRSIZE 13 #define TRUE 1 #define FALSE 0 @@ -56,18 +68,24 @@ typedef unsigned long int h_val; /* should be 32-bit */ typedef unsigned short int flag; +typedef unsigned char f_mode; struct apg_bf_hdr { - char id[8]; /* ID */ - unsigned long int fs; /* filter size */ + char id[5]; /* filter ID */ + char version[3]; /* filter version */ + unsigned long int fs; /* filter size */ + f_mode mode; /* filter flags */ }; -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 int insert_word(char *word, FILE *file, h_val filter_size, f_mode mode); +extern int check_word(char *word, FILE *file, h_val filter_size, f_mode mode); +extern FILE * create_filter(char * f_name, unsigned long int n_words, f_mode mode); extern FILE * open_filter(char * f_name, const char *mode); extern int close_filter(FILE *f_dsk); extern h_val get_filtersize(FILE *f); +extern f_mode get_filtermode(FILE *f); extern h_val count_words(FILE *dict_file); - +#ifdef APGBFM +extern int print_flt_info(FILE * filter); +#endif /* APGBFM */ #endif /* APG_BLOOM_H */ diff --git a/convert.c b/convert.c new file mode 100644 index 0000000..9b4ef85 --- /dev/null +++ b/convert.c @@ -0,0 +1,407 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** 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 +#include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) +#include +#endif +#ifndef APGBFM +# include "errs.h" +# include "randpass.h" +#endif + +#include "convert.h" + +/* +** GLOBALS +*/ + +/* small letters */ +char let[26] = + { + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', + 'u', 'v', 'w', 'x', 'w', 'z' + }; +/* capital letters */ +char clet[26] = + { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'W', 'Z' + }; + +/* +** FUNCTIONS +*/ + +/* +** decapitalize() - This routine replaces all capital letters +** to small letters in the word: +** INPUT: +** char * - word. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +decapitalize (char *word) +{ + int i = 0; /* counter */ + int j = 0; /* counter */ + int str_len = strlen(word); + for(j = 0; j < str_len; j++) + for(i=0; i < 26; i++) + if(word[j] == clet[i]) + word[j] = let[i]; +} + +#ifndef APGBFM +/* +** capitalize() - This routine designed to modify sullable like this: +** adel ----> Adel +** dot ----> Dot +** etc. +** INPUT: +** char * - syllable. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +capitalize (char *syllable) +{ + char tmp = 0x00; + int i = 0; + if ( randint(2) == TRUE) + { + (void)memcpy((void *)&tmp, (void *)syllable, sizeof(tmp)); + for(i=0; i < 26; i++) + if ( let[i] == tmp ) + if (is_restricted_symbol(clet[i]) != TRUE) + (void)memcpy ((void *)syllable, (void *)&clet[i], 1); + } +} + +/* +** numerize() - This routine designed to modify single-letter +** syllable like this: +** a ----> 1 or 2 or 3 etc. +** u ----> 1 or 2 or 3 etc. +** etc. +** INPUT: +** char * - single-letter syllable +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +numerize (char *syllable) +{ + char *tmp; + if ( (tmp = (char *)calloc(1, 4)) == NULL) + err_sys_fatal("calloc"); + if ( strlen (syllable) == 1 ) + { + (void) gen_rand_symbol(tmp, S_NB); + (void)memcpy ((void *)syllable, (void *)tmp, 1); + } + free ((void *)tmp); +} +/* +** specialize() - This routine designed to modify single-letter syllable +** like this: +** a ----> # or $ or % etc. +** u ----> # or $ or % etc. +** etc. +** INPUT: +** char * - single-letter syllable. +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +specialize (char *syllable) +{ + char *tmp; + if ( (tmp = (char *)calloc(1, 4)) == NULL) + err_sys_fatal("calloc"); + if ( strlen (syllable) == 1 ) + { + (void) gen_rand_symbol(tmp, S_SS); + (void)memcpy ((void *)syllable, (void *)tmp, 1); + } + free ((void *)tmp); +} + +/* +** symb2name - convert symbol to it's name +** INPUT: +** char * - one symbol syllable +** OUTPUT: +** none. +** NOTES: +** none. +*/ +void +symb2name(char * syllable, char * h_syllable) +{ + struct ssymb_names + { + char symbol; + char *name; + }; + static struct ssymb_names ssn[42] = + { + {'1',"ONE"}, + {'2',"TWO"}, + {'3',"THREE"}, + {'4',"FOUR"}, + {'5',"FIVE"}, + {'6',"SIX"}, + {'7',"SEVEN"}, + {'8',"EIGHT"}, + {'9',"NINE"}, + {'0',"ZERO"}, + {33, "EXCLAMATION_POINT"}, + {34, "QUOTATION_MARK"}, + {35, "CROSSHATCH"}, + {36, "DOLLAR_SIGN"}, + {37, "PERCENT_SIGN"}, + {38, "AMPERSAND"}, + {39, "APOSTROPHE"}, + {40, "LEFT_PARENTHESIS"}, + {41, "RIGHT_PARENTHESIS"}, + {42, "ASTERISK"}, + {43, "PLUS_SIGN"}, + {44, "COMMA"}, + {45, "HYPHEN"}, + {46, "PERIOD"}, + {47, "SLASH"}, + {58, "COLON"}, + {59, "SEMICOLON"}, + {60, "LESS_THAN"}, + {61, "EQUAL_SIGN"}, + {62, "GREATER_THAN"}, + {63, "QUESTION_MARK"}, + {64, "AT_SIGN"}, + {91, "LEFT_BRACKET"}, + {92, "BACKSLASH"}, + {93, "RIGHT_BRACKET"}, + {94, "CIRCUMFLEX"}, + {95, "UNDERSCORE"}, + {96, "GRAVE"}, + {123, "LEFT_BRACE"}, + {124, "VERTICAL_BAR"}, + {125, "RIGHT_BRACE"}, + {126, "TILDE"} + }; + int i = 0; + int flag = FALSE; + + if (strlen(syllable) == 1) + { + for (i = 0; i < 42; i++) + { + if(*syllable == ssn[i].symbol) + { + (void)memcpy((void*)h_syllable, (void*)ssn[i].name, strlen(ssn[i].name)); + flag = TRUE; + } + } + if (flag != TRUE) + (void)memcpy((void*)h_syllable, (void*)syllable, strlen(syllable)); + } +} + +/* +** spell_word - spell the word +** INPUT: +** char * - pointer to the word +** char * - pointer to the spelled word +** OUTPUT: +** char * - pointer to the spelled word +** NULL - something is wrong +** NOTES: +** You should free() memory pointed by spelled_word after each use of spell_word +*/ +char * +spell_word(char * word, char * spelled_word) +{ + struct char_spell + { + char symbol; + char *name; + }; + static struct char_spell cs[94] = + { + {'1',"ONE" }, + {'2',"TWO" }, + {'3',"THREE" }, + {'4',"FOUR" }, + {'5',"FIVE" }, + {'6',"SIX" }, + {'7',"SEVEN" }, + {'8',"EIGHT" }, + {'9',"NINE" }, + {'0',"ZERO" }, + {'A', "Alfa" }, + {'B', "Bravo" }, + {'C', "Charlie" }, + {'D', "Delta" }, + {'E', "Echo" }, + {'F', "Foxtrot" }, + {'G', "Golf" }, + {'H', "Hotel" }, + {'I', "India" }, + {'J', "Juliett" }, + {'K', "Kilo" }, + {'L', "Lima" }, + {'M', "Mike" }, + {'N', "November" }, + {'O', "Oscar" }, + {'P', "Papa" }, + {'Q', "Quebec" }, + {'R', "Romeo" }, + {'S', "Sierra" }, + {'T', "Tango" }, + {'U', "Uniform" }, + {'V', "Victor" }, + {'W', "Whiskey" }, + {'X', "X_ray" }, + {'Y', "Yankee" }, + {'Z', "Zulu" }, + {'a', "alfa" }, + {'b', "bravo" }, + {'c', "charlie" }, + {'d', "delta" }, + {'e', "echo" }, + {'f', "foxtrot" }, + {'g', "golf" }, + {'h', "hotel" }, + {'i', "india" }, + {'j', "juliett" }, + {'k', "kilo" }, + {'l', "lima" }, + {'m', "mike" }, + {'n', "november" }, + {'o', "oscar" }, + {'p', "papa" }, + {'q', "quebec" }, + {'r', "romeo" }, + {'s', "sierra" }, + {'t', "tango" }, + {'u', "uniform" }, + {'v', "victor" }, + {'w', "whiskey" }, + {'x', "x_ray" }, + {'y', "yankee" }, + {'z', "zulu" }, + {33, "EXCLAMATION_POINT"}, + {34, "QUOTATION_MARK" }, + {35, "CROSSHATCH" }, + {36, "DOLLAR_SIGN" }, + {37, "PERCENT_SIGN" }, + {38, "AMPERSAND" }, + {39, "APOSTROPHE" }, + {40, "LEFT_PARENTHESIS" }, + {41, "RIGHT_PARENTHESIS"}, + {42, "ASTERISK" }, + {43, "PLUS_SIGN" }, + {44, "COMMA" }, + {45, "HYPHEN" }, + {46, "PERIOD" }, + {47, "SLASH" }, + {58, "COLON" }, + {59, "SEMICOLON" }, + {60, "LESS_THAN" }, + {61, "EQUAL_SIGN" }, + {62, "GREATER_THAN" }, + {63, "QUESTION_MARK" }, + {64, "AT_SIGN" }, + {91, "LEFT_BRACKET" }, + {92, "BACKSLASH" }, + {93, "RIGHT_BRACKET" }, + {94, "CIRCUMFLEX" }, + {95, "UNDERSCORE" }, + {96, "GRAVE" }, + {123, "LEFT_BRACE" }, + {124, "VERTICAL_BAR" }, + {125, "RIGHT_BRACE" }, + {126, "TILDE" } + }; + int s_length = 0; + int i = 0; + int j = 0; + int word_len = strlen(word); + char * tmp_ptr; + char hyphen = '-'; + char zero = 0x00; + + /* Count the length of the spelled word */ + for (i=0; i <= word_len; i++) + for (j=0; j < 94; j++) + if (word[i] == cs[j].symbol) + { + s_length = s_length + strlen(cs[j].name) + 1; + continue; + } + + /* Allocate memory for spelled word */ + if ( (spelled_word = (char *)calloc(1, (size_t)s_length)) == NULL) + return(NULL); + + /* Construct spelled word */ + tmp_ptr = spelled_word; + + for (i=0; i < word_len; i++) + for (j=0; j < 94; j++) + if (word[i] == cs[j].symbol) + { + (void) memcpy((void *)tmp_ptr, (void *)cs[j].name, strlen(cs[j].name)); + tmp_ptr = tmp_ptr + strlen(cs[j].name); + /* Place the hyphen after each symbol */ + (void) memcpy((void *)(tmp_ptr), (void *)&hyphen, 1); + tmp_ptr = tmp_ptr + 1; + continue; + } + + /* Remove hyphen at the end of the word */ + tmp_ptr = tmp_ptr - 1; + (void) memcpy((void *)(tmp_ptr), (void *)&zero, 1); + + return (spelled_word); +} + +#endif /* APGBFM */ diff --git a/convert.h b/convert.h new file mode 100644 index 0000000..08f0bf0 --- /dev/null +++ b/convert.h @@ -0,0 +1,43 @@ +/* +** Copyright (c) 1999, 2000, 2001, 2002, 2003 +** 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. +*/ + +#ifndef APG_CONVERT_H +#define APG_CONVERT_H 1 + +void decapitalize (char *word); + +#ifndef APGBFM +void capitalize (char *syllable); +void numerize (char *syllable); +void specialize (char *syllable); +void symb2name(char * syllable, char * h_syllable); +char* spell_word(char * word, char * spelled_word); +#endif /* APGBFM */ + +#endif /* APG_CONVERT_H */ diff --git a/doc/man/apg.1 b/doc/man/apg.1 index ebdaeac..55a8470 100644 --- a/doc/man/apg.1 +++ b/doc/man/apg.1 @@ -2,7 +2,7 @@ .\" Licensed under BSD-like License. .\" Created by Adel I. Mirzazhanov .\" -.TH APG 1 "2002 Jun 11" "Automated Password Generator" "User Manual" +.TH APG 1 "2003 Jun 19" "Automated Password Generator" "User Manual" .SH NAME apg \- generates several random passwords @@ -11,8 +11,8 @@ apg .B apg [\fB-a algorithm\fP] [\fB-M mode\fP] [\fB-E char_string\fP] [\fB-n num_of_pass\fP] [\fB-m min_pass_len\fP] [\fB-x max_pass_len\fP] -[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP] -[\fB-s\fP] [\fB-c cl_seed\fP] [\fB-d\fP] [\fB-y\fP] [\fB-q\fP] [\fB-h\fP] [\fB-v\fP] +[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP] [\fB-p min_substr_len\fP] +[\fB-s\fP] [\fB-c cl_seed\fP] [\fB-d\fP] [\fB-y\fP] [\fB-l\fP] [\fB-t\fP] [\fB-q\fP] [\fB-h\fP] [\fB-v\fP] .PP .SH DESCRIPTION .B apg @@ -128,9 +128,6 @@ Usage of L, M, N, C will slow down password generation process. .B Examples: .br \fB-M sncl\fP or \fB-M SNCL\fP or \fB-M Cn\fP -.PP -\fB-M mode\fP is the new style password generation mode definition. Old style -options(-C, -N, -S, -L, -R) are not supported any more. .RE .TP .B -a algorithm @@ -184,6 +181,14 @@ check generated passwords for their appearance in \fIfilter_file\fP. \fIfilter_file\fP should be created with \fBapgbfm\fP(1) utility. .TP +.B -p min_substr_len +this option tells \fBapg\fP(1) to check every substring of the generated +password for appearance in \fIfilter_file\fP. If any of such substrings would +be found in the \fIfilter_file\fP then generated password would be rejected +and apg(1) will generate another one. +\fBmin_substr_len\fP specifies minimum substring length to check. +This option is active only if \fB-b\fP option is defined. +.TP .B -s ask user for random sequence for password generation .TP @@ -206,13 +211,13 @@ number of passwords. Default is 6. generate password with minimum length .B min_pass_len. If \fBmin_pass_len > max_pass_len\fP then \fBmax_pass_len = min_pass_len\fP. -Default minimum password length is 6. +Default minimum password length is 8. .TP .B -x max_pass_len generate password with maximum length .B max_pass_len. If \fBmin_pass_len > max_pass_len\fP then \fBmax_pass_len = min_pass_len\fP. -Default maximum password length is 8. +Default maximum password length is 10. .TP .B -y print generated passwords and crypted passwords (see man \fBcrypt\fP(3)) @@ -220,13 +225,23 @@ print generated passwords and crypted passwords (see man \fBcrypt\fP(3)) .B -q quiet mode (do not print warnings) .TP +.B -l +spell genetated passwords. Useful when you want to read generated password by telephone. +.RS +.B WARNING: +Think twice before read your password by phone. +.RE +.TP +.B -t +print pronunciation for generated pronounceable password +.TP .B -h print help information and exit .TP .B -v print version information and exit .SH "DEFAULT OPTIONS" -\fBapg -a 0 -M ncl -n 6 -x 8 -m 6\fP (new style) +\fBapg -a 0 -M sncl -n 6 -x 10 -m 8\fP (new style) .PP If you want to generate really secure passwords, you should use option \fB-s\fP. To simplify diff --git a/doc/man/apgbfm.1 b/doc/man/apgbfm.1 index 7b3f607..a77885d 100644 --- a/doc/man/apgbfm.1 +++ b/doc/man/apgbfm.1 @@ -2,17 +2,17 @@ .\" Licensed under BSD-like License. .\" Created by Adel I. Mirzazhanov .\" -.TH APGBFM 1 "2002 Jun 12" "Automated Password Generator" "User Manual" +.TH APGBFM 1 "2003 Jun 19" "Automated Password Generator" "User Manual" .SH NAME apgbfm \- APG Bloom filter management program .SH SYNOPSIS .B apgbfm -\fB-f\fP \fIfilter\fP \fB-n\fP \fBnumofwords\fP [\fB-q\fP] +\fB-f\fP \fIfilter\fP \fB-n\fP \fBnumofwords\fP [\fB-q\fP] [\fB-s\fP] .br .B apgbfm -\fB-f\fP \fIfilter\fP \fB-d\fP \fIdictfile\fP [\fB-q\fP] +\fB-f\fP \fIfilter\fP \fB-d\fP \fIdictfile\fP [\fB-q\fP] [\fB-s\fP] .br .B apgbfm \fB-f\fP \fIfilter\fP \fB-a\fP \fBword\fP [\fB-q\fP] @@ -27,6 +27,9 @@ apgbfm \fB-f\fP \fIfilter\fP \fB-C\fP \fIdictfile\fP [\fB-q\fP] .br .B apgbfm +\fB-i\fP \fIfilter\fP +.br +.B apgbfm [\fB-v\fP] [\fB-h\fP] .PP .SH DESCRIPTION @@ -57,7 +60,7 @@ bits in filter file are set to 1 then it suppose that word exists in dicionary. .PP .TP .B WARNING !!! -This is the first release of \fBapgbfm\fP and filter file format can be changed +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 !!! @@ -67,6 +70,9 @@ in the future. I'll try to make file formats compatible but i can not guaranty t .B -f \fIfilter\fP use \fIfilter\fP as the name for Bloom filter filename. .TP +.B -i \fIfilter\fP +print information about \fIfilter\fP. +.TP .B -n numofwords create new empty filter for \fBnumofwords\fP number of words. Useful when you want to fill filter dynamicaly. @@ -98,6 +104,9 @@ check every word from \fIdictfile\fP for appearance in the filter. .B -q quiet mode. .TP +.B -s +create new filter in case-insensitive mode. +.TP .B -v print version information. .TP diff --git a/doc/man/apgd.8 b/doc/man/apgd.8 index 0fc3ea8..bfaa284 100644 --- a/doc/man/apgd.8 +++ b/doc/man/apgd.8 @@ -2,7 +2,7 @@ .\" Licensed under BSD-like License. .\" Created by Adel I. Mirzazhanov .\" -.TH APGD 8 "2002 Jun 11" "Automated Password Generator" "User Manual" +.TH APGD 8 "2003 Jun 19" "Automated Password Generator" "User Manual" .SH NAME apgd \- server that generates several random passwords @@ -11,7 +11,8 @@ apgd .B apgd [\fB-a algorithm\fP] [\fB-M mode\fP] [\fB-E char_string\fP] [\fB-n num_of_pass\fP] [\fB-m min_pass_len\fP] [\fB-x max_pass_len\fP] -[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP] +[\fB-r\fP \fIdictfile\fP] [\fB-b\fP \fIfilter_file\fP] [\fB-p min_substr_len\fP] +[\fB-t\fP] [\fB-l\fP] .PP .SH DESCRIPTION .B apgd @@ -164,9 +165,6 @@ Usage of L, M, N, C will slow down password generation process. .B Examples: .br \fB-M sncl\fP or \fB-M SNCL\fP or \fB-M Cn\fP -.PP -\fB-M mode\fP is the new style password generation mode definition. Old style -options(-C, -N, -S, -L, -R) are not supported any more. .RE .TP .B -a algorithm @@ -220,6 +218,14 @@ check generated passwords for their appearance in \fIfilter_file\fP. \fIfilter_file\fP should be created with \fBapgbfm\fP(1) utility. .TP +.B -p min_substr_len +this option tells \fBapg\fP(1) to check every substring of the generated +password for appearance in \fIfilter_file\fP. If any of such substrings would +be found in the \fIfilter_file\fP then generated password would be rejected +and apg(1) will generate another one. +\fBmin_substr_len\fP is specifies minimum substring length to check. +This option is active only if \fB-b\fP option is defined. +.TP .B -n num_of_pass generate .B num_of_pass @@ -229,15 +235,25 @@ number of passwords. Default is 6. generate password with minimum length .B min_pass_len. If \fBmin_pass_len > max_pass_len\fP then \fBmax_pass_len = min_pass_len\fP. -Default minimum password length is 6. +Default minimum password length is 8. .TP .B -x max_pass_len generate password with maximum length .B max_pass_len If \fBmin_pass_len > max_pass_len\fP then \fBmax_pass_len = min_pass_len\fP. -Default maximum password length is 8. +Default maximum password length is 10. +.TP +.B -l +spell genetated passwords. Useful when you want to read generated password by telephone. +.RS +.B WARNING: +Think twice before read your password by phone. +.RE +.TP +.B -t +print pronunciation for generated pronounceable password .SH "DEFAULT OPTIONS" -\fBapgd -a 0 -M ncl -n 6 -x 8 -m 6\fP (new style) +\fBapgd -a 0 -M sncl -n 6 -x 10 -m 8\fP (new style) .SH "EXIT CODE" On successful completion of its task, .B apgd diff --git a/doc/man/wapg.txt b/doc/man/wapg.txt new file mode 100644 index 0000000..0015e1d --- /dev/null +++ b/doc/man/wapg.txt @@ -0,0 +1,192 @@ +WAPG(1) User Manual WAPG(1) + + + +NAME + WAPG - generates several random passwords + + +SYNOPSIS + WAPG [-a algorithm] [-M mode] [-E char_string] [-n num_of_pass] [-m + min_pass_len] [-x max_pass_len] [-r dictfile] [-b filter_file] [-p + min_substr_len] [-c cl_seed] [-d] [-l] [-t] [-q] [-h] [-v] + + +DESCRIPTION + WAPG generates several random passwords. It uses several password gener- + ation algorithms (currently two) and a built-in pseudo random number + generator. + + Default algorithm is pronounceable password generation algorithm + designed by Morrie Gasser and described in A Random Word Generator For + Pronounceable Passwords National Technical Information Service (NTIS) + AD-A-017676. The original paper is very old and had never been put + online, so I have to use NIST implementation described in FIPS-181. + + Another algorithm is simple random character generation algorithm, but + it uses four user-defined symbol sets to produce random password. It + means that user can choose type of symbols that should appear in pass- + word. Symbol sets are: numeric symbol set (0,...,9) , capital letters + symbol set (A,...,Z) , small letters symbol set (a,...,z) and special + symbols symbol set (#,@,!,...). + + Built-in pseudo random number generator is an implementation of algo- + rithm described in Appendix C of ANSI X9.17 or RFC1750 with exception + that it uses CAST or SHA-1 instead of Triple DES. It uses local time + with precision of microseconds (see gettimeofday(2)) and /dev/random + (if available) to produce initial random seed. + + WAPG also have the ability to check generated password quality using + dictionary. You can use this ability if you specify command-line + options -r dictfile or -b filtername where dictfile is the dictionary + file name and filtername is the name of Bloom filter file. In that dic- + tionary you may place words (one per line) that should not appear as + generated passwords. For example: user names, common words, etc. You + even can use one of the dictionaries that come with dictionary password + crackers. Bloom filter file should be created with WAPGbfm(1) utility + included in WAPG distribution. These checks are case sensitive. For + example, if you want to reject word 'root', you should insert in dict- + file words: root, Root, RoOt, ... , ROOT. It is not the easiest way to + check password quality, but it is the most powerful way. In future + releases I plan to implement some other techniques to check passwords + (like pattern check) just to make life easier. + + +OPTIONS + -M mode + Use symbolsets specified with mode for password generation. + mode is a text string consisting of characters S, s, N, n, C, c, + L, l. Where: + + S generator must use special symbol set for every generated + password. + + s generator should use special symbol set for password gen- + eration. + + N generator must use numeral symbol set for every generated + password. + + n generator should use numeral symbol set for password gen- + eration. + + C generator must use capital symbol set for every generated + password. + + c generator should use capital symbol set for password gen- + eration. + + L generator must use small letters symbol set for every + generated password (always present if pronounceable pass- + word generation algorithm is used). + + l generator should use small letters symbol set for pass- + word generation. + + R,r not supported any more. Use -E char_string option + instead. + mode can not be more than 4 characters in length. + + Note: + Usage of L, M, N, C will slow down password generation process. + + Examples: + -M sncl or -M SNCL or -M Cn + + -a algorithm + use algorithm for password generation. + 0 - (default) pronounceable password generation + 1 - random character password generation + + -E char_string + exclude characters in char_string from password generation pro- + cess (in pronounceable password generation mode you can not + exclude small letters). To include special symbols that can be + recognized by shell (apostrophe, quotes, dollar sign, etc.) in + char_string use the backslashed versions. + + Examples: + + Command WAPG -a 1 -M n -n 3 -m 8 -e 23456789 will generate a set + of passwords that will look like this + 10100110 + 01111000 + 11011101 + + Command WAPG -a 1 -M nc -n 3 -m 26 -e GHIJKLMNOPQRSTUVWXYZ will + generate a set of passwords that will look like this + 16A1653CD4DE5E7BD9584A3476 + C8F78E06944AFD57FB9CB882BC + 8C8DF37CD792D36D056BBD5002 + + -r dictfile + check generated passwords for their appearance in dictfile + + -b filter_file + check generated passwords for their appearance in filter_file. + filter_file should be created with WAPGBFM utility. + + -p min_substr_len + this option tells WAPG to check every substring of the gener- + ated password for appearance in filter_file. If any of such sub- + strings would be found in the filter_file then generated + password would be rejected and WAPG will generate another one. + min_substr_len specifies minimum substring length to check. + This option is active only if -b option is defined. + + -c cl_seed + use cl_seed as a random seed for password generation. I use it + when i have to generate passwords in a shell script. + + -d do NOT use any delimiters between generated passwords. I use it + when i have to generate passwords in a shell script. + + -n num_of_pass + generate num_of_pass number of passwords. Default is 6. + + -m min_pass_len + generate password with minimum length min_pass_len. If + min_pass_len > max_pass_len then max_pass_len = min_pass_len. + Default minimum password length is 8. + + -x max_pass_len + generate password with maximum length max_pass_len. If + min_pass_len > max_pass_len then max_pass_len = min_pass_len. + Default maximum password length is 10. + + -q quiet mode (do not print warnings) + + -l spell genetated passwords. Useful when you want to read gener- + ated password by telephone. + WARNING: Think twice before read your password by phone. + + -t print pronunciation for generated pronounceable password + + -h print help information and exit + + -v print version information and exit + +DEFAULT OPTIONS + WAPG -a 0 -M sncl -n 6 -x 10 -m 8 (new style) + +EXIT CODE + On successful completion of its task, WAPG will complete with exit code + 0. An exit code of -1 indicates an error occurred. Textual errors are + written to the standard error stream. + +FILES + None. + +BUGS + None. If you've found one, please send bug description to the author. + +SEE ALSO + WAPGBFM.TXT + +AUTHOR + Adel I. Mirzazhanov, + Project home page: http://www.adel.nursat.kz/WAPG/ + + + +Automated Password Generator 2003 Jun 19 WAPG(1) \ No newline at end of file diff --git a/doc/man/wapgbfm.txt b/doc/man/wapgbfm.txt new file mode 100644 index 0000000..18c19c8 --- /dev/null +++ b/doc/man/wapgbfm.txt @@ -0,0 +1,116 @@ +WAPGBFM User Manual WAPGBFM + + + +NAME + WAPGBFM - APG Bloom filter management program + + +SYNOPSIS + WAPGBFM -f filter -n numofwords [-q] [-s] + WAPGBFM -f filter -d dictfile [-q] [-s] + WAPGBFM -f filter -a word [-q] + WAPGBFM -f filter -A dictfile [-q] + WAPGBFM -f filter -c word [-q] + WAPGBFM -f filter -C dictfile [-q] + WAPGBFM -i filter + WAPGBFM [-v] [-h] + + +DESCRIPTION + WAPGBFM is used to manage Bloom filter that is used to restrict password + generation in WAPG pasword generation software. Usage of the Bloom fil- + ter allows to speed up password check for large dictionaries and has + some other benefits. + + The idea to use Bloom filter for that purpose is came from the descrip- + tion of the OPUS project OPUS: Preventing Weak Password Choices Purdue + Technical Report CSD-TR 92-028 writen by Eugene H. Spafford. + + You can obtain this article from: + http://www.cerias.purdue.edu/homes/spaf/tech-reps/9128.ps + It has very nice description of Bloom filter and it's advantages for + password checking systems. + + In simple words, WAPGBFM generates n hash values for every word and sets + corresponding bits in filter file to 1. To check the word WAPGBFM gener- + ates the same hash functions for that word and if all n corresponding + bits in filter file are set to 1 then it suppose that word exists in + dicionary. WAPGBFM uses SHA-1 as a hash function. + + WAPGBFM can be used as standalone utility, not only with apg, or apgd. + + + WARNING !!! + Filter file format can be changed in the future. I'll try to + make file formats compatible but i can not guaranty this. + + WARNING !!! + WAPGBFM may slow down your computer during filter creation. + +OPTIONS + -f filter + use filter as the name for Bloom filter filename. + + -i filter + print information about filter. + + -n numofwords + create new empty filter for numofwords number of words. Useful + when you want to fill filter dynamicaly. + + -d dictfile + create new filter from dictfile. It may take a lot of time to + generate filter from a big dictionary. In that dictionary you + may place words (one per line) that should not appear as gener- + ated passwords. For example: user names common words, etc. You + even can use one of the dictionaries that come with dictionary + password crackers. This check is case sensitive. For example, + if you want to reject word 'root', you should insert in dictfile + words: root, Root, RoOt, ... , ROOT. To indicate that program + is working WAPGBFM prints dot for every 100 words added in dic- + tionary. + + -a word + add word to the filter. + + -A dictfile + add all words from dictfile to the filter. To indicate that pro- + gram is working WAPGBFM prints dot for every 100 words added in + dictionary. + + -c word + check word for appearance in the filter. + + -C dictfile + check every word from dictfile for appearance in the filter. + + -q quiet mode. + + -s create new filter in case-insensitive mode. + + -v print version information. + + -h print help information. + +EXIT CODE + On successful completion of its task, WAPGBFM will complete with exit + code 0. An exit code of -1 indicates an error occurred. Textual + errors are written to the standard error stream. + +FILES + None. + +BUGS + None. If you've found one, please send bug description to the author. + +SEE ALSO + WAPG.TXT + +AUTHOR + Adel I. Mirzazhanov, + Project home page: http://www.adel.nursat.kz/apg/ + + + +Automated Password Generator 2003 Jun 19 WAPGBFM diff --git a/errors.c b/errors.c index 4a6b5a9..f5dcfdd 100644 --- a/errors.c +++ b/errors.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without diff --git a/errs.h b/errs.h index f19e768..f501088 100644 --- a/errs.h +++ b/errs.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -27,8 +27,8 @@ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef ERRS_H -#define ERRS_H 1 +#ifndef APG_ERRS_H +#define APG_ERRS_H 1 #include @@ -37,4 +37,4 @@ extern void err_sys_fatal(const char *string); extern void err_app(const char *string, const char *err); extern void err_app_fatal(const char *string, const char *err); -#endif /* ERRS_H */ +#endif /* APG_ERRS_H */ diff --git a/getopt.c b/getopt.c index d911df5..4991f4a 100644 --- a/getopt.c +++ b/getopt.c @@ -1,5 +1,5 @@ /* - * Modified by Adel I. Mirzazhanov 2002 + * Modified by Adel I. Mirzazhanov 2002, 2003 * getopt - get option letter from argv * * This is a version of the public domain getopt() implementation by diff --git a/getopt.h b/getopt.h index 9b7ddd9..07e64ad 100644 --- a/getopt.h +++ b/getopt.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 2002 +** Copyright (c) 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without diff --git a/owntypes.h b/owntypes.h index fe2ccc2..31a34f9 100644 --- a/owntypes.h +++ b/owntypes.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -27,8 +27,8 @@ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef OWN_TYPES_H -#define OWN_TYPES_H 1 +#ifndef APG_OWN_TYPES_H +#define APG_OWN_TYPES_H 1 typedef unsigned int UINT; typedef unsigned short USHORT; @@ -41,4 +41,4 @@ typedef unsigned long int UINT32; #define APG_MAX_PASSWORD_LENGTH 255 -#endif /* OWN_TYPES_H */ +#endif /* APG_OWN_TYPES_H */ diff --git a/php/apgonline/lang/polish.php b/php/apgonline/lang/polish.php new file mode 100644 index 0000000..380324a --- /dev/null +++ b/php/apgonline/lang/polish.php @@ -0,0 +1,26 @@ + diff --git a/pronpass.c b/pronpass.c index afbdd11..ca78293 100644 --- a/pronpass.c +++ b/pronpass.c @@ -5,7 +5,7 @@ */ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -37,11 +37,14 @@ #include #include #include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include +#endif #include #include #include "pronpass.h" #include "randpass.h" +#include "convert.h" #include "errs.h" struct unit @@ -2285,172 +2288,3 @@ get_random (USHORT minlen, USHORT maxlen) ret = minlen + (USHORT) randint ((int) (maxlen - minlen + 1)); return (ret); } - -/* -** capitalize() - This routine designed to modify sullable like this: -** adel ----> Adel -** dot ----> Dot -** etc. -** INPUT: -** char * - syllable. -** OUTPUT: -** none. -** NOTES: -** none. -*/ -void capitalize (char *syllable) -{ - char let[26] = - { - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', - 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', - 'u', 'v', 'w', 'x', 'w', 'z' - }; - char clet[26] = - { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', - 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'W', 'Z' - }; - char tmp = 0x00; - int i = 0; - if ( randint(2) == TRUE) - { - (void)memcpy((void *)&tmp, (void *)syllable, sizeof(tmp)); - for(i=0; i < 26; i++) - if ( let[i] == tmp ) - if (is_restricted_symbol(clet[i]) != TRUE) - (void)memcpy ((void *)syllable, (void *)&clet[i], 1); - } -} - -/* -** numerize() - This routine designed to modify single-letter -** syllable like this: -** a ----> 1 or 2 or 3 etc. -** u ----> 1 or 2 or 3 etc. -** etc. -** INPUT: -** char * - single-letter syllable -** OUTPUT: -** none. -** NOTES: -** none. -*/ -void numerize (char *syllable) -{ - char *tmp; - if ( (tmp = (char *)calloc(1, 4)) == NULL) - err_sys_fatal("calloc"); - if ( strlen (syllable) == 1 ) - { - (void) gen_rand_symbol(tmp, S_NB); - (void)memcpy ((void *)syllable, (void *)tmp, 1); - } - free ((void *)tmp); -} -/* -** specialize() - This routine designed to modify single-letter syllable -** like this: -** a ----> # or $ or % etc. -** u ----> # or $ or % etc. -** etc. -** INPUT: -** char * - single-letter syllable. -** OUTPUT: -** none. -** NOTES: -** none. -*/ -void specialize (char *syllable) -{ - char *tmp; - if ( (tmp = (char *)calloc(1, 4)) == NULL) - err_sys_fatal("calloc"); - if ( strlen (syllable) == 1 ) - { - (void) gen_rand_symbol(tmp, S_SS); - (void)memcpy ((void *)syllable, (void *)tmp, 1); - } - free ((void *)tmp); -} - -/* -** symb2name - convert symbol to it's name -** INPUT: -** char * - one symbol syllable -** OUTPUT: -** none. -** NOTES: -** none. -*/ -void -symb2name(char * syllable, char * h_syllable) -{ - struct ssymb_names - { - char symbol; - char *name; - }; - static struct ssymb_names ssn[42] = - { - {'1',"ONE"}, - {'2',"TWO"}, - {'3',"THREE"}, - {'4',"FOUR"}, - {'5',"FIVE"}, - {'6',"SIX"}, - {'7',"SEVEN"}, - {'8',"EIGHT"}, - {'9',"NINE"}, - {'0',"ZERO"}, - {33, "EXCLAMATION_POINT"}, - {34, "QUOTATION_MARK"}, - {35, "CROSSHATCH"}, - {36, "DOLLAR_SIGN"}, - {37, "PERCENT_SIGN"}, - {38, "AMPERSAND"}, - {39, "APOSTROPHE"}, - {40, "LEFT_PARENTHESIS"}, - {41, "RIGHT_PARENTHESIS"}, - {42, "ASTERISK"}, - {43, "PLUS_SIGN"}, - {44, "COMMA"}, - {45, "HYPHEN"}, - {46, "PERIOD"}, - {47, "SLASH"}, - {58, "COLON"}, - {59, "SEMICOLON"}, - {60, "LESS_THAN"}, - {61, "EQUAL_SIGN"}, - {62, "GREATER_THAN"}, - {63, "QUESTION_MARK"}, - {64, "AT_SIGN"}, - {91, "LEFT_BRACKET"}, - {92, "BACKSLASH"}, - {93, "RIGHT_BRACKET"}, - {94, "CIRCUMFLEX"}, - {95, "UNDERSCORE"}, - {96, "GRAVE"}, - {123, "LEFT_BRACE"}, - {124, "VERTICAL_BAR"}, - {125, "RIGHT_BRACE"}, - {126, "TILDE"} - }; - int i = 0; - int flag = FALSE; - - if (strlen(syllable) == 1) - { - for (i=0;i<42;i++) - { - if(*syllable == ssn[i].symbol) - { - (void)memcpy((void*)h_syllable, (void*)ssn[i].name, strlen(ssn[i].name)); - flag = TRUE; - } - } - if (flag != TRUE) - (void)memcpy((void*)h_syllable, (void*)syllable, strlen(syllable)); - } -} diff --git a/pronpass.h b/pronpass.h index 333ad6a..bc9270b 100644 --- a/pronpass.h +++ b/pronpass.h @@ -5,7 +5,7 @@ */ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -34,16 +34,16 @@ */ -#ifndef PRONPASS_H -#define PRONPASS_H 1 +#ifndef APG_PRONPASS_H +#define APG_PRONPASS_H 1 -#ifndef OWN_TYPES_H +#ifndef APG_OWN_TYPES_H #include "owntypes.h" -#endif /* OWN_TYPES_H */ +#endif /* APG_OWN_TYPES_H */ -#ifndef RND_H +#ifndef APG_RND_H #include "rnd.h" -#endif /* RND_H */ +#endif /* APG_RND_H */ #define RULE_SIZE (sizeof(rules)/sizeof(struct unit)) #define ALLOWED(flag) (digram[units_in_syllable[current_unit -1]][unit] & (flag)) @@ -80,10 +80,5 @@ int gen_word (char *word, char *hyphenated_word, USHORT pwlen, unsigned int pass_mode); char *gen_syllable(char *syllable, USHORT pwlen, USHORT *units_in_syllable, USHORT *syllable_length); -void capitalize (char *syllable); -void numerize (char *syllable); -void specialize (char *syllable); -void r_specialize (char *syllable); -void symb2name (char *syllable, char * h_syllable); -#endif /* PRONPASS_H */ +#endif /* APG_PRONPASS_H */ diff --git a/randpass.c b/randpass.c index 6a96943..b804365 100644 --- a/randpass.c +++ b/randpass.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -34,7 +34,9 @@ #include #include #include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include +#endif #include #include "randpass.h" diff --git a/randpass.h b/randpass.h index 5a485cd..dbe1da4 100644 --- a/randpass.h +++ b/randpass.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -30,14 +30,14 @@ /* ** randpass.h */ -#ifndef RANDPASS_H -#define RANDPASS_H 1 +#ifndef APG_RANDPASS_H +#define APG_RANDPASS_H 1 -#ifndef RND_H +#ifndef APG_RND_H #include "rnd.h" #endif -#ifndef OWNTYPES_H +#ifndef APG_OWN_TYPES_H #include "owntypes.h" #endif diff --git a/restrict.c b/restrict.c index a194d0c..2f17560 100644 --- a/restrict.c +++ b/restrict.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -53,8 +53,14 @@ check_pass(char *pass, char *dict) { FILE *dct; char *string; - string = (char *) calloc(1,MAX_DICT_STRING_SIZE); + char *tmp; + if( (string = (char *) calloc(1,MAX_DICT_STRING_SIZE)) == NULL) + return(-1); +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> check_pass: ck pass: %s\n", pass); + fflush (stdout); +#endif /* APG_DEBUG */ /* ** Open dict file an report of error */ @@ -63,12 +69,20 @@ check_pass(char *pass, char *dict) while ((fgets(string, MAX_DICT_STRING_SIZE, dct) != NULL)) { - string = strtok (string," \t\n\0"); + tmp = strtok (string," \t\n\0"); + if( tmp != NULL) + string = tmp; + else + continue; if(strlen(string) != strlen(pass)) continue; else if (strncmp(string, pass, strlen(pass)) == 0) { free ( (void *)string); fclose (dct); +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> check_pass: password found in dictionary: %s\n", pass); + fflush (stdout); +#endif /* APG_DEBUG */ return (1); } } @@ -97,14 +111,79 @@ bloom_check_pass (char *word, char *filter) int ret = 0; FILE *f_filter; h_val filter_size = 0L; + f_mode flt_mode = 0x00; if ( (f_filter = open_filter(filter,"r")) == NULL) return(-1); filter_size = get_filtersize(f_filter); - ret = check_word (word, f_filter, filter_size); + flt_mode = get_filtermode(f_filter); + ret = check_word (word, f_filter, filter_size, flt_mode); close_filter(f_filter); return(ret); } +/* +** paranoid_bloom_check_pass() - routine that checks if password or any +** substring of the password exist in dictionary using Bloom filter. +** INPUT: +** char * - password to check. +** char * - bloom-filter filename. +** USHORT - minimum substring length +** OUTPUT: +** int +** -1 - error +** 1 - password exist in dictionary +** 0 - password does not exist in dictionary +** NOTES: +** none. +*/ +int +paranoid_bloom_check_pass (char * password, char *filter, USHORT s_len) +{ + char * substring; + int len = strlen(password); /* string length */ + int c_substr_start_pos = 0; /* current start position */ + int substr_len = 0; /* substring length (LEN-I >= substr_len >= 2) */ + int k = 0; /* counter */ + int c = 0; /* counter */ + int ret = 0; + if (s_len < 2) s_len = 2; + if (s_len > len) return (bloom_check_pass(password, filter)); + +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> paranoid_bloom_check_pass: ck pass: %s\n", password); + fflush (stdout); +#endif /* APG_DEBUG */ + + if ((substring = (char *)calloc(1, (size_t)len))==NULL) + return (-1); + + for (c_substr_start_pos = 0; c_substr_start_pos <= len-s_len; c_substr_start_pos++) + for (substr_len = s_len; substr_len <= len-c_substr_start_pos; substr_len++) + { + c = 0; + for (k = c_substr_start_pos; k <= c_substr_start_pos + substr_len-1; k++) + { + substring[c]=password[k]; + c++; + } +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> paranoid_bloom_check_pass: ck substr: %s\n", substring); + fflush (stdout); +#endif /* APG_DEBUG */ + if((ret = bloom_check_pass(substring, filter)) == 1) + { +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> paranoid_bloom_check_pass: substr found in filter: %s\n", substring); + fflush (stdout); +#endif /* APG_DEBUG */ + return(1); + } + else if (ret == -1) return(-1); + (void)memset(substring,0,(size_t)len); + } + return(0); +} + /* ** filter_check_pass() - routine that checks password against filter string ** @@ -128,6 +207,12 @@ filter_check_pass(const char * word, unsigned int cond) int cl_ret = 0; int nb_ret = 0; int ss_ret = 0; + +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> filter_check_pass: ck pass: %s\n", word); + fflush (stdout); +#endif /* APG_DEBUG */ + if ((cond & S_SS) > 0) for (i=0; i < 94; i++) if ((smbl[i].type & S_SS) > 0) @@ -156,6 +241,10 @@ filter_check_pass(const char * word, unsigned int cond) if (((cond & S_CL) > 0) &&(cl_ret != 1)) return (1); if (((cond & S_NB) > 0) &&(nb_ret != 1)) return (1); +#ifdef APG_DEBUG + fprintf (stdout, "DEBUG> filter_check_pass: password %s pass the filter\n", word); + fflush (stdout); +#endif /* APG_DEBUG */ return(0); } diff --git a/restrict.h b/restrict.h index 3783c95..c54ebf3 100644 --- a/restrict.h +++ b/restrict.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -30,15 +30,16 @@ /* ** restrict.h */ -#ifndef RESTRICT_H -#define RESTRICT_H 1 +#ifndef APG_RESTRICT_H +#define APG_RESTRICT_H 1 #include "bloom.h" #include "randpass.h" #define MAX_DICT_STRING_SIZE 255 int check_pass(char * pass, char *dict); int bloom_check_pass (char *word, char *filter); +int paranoid_bloom_check_pass (char * password, char *filter, USHORT s_len); int filter_check_pass(const char * word, unsigned int cond); int set_exclude_list(const char * char_string); -#endif /* RESTRICT_H */ +#endif /* APG_RESTRICT_H */ diff --git a/rnd.c b/rnd.c index ad01051..81e9eec 100644 --- a/rnd.c +++ b/rnd.c @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -29,7 +29,9 @@ #include #include +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) #include +#endif #include #include #include @@ -77,7 +79,11 @@ randint(int n) UINT32 x917cast_rnd (void) { +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) struct timeval local_time; +#else + clock_t local_time[2]; /* clock ticks for win32 */ +#endif UINT32 I[2] = {0L,0L}; UINT32 I_plus_s[2] = {0L,0L}; UINT32 Xi[2] = {0L,0L}; @@ -94,7 +100,12 @@ u8 ro_key[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, * ENCRYPTION KEY HEX : 0x000102030405060708090A0B0C0D0E0F (128-bit) * * YOU CAN CHANGE IT IF YOU WANT * **********************************************************************/ +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) (void) gettimeofday (&local_time, 0); +#else + local_time[0] = clock(); + local_time[1] = clock(); +#endif cast_setkey(&ky, (u8*)&ro_key[0], 16); cast_encrypt (&ky, (u8 *)&local_time, (u8*)&I[0]); /* I=Ek(D), D-time */ I_plus_s[0] = I[0] ^ __rnd_seed[0]; /* I0 (+) s0 */ @@ -173,14 +184,14 @@ x917_setseed (UINT32 seed, int quiet) if ( (dr = fopen(APG_DEVRANDOM, "r")) != NULL) { - (void) fread( (void *)&drs[0], 8, 1, dr); + (void)fread( (void *)&drs[0], 8, 1, dr); __rnd_seed[0] = seed ^ drs[0]; __rnd_seed[1] = seed ^ drs[1]; (void) fclose(dr); } else if ( (dr = fopen(APG_DEVURANDOM, "r")) != NULL) { - (void) fread( (void *)&drs[0], 8, 1, dr); + (void)fread( (void *)&drs[0], 8, 1, dr); __rnd_seed[0] = seed ^ drs[0]; __rnd_seed[1] = seed ^ drs[1]; (void) fclose(dr); @@ -188,12 +199,14 @@ x917_setseed (UINT32 seed, int quiet) else { #ifndef CLISERV +#if !defined(WIN32) && !defined(_WIN32) && !defined(__WIN32) && !defined(__WIN32__) if (quiet != TRUE) { fprintf(stderr,"CAN NOT USE RANDOM DEVICE TO GENERATE RANDOM SEED\n"); fprintf(stderr,"USING LOCAL TIME AND PID FOR SEED GENERATION !!!\n"); fflush(stderr); } +#endif /* WIN32 */ #endif /* CLISERV */ __rnd_seed[0] = seed ^ pid; __rnd_seed[1] = seed ^ pid; diff --git a/rnd.h b/rnd.h index 0809f46..230726c 100644 --- a/rnd.h +++ b/rnd.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -27,10 +27,10 @@ ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef RND_H -#define RND_H 1 +#ifndef APG_RND_H +#define APG_RND_H 1 -#ifndef OWN_TYPES_H +#ifndef APG_OWN_TYPES_H #include "owntypes.h" #endif /* OWN_TYPES_H */ @@ -52,4 +52,4 @@ UINT32 x917cast_rnd (void); UINT32 x917sha1_rnd (void); #endif /* APG_USE_SHA*/ -#endif /* RND_H */ +#endif /* APG_RND_H */ diff --git a/smbl.h b/smbl.h index ae4ad18..bb94ef5 100644 --- a/smbl.h +++ b/smbl.h @@ -1,5 +1,5 @@ /* -** Copyright (c) 1999, 2000, 2001, 2002 +** Copyright (c) 1999, 2000, 2001, 2002, 2003 ** Adel I. Mirzazhanov. All rights reserved ** ** Redistribution and use in source and binary forms, with or without @@ -35,8 +35,8 @@ struct sym smbl[94] = {'m', S_SL}, {'n', S_SL}, {'o', S_SL}, {'p', S_SL}, {'q', S_SL}, {'r', S_SL}, {'s', S_SL}, {'t', S_SL}, {'u', S_SL}, {'v', S_SL}, {'w', S_SL}, {'x', S_SL}, {'y', S_SL}, {'z', S_SL}, {'A', S_CL}, {'B', S_CL}, {'C', S_CL}, {'D', S_CL}, - {'E', S_CL}, {'F', S_CL}, {'G', S_CL}, {'H', S_CL}, {'I', S_CL}, {'I', S_CL}, - {'K', S_CL}, {'K', S_CL}, {'M', S_CL}, {'N', S_CL}, {'O', S_CL}, {'P', S_CL}, + {'E', S_CL}, {'F', S_CL}, {'G', S_CL}, {'H', S_CL}, {'I', S_CL}, {'J', S_CL}, + {'K', S_CL}, {'L', S_CL}, {'M', S_CL}, {'N', S_CL}, {'O', S_CL}, {'P', S_CL}, {'Q', S_CL}, {'R', S_CL}, {'S', S_CL}, {'T', S_CL}, {'U', S_CL}, {'V', S_CL}, {'W', S_CL}, {'X', S_CL}, {'Y', S_CL}, {'Z', S_CL}, {'1', S_NB}, {'2', S_NB}, {'3', S_NB}, {'4', S_NB}, {'5', S_NB}, {'6', S_NB}, {'7', S_NB}, {'8', S_NB},