1#include <memory.h>
2#include <string.h>
3#include <stdlib.h>
4#include <stdio.h>
5#include <ctype.h>
6#include <crack.h>
7
8void usage(char *command) {
9	char *c, *comm;
10
11	comm = command;
12	while ((c = strrchr(comm, '/')) != NULL) {
13		comm = c + 1;
14	}
15
16	fprintf(stderr, "Usage: %s [-c] [-s] [-d <dictionary>]\n\n", comm);
17	fprintf(stderr, "     -c    enables NT like complexity checks\n");
18	fprintf(stderr, "     -d <dictionary file>    for cracklib\n");
19	fprintf(stderr, "     -s    simple check use NT like checks ONLY\n\n");
20	fprintf(stderr, "The password is read via stdin.\n\n");
21	exit(-1);
22}
23
24int complexity(char* passwd)
25{
26	/* TG 26.10.2005
27	 * check password for complexity like MS Windows NT
28	 */
29
30	int c_upper = 0;
31	int c_lower = 0;
32	int c_digit = 0;
33	int c_punct = 0;
34	int c_tot = 0;
35	int i, len;
36
37	if (!passwd) goto fail;
38	len = strlen(passwd);
39
40	for (i = 0; i < len; i++) {
41
42		if (c_tot >= 3) break;
43
44		if (isupper(passwd[i])) {
45			if (!c_upper) {
46				c_upper = 1;
47				c_tot += 1;
48			}
49			continue;
50		}
51		if (islower(passwd[i])) {
52			if (!c_lower) {
53				c_lower = 1;
54				c_tot += 1;
55			}
56			continue;
57		}
58		if (isdigit(passwd[i])) {
59			if (!c_digit) {
60				c_digit = 1;
61				c_tot += 1;
62			}
63			continue;
64		}
65		if (ispunct(passwd[i])) {
66			if (!c_punct) {
67				c_punct = 1;
68				c_tot += 1;
69			}
70			continue;
71		}
72	}
73
74	if ((c_tot) < 3) goto fail;
75	return 0;
76
77fail:
78	fprintf(stderr, "ERR Complexity check failed\n\n");
79	return -4;
80}
81
82int main(int argc, char **argv) {
83	extern char *optarg;
84	int c, ret, complex_check = 0, simplex_check = 0;
85
86	char f[256];
87	char *dictionary = NULL;
88	char *password;
89	char *reply;
90
91	while ( (c = getopt(argc, argv, "d:cs")) != EOF){
92		switch(c) {
93		case 'd':
94			dictionary = strdup(optarg);
95			break;
96		case 'c':
97			complex_check = 1;
98			break;
99		case 's':
100			complex_check = 1;
101			simplex_check = 1;
102			break;
103		default:
104			usage(argv[0]);
105		}
106	}
107
108	if (!simplex_check && dictionary == NULL) {
109		fprintf(stderr, "ERR - Missing cracklib dictionary\n\n");
110		usage(argv[0]);
111	}
112
113	fflush(stdin);
114	password = fgets(f, sizeof(f), stdin);
115
116	if (password == NULL) {
117		fprintf(stderr, "ERR - Failed to read password\n\n");
118		exit(-2);
119	}
120
121	if (complex_check) {
122		ret = complexity(password);
123		if (ret) {
124			exit(ret);
125		}
126	}
127
128	if (simplex_check) {
129		exit(0);
130	}
131
132	reply = FascistCheck(password, dictionary);
133	if (reply != NULL) {
134		fprintf(stderr, "ERR - %s\n\n", reply);
135		exit(-3);
136	}
137
138	exit(0);
139}
140
141