root/genpasswd/trunk/genpasswd.c

Revision 133, 5.0 kB (checked in by root, 5 years ago)

Initial import.

Line 
1 #define _XOPEN_SOURCE
2 #include <sys/types.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <ctype.h>
8
9 #define VERSION  "0.1.13"
10
11 char *get_range(char const *input);
12 void usage(char const *name);
13 void make_salt(char *salt, int size);
14
15 int main(int argc, char **argv) {
16 char *input = "-0-9a-zA-Z`=[]\\;',./~_+{}|:\"<>?", *buffer = 0, *exclude = 0, *excludeinput = 0;
17 int len, i, pwlen = 16, md5 = 0, cryptit = 0, showplain = 1, quiet = 0;
18 char *password = NULL;
19
20         if (argc > 1)
21                 for (i = 1; i < argc; i++)
22                         /* options */
23                         if (argv[i][0] == '-') {
24                         int j = 1;
25
26                                 while (argv[i][j]) {
27                                         switch (argv[i][j]) {
28                                                 /* numeric size */
29                                                 case '0' : case '1' : case '2' : case '3' :
30                                                 case '4' : case '5' : case '6' : case '7' :
31                                                 case '8' : case '9' :
32                                                         pwlen = atoi(argv[i] + j);
33                                                         while (argv[i][j] && isdigit(argv[i][j])) j++;
34                                                         j--;
35                                                 break;
36                                                 /* md5 */
37                                                 case 'm' :
38                                                         md5 = 1;
39                                                 break;
40                                                 case 'v' :
41                                                         printf("%s\n", VERSION);
42                                                         return 0;
43                                                 break;
44                                                 // crypt
45                                                 case 'c' :
46                                                         cryptit = 1;
47                                                 break;
48                                                 case 'n' :
49                                                         input = "0-9";
50                                                 break;
51                                                 case 'q' :
52                                                         quiet = 1;
53                                                 break;
54                                                 // exclude
55                                                 case 'e' :
56                                                         excludeinput = argv[i] + j;
57                                                         while (argv[i][j]) ++j;
58                                                         --j;
59                                                 break;
60                                                 case 'a' :
61                                                         input = "a-zA-Z";
62                                                 break;
63                                                 case 'A' :
64                                                         input = "A-Za-z0-9";
65                                                 break;
66                                                 case 'p' :
67                                                 {
68                                                 int i;
69                                                 char comp[64];
70
71                                                         for (i = 0; i < 2; i++) {
72                                                                 showplain = 0;
73                                                                 system("stty -echo");
74                                                                 if (i == 1)
75                                                                         password = (char*)malloc(64);
76                                                                 else
77                                                                         password = comp;
78                                                                 if (!quiet) printf("Password: ");
79                                                                 fflush(stdout);
80                                                                 fgets(password, 64, stdin);
81                                                                 password[strlen(password) - 1] = 0;
82                                                                 system("stty echo");
83                                                                 if (!quiet) printf("\n");
84                                                                 fflush(stdout);
85                                                         }
86                                                         if (strcmp(password, comp)) {
87                                                                 fprintf(stderr, "error: passwords do not match\n");
88                                                                 return 1;
89                                                         }
90                                                 }
91                                                 break;
92                                                 case 'P' :
93                                                         password = argv[i] + j + 1;
94                                                         while (argv[i][j]) ++j;
95                                                         --j;
96                                                 break;
97                                                 default :
98                                                         usage(argv[0]);
99                                                 break;
100                                         }
101                                         j++;
102                                 }
103                         } else /* specify range of characters to use */
104                                 input = argv[i];
105                
106         srand48(getpid() + time(0));
107
108         if ((buffer = get_range(input)) == NULL) {
109                 printf("%s: error, too many characters in password character pool (>255)\n", argv[0]);
110                 return 1;
111         }
112
113         if (excludeinput) {
114         char *new =  (char*)malloc(strlen(buffer) + 1);
115         int j = 0;
116
117                 if ((exclude = get_range(excludeinput)) == NULL) {
118                         printf("%s: error, too many characters in exclude pool (>255)\n", argv[0]);
119                         return 1;
120                 }
121                 for (i = 0; i < strlen(buffer); i++)
122                         if (!strchr(exclude, buffer[i]))
123                                 new[j++] = buffer[i];
124                 new[j] = 0;
125                 free(buffer);
126                 buffer = new;
127         }
128
129         len = strlen(buffer);
130
131         if (password == NULL) {
132                 password = (char*)malloc(pwlen + 1);
133                 for (i = 0; i < pwlen; i++)
134                         password[i] = buffer[(int)(drand48() * len)];
135                 password[i] = 0;
136         }
137
138         if (showplain) {
139                 if (!quiet) printf("Password: ");
140                 printf("%s\n", password);
141         }
142
143         if (md5) {
144         char salt[13];
145                
146                 strcpy(salt, "$1$");
147                 make_salt(salt + 3, 9);
148                 if (!quiet) printf("MD5: ");
149                 printf("%s\n", crypt(password, salt));
150         }
151
152         if (cryptit) {
153         char salt[3];
154
155                 make_salt(salt, 2);
156                 if (!quiet) printf("Crypt: ");
157                 printf("%s\n", crypt(password, salt));
158         }
159         return 0;
160 }
161
162 char *get_range(char const *input) {
163 char *out = (char*)malloc(257), *p = out;
164        
165         if (*input == '-') {
166                 *p++ = '-';
167                 input++;
168         }
169         /* return zero-terminated buffer */
170         while (*input) {
171
172                 if (p - out >= 254) return NULL;
173                 if (input[1] == '-') {
174                 int i;
175
176                         if (input[2] == 0)
177                                 *p++ = '-';
178                         else {
179                                 for (i = input[0]; i <= input[2]; ++i) {
180                                         if (p - out >= 254) return NULL;
181                                         *p++ = i;
182                                 }
183                         }
184                         input += 3;
185                 } else {
186                         *p++ = *input;
187                         ++input;
188                 }
189         }
190         *p = 0;
191         return out;
192 }
193
194 void usage(char const *name) {
195         printf("usage: %s [-<length>] [-m] [-n] [-a] [-A] [<range>]\n"
196 "  -<length>    specify the length of the password\n"
197 "  -m           generate the MD5 sum of the resultant password\n"
198 "  -c           generate crypt of resultant password\n"
199 "  -n           use numeric characters for password character pool\n"
200 "  -a           use alpha characters for password character pool\n"
201 "  -A           use alpha-numeric characters for password character pool\n"
202 "  -e<string>   exclude the given characters from the password\n"
203 "  -p           prompt the user for the password\n"
204 "  -P<string>   use the specified string as the password\n"
205 "  -q           do not display prompts or field descriptions\n"
206 "  <range>      specify characters to use for password, ala '[]' regexp\n"
207 "  -v           show version number\n"
208 "\n"
209 "eg. %s -64m A-Za-z0-9\n"
210 , name, name);
211         exit(1);
212 }
213
214 void make_salt(char *salt, int size) {
215 char *randomchars = get_range("a-zA-Z0-9./");
216 int i;
217
218         for (i = 0; i < size; i++)
219                 salt[i] = randomchars[(int)(drand48() * strlen(randomchars))];
220         salt[size] = 0;
221         free((void*)randomchars);
222 }
Note: See TracBrowser for help on using the browser.