1 #include <ctype.h>
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 
8 #define PROGRAM "PW-Inspector"
9 #define VERSION "v0.2"
10 #define EMAIL "vh@thc.org"
11 #define WEB "https://github.com/vanhauser-thc/thc-hydra"
12 
13 #define MAXLENGTH 256
14 
15 char *prg;
16 
help()17 void help() {
18   printf("%s %s (c) 2005 by van Hauser / THC %s [%s]\n\n", PROGRAM, VERSION, EMAIL, WEB);
19   printf("Syntax: %s [-i FILE] [-o FILE] [-m MINLEN] [-M MAXLEN] [-c MINSETS] "
20          "-l -u -n -p -s\n\n",
21          prg);
22   printf("Options:\n");
23   printf("  -i FILE    file to read passwords from (default: stdin)\n");
24   printf("  -o FILE    file to write valid passwords to (default: stdout)\n");
25   printf("  -m MINLEN  minimum length of a valid password\n");
26   printf("  -M MAXLEN  maximum length of a valid password\n");
27   printf("  -c MINSETS the minimum number of sets required (default: all "
28          "given)\n");
29   printf("Sets:\n");
30   printf("  -l         lowcase characters (a,b,c,d, etc.)\n");
31   printf("  -u         upcase characters (A,B,C,D, etc.)\n");
32   printf("  -n         numbers (1,2,3,4, etc.)\n");
33   printf("  -p         printable characters (which are not -l/-n/-p, e.g. "
34          "$,!,/,(,*, etc.)\n");
35   printf("  -s         special characters - all others not within the sets "
36          "above\n");
37   printf("\n%s reads passwords in and prints those which meet the requirements.\n", PROGRAM);
38   printf("The return code is the number of valid passwords found, 0 if none "
39          "was found.\n");
40   printf("Use for security: check passwords, if 0 is returned, reject password "
41          "choice.\n");
42   printf("Use for hacking: trim your dictionary file to the pw requirements of "
43          "the target.\n");
44   printf("Usage only allowed for legal purposes.\n");
45   exit(-1);
46 }
47 
main(int argc,char * argv[])48 int main(int argc, char *argv[]) {
49   int32_t i, j, k;
50   int32_t sets = 0, countsets = 0, minlen = 0, maxlen = MAXLENGTH, count = 0;
51   int32_t set_low = 0, set_up = 0, set_no = 0, set_print = 0, set_other = 0;
52   FILE *in = stdin, *out = stdout;
53   char buf[MAXLENGTH + 1];
54 
55   prg = argv[0];
56   if (argc < 2)
57     help();
58 
59   while ((i = getopt(argc, argv, "i:o:m:M:c:lunps")) >= 0) {
60     switch (i) {
61     case 'i':
62       if ((in = fopen(optarg, "r")) == NULL) {
63         fprintf(stderr, "Error: unable to open input file %s\n", optarg);
64         exit(-1);
65       }
66       break;
67     case 'o':
68       if ((out = fopen(optarg, "w")) == NULL) {
69         fprintf(stderr, "Error: unable to open output file %s\n", optarg);
70         exit(-1);
71       }
72       break;
73     case 'm':
74       minlen = atoi(optarg);
75       break;
76     case 'M':
77       maxlen = atoi(optarg);
78       break;
79     case 'c':
80       countsets = atoi(optarg);
81       break;
82     case 'l':
83       if (set_low == 0) {
84         set_low = 1;
85         sets++;
86       }
87       break;
88     case 'u':
89       if (set_up == 0) {
90         set_up = 1;
91         sets++;
92       }
93       break;
94     case 'n':
95       if (set_no == 0) {
96         set_no = 1;
97         sets++;
98       }
99       break;
100     case 'p':
101       if (set_print == 0) {
102         set_print = 1;
103         sets++;
104       }
105       break;
106     case 's':
107       if (set_other == 0) {
108         set_other = 1;
109         sets++;
110       }
111       break;
112     default:
113       help();
114     }
115   }
116   if (minlen > maxlen) {
117     fprintf(stderr, "Error: -m MINLEN is greater than -M MAXLEN\n");
118     exit(-1);
119   }
120   if (countsets > sets) {
121     fprintf(stderr, "Error: -c MINSETS is larger than the sets defined\n");
122     exit(-1);
123   }
124   if (countsets == 0)
125     countsets = sets;
126 
127   while (fgets(buf, sizeof(buf), in) != NULL) {
128     i = -1;
129     if (buf[0] == 0)
130       continue;
131     if (buf[strlen(buf) - 1] == '\n')
132       buf[strlen(buf) - 1] = 0;
133     if (buf[strlen(buf) - 1] == '\r')
134       buf[strlen(buf) - 1] = 0;
135     if (strlen(buf) >= minlen && strlen(buf) <= maxlen) {
136       i = 0;
137       if (countsets > 0) {
138         if (set_low)
139           if (strpbrk(buf, "abcdefghijklmnopqrstuvwxyz") != NULL)
140             i++;
141         if (set_up)
142           if (strpbrk(buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ") != NULL)
143             i++;
144         if (set_no)
145           if (strpbrk(buf, "0123456789") != NULL)
146             i++;
147         if (set_print) {
148           j = 0;
149           for (k = 0; k < strlen(buf); k++)
150             if (isprint((int32_t)buf[k]) != 0 && isalnum((int32_t)buf[k]) == 0)
151               j = 1;
152           if (j)
153             i++;
154         }
155         if (set_other) {
156           j = 0;
157           for (k = 0; k < strlen(buf); k++)
158             if (isprint((int32_t)buf[k]) == 0 && isalnum((int32_t)buf[k]) == 0)
159               j = 1;
160           if (j)
161             i++;
162         }
163       }
164       if (i >= countsets) {
165         fprintf(out, "%s\n", buf);
166         count++;
167       }
168     }
169     /* fprintf(stderr, "[DEBUG] i: %d  minlen: %d  maxlen: %d  len: %d\n", i,
170      * minlen, maxlen, strlen(buf)); */
171   }
172   fclose(in);
173   fclose(out);
174 
175   return count;
176 }
177