| 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 | 
 | 
|---|
| 8 | void 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 | 
 | 
|---|
| 24 | int 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 | 
 | 
|---|
| 77 | fail:
 | 
|---|
| 78 |         fprintf(stderr, "ERR Complexity check failed\n\n");
 | 
|---|
| 79 |         return -4;
 | 
|---|
| 80 | }
 | 
|---|
| 81 | 
 | 
|---|
| 82 | int 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 | 
 | 
|---|