Commit | Line | Data |
---|---|---|
eb1747f5 KM |
1 | /* Copyright (c) 1982 Regents of the University of California */ |
2 | ||
1d822ead | 3 | static char sccsid[] = "@(#)ruserpass.c 4.2 %G%"; |
eb1747f5 KM |
4 | |
5 | #include <stdio.h> | |
6 | #include <utmp.h> | |
7 | #include <ctype.h> | |
8 | #include <sys/types.h> | |
9 | #include <sys/stat.h> | |
c4a8a0db | 10 | #include <errno.h> |
eb1747f5 KM |
11 | |
12 | char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin(); | |
13 | struct utmp *getutmp(); | |
14 | static FILE *cfile; | |
15 | ||
16 | ruserpass(host, aname, apass) | |
17 | char *host, **aname, **apass; | |
18 | { | |
19 | ||
20 | renv(host, aname, apass); | |
21 | if (*aname == 0 || *apass == 0) | |
22 | rnetrc(host, aname, apass); | |
23 | if (*aname == 0) { | |
24 | char *myname = getlogin(); | |
25 | *aname = malloc(16); | |
26 | printf("Name (%s:%s): ", host, myname); | |
27 | fflush(stdout); | |
28 | if (read(2, *aname, 16) <= 0) | |
29 | exit(1); | |
30 | if ((*aname)[0] == '\n') | |
31 | *aname = myname; | |
32 | else | |
33 | if (index(*aname, '\n')) | |
34 | *index(*aname, '\n') = 0; | |
35 | } | |
36 | if (*aname && *apass == 0) { | |
37 | printf("Password (%s:%s): ", host, *aname); | |
38 | fflush(stdout); | |
39 | *apass = getpass(""); | |
40 | } | |
41 | } | |
42 | ||
43 | static | |
44 | renv(host, aname, apass) | |
45 | char *host, **aname, **apass; | |
46 | { | |
47 | register char *cp; | |
48 | char *stemp, fgetlogin, *comma; | |
49 | ||
50 | cp = renvlook(host); | |
51 | if (cp == NULL) | |
52 | return; | |
53 | if (!isalpha(cp[0])) | |
54 | return; | |
55 | comma = index(cp, ','); | |
56 | if (comma == 0) | |
57 | return; | |
58 | if (*aname == 0) { | |
59 | *aname = malloc(comma - cp + 1); | |
60 | strncpy(*aname, cp, comma - cp); | |
61 | } else | |
62 | if (strncmp(*aname, cp, comma - cp)) | |
63 | return; | |
64 | comma++; | |
65 | cp = malloc(strlen(comma)+1); | |
66 | strcpy(cp, comma); | |
67 | *apass = malloc(16); | |
68 | mkpwclear(cp, host[0], *apass); | |
69 | } | |
70 | ||
71 | static | |
72 | char * | |
73 | renvlook(host) | |
74 | char *host; | |
75 | { | |
76 | register char *cp, **env; | |
77 | extern char **environ; | |
78 | ||
79 | env = environ; | |
80 | for (env = environ; *env != NULL; env++) | |
81 | if (!strncmp(*env, "MACH", 4)) { | |
82 | cp = index(*env, '='); | |
83 | if (cp == 0) | |
84 | continue; | |
85 | if (strncmp(*env+4, host, cp-(*env+4))) | |
86 | continue; | |
87 | return (cp+1); | |
88 | } | |
89 | return (NULL); | |
90 | } | |
91 | ||
92 | #define DEFAULT 1 | |
93 | #define LOGIN 2 | |
94 | #define PASSWD 3 | |
95 | #define NOTIFY 4 | |
96 | #define WRITE 5 | |
97 | #define YES 6 | |
98 | #define NO 7 | |
99 | #define COMMAND 8 | |
100 | #define FORCE 9 | |
101 | #define ID 10 | |
102 | #define MACHINE 11 | |
103 | ||
104 | static char tokval[100]; | |
105 | ||
106 | static struct toktab { | |
107 | char *tokstr; | |
108 | int tval; | |
109 | } toktab[]= { | |
110 | "default", DEFAULT, | |
111 | "login", LOGIN, | |
112 | "password", PASSWD, | |
113 | "notify", NOTIFY, | |
114 | "write", WRITE, | |
115 | "yes", YES, | |
116 | "y", YES, | |
117 | "no", NO, | |
118 | "n", NO, | |
119 | "command", COMMAND, | |
120 | "force", FORCE, | |
121 | "machine", MACHINE, | |
122 | 0, 0 | |
123 | }; | |
124 | ||
125 | static | |
126 | rnetrc(host, aname, apass) | |
127 | char *host, **aname, **apass; | |
128 | { | |
129 | char *hdir, buf[BUFSIZ]; | |
130 | int t; | |
131 | struct stat stb; | |
c4a8a0db | 132 | extern int errno; |
eb1747f5 KM |
133 | |
134 | hdir = getenv("HOME"); | |
135 | if (hdir == NULL) | |
136 | hdir = "."; | |
137 | sprintf(buf, "%s/.netrc", hdir); | |
138 | cfile = fopen(buf, "r"); | |
139 | if (cfile == NULL) { | |
c4a8a0db SL |
140 | if (errno != ENOENT) |
141 | perror(buf); | |
eb1747f5 KM |
142 | return; |
143 | } | |
144 | next: | |
145 | while ((t = token())) switch(t) { | |
146 | ||
147 | case DEFAULT: | |
148 | (void) token(); | |
149 | continue; | |
150 | ||
151 | case MACHINE: | |
152 | if (token() != ID || strcmp(host, tokval)) | |
153 | continue; | |
154 | while ((t = token()) && t != MACHINE) switch(t) { | |
155 | ||
156 | case LOGIN: | |
157 | if (token()) | |
158 | if (*aname == 0) { | |
159 | *aname = malloc(strlen(tokval) + 1); | |
160 | strcpy(*aname, tokval); | |
161 | } else { | |
162 | if (strcmp(*aname, tokval)) | |
163 | goto next; | |
164 | } | |
165 | break; | |
166 | case PASSWD: | |
167 | if (fstat(fileno(cfile), &stb) >= 0 | |
168 | && (stb.st_mode & 077) != 0) { | |
169 | fprintf(stderr, "Error - .netrc file not correct mode.\n"); | |
170 | fprintf(stderr, "Remove password or correct mode.\n"); | |
171 | exit(1); | |
172 | } | |
173 | if (token() && *apass == 0) { | |
174 | *apass = malloc(strlen(tokval) + 1); | |
175 | strcpy(*apass, tokval); | |
176 | } | |
177 | break; | |
178 | case COMMAND: | |
179 | case NOTIFY: | |
180 | case WRITE: | |
181 | case FORCE: | |
182 | (void) token(); | |
183 | break; | |
184 | default: | |
185 | fprintf(stderr, "Unknown .netrc option %s\n", tokval); | |
186 | break; | |
187 | } | |
188 | goto done; | |
189 | } | |
190 | done: | |
191 | fclose(cfile); | |
192 | } | |
193 | ||
194 | static | |
195 | token() | |
196 | { | |
197 | char *cp; | |
198 | int c; | |
199 | struct toktab *t; | |
200 | ||
201 | if (feof(cfile)) | |
202 | return (0); | |
203 | while ((c = getc(cfile)) != EOF && | |
204 | (c == '\n' || c == '\t' || c == ' ' || c == ',')) | |
205 | continue; | |
206 | if (c == EOF) | |
207 | return (0); | |
208 | cp = tokval; | |
209 | if (c == '"') { | |
210 | while ((c = getc(cfile)) != EOF && c != '"') { | |
211 | if (c == '\\') | |
212 | c = getc(cfile); | |
213 | *cp++ = c; | |
214 | } | |
215 | } else { | |
216 | *cp++ = c; | |
217 | while ((c = getc(cfile)) != EOF | |
218 | && c != '\n' && c != '\t' && c != ' ' && c != ',') { | |
219 | if (c == '\\') | |
220 | c = getc(cfile); | |
221 | *cp++ = c; | |
222 | } | |
223 | } | |
224 | *cp = 0; | |
225 | if (tokval[0] == 0) | |
226 | return (0); | |
227 | for (t = toktab; t->tokstr; t++) | |
228 | if (!strcmp(t->tokstr, tokval)) | |
229 | return (t->tval); | |
230 | return (ID); | |
231 | } | |
232 | /* rest is nbs.c stolen from berknet */ | |
233 | ||
234 | char *deblknot(), *deblkclr(); | |
235 | char *nbs8decrypt(), *nbs8encrypt(); | |
236 | static char E[48]; | |
237 | ||
238 | /* | |
239 | * The E bit-selection table. | |
240 | */ | |
241 | static char e[] = { | |
242 | 32, 1, 2, 3, 4, 5, | |
243 | 4, 5, 6, 7, 8, 9, | |
244 | 8, 9,10,11,12,13, | |
245 | 12,13,14,15,16,17, | |
246 | 16,17,18,19,20,21, | |
247 | 20,21,22,23,24,25, | |
248 | 24,25,26,27,28,29, | |
249 | 28,29,30,31,32, 1, | |
250 | }; | |
251 | static | |
252 | char *nbsencrypt(str,key,result) | |
253 | char *result; | |
254 | char *str, *key; { | |
255 | static char buf[20],oldbuf[20]; | |
256 | register int j; | |
257 | result[0] = 0; | |
258 | strcpy(oldbuf,key); | |
259 | while(*str){ | |
260 | for(j=0;j<10;j++)buf[j] = 0; | |
261 | for(j=0;j<8 && *str;j++)buf[j] = *str++; | |
262 | strcat(result,nbs8encrypt(buf,oldbuf)); | |
263 | strcat(result,"$"); | |
264 | strcpy(oldbuf,buf); | |
265 | } | |
266 | return(result); | |
267 | } | |
268 | static | |
269 | char *nbsdecrypt(cpt,key,result) | |
270 | char *result; | |
271 | char *cpt,*key; { | |
272 | char *s; | |
273 | char c,oldbuf[20]; | |
274 | result[0] = 0; | |
275 | strcpy(oldbuf,key); | |
276 | while(*cpt){ | |
277 | for(s = cpt;*s && *s != '$';s++); | |
278 | c = *s; | |
279 | *s = 0; | |
280 | strcpy(oldbuf,nbs8decrypt(cpt,oldbuf)); | |
281 | strcat(result,oldbuf); | |
282 | if(c == 0)break; | |
283 | cpt = s + 1; | |
284 | } | |
285 | return(result); | |
286 | } | |
287 | ||
288 | static | |
289 | char *nbs8encrypt(str,key) | |
290 | char *str, *key; { | |
291 | static char keyblk[100], blk[100]; | |
292 | register int i; | |
293 | ||
294 | enblkclr(keyblk,key); | |
295 | nbssetkey(keyblk); | |
296 | ||
297 | for(i=0;i<48;i++) E[i] = e[i]; | |
298 | enblkclr(blk,str); | |
299 | blkencrypt(blk,0); /* forward dir */ | |
300 | ||
301 | return(deblknot(blk)); | |
302 | } | |
303 | ||
304 | static | |
305 | char *nbs8decrypt(crp,key) | |
306 | char *crp, *key; { | |
307 | static char keyblk[100], blk[100]; | |
308 | register int i; | |
309 | ||
310 | enblkclr(keyblk,key); | |
311 | nbssetkey(keyblk); | |
312 | ||
313 | for(i=0;i<48;i++) E[i] = e[i]; | |
314 | enblknot(blk,crp); | |
315 | blkencrypt(blk,1); /* backward dir */ | |
316 | ||
317 | return(deblkclr(blk)); | |
318 | } | |
319 | ||
320 | static | |
321 | enblkclr(blk,str) /* ignores top bit of chars in string str */ | |
322 | char *blk,*str; { | |
323 | register int i,j; | |
324 | char c; | |
325 | for(i=0;i<70;i++)blk[i] = 0; | |
326 | for(i=0; (c= *str) && i<64; str++){ | |
327 | for(j=0; j<7; j++, i++) | |
328 | blk[i] = (c>>(6-j)) & 01; | |
329 | i++; | |
330 | } | |
331 | } | |
332 | ||
333 | static | |
334 | char *deblkclr(blk) | |
335 | char *blk; { | |
336 | register int i,j; | |
337 | char c; | |
338 | static char iobuf[30]; | |
339 | for(i=0; i<10; i++){ | |
340 | c = 0; | |
341 | for(j=0; j<7; j++){ | |
342 | c <<= 1; | |
343 | c |= blk[8*i+j]; | |
344 | } | |
345 | iobuf[i] = c; | |
346 | } | |
347 | iobuf[i] = 0; | |
348 | return(iobuf); | |
349 | } | |
350 | ||
351 | static | |
352 | enblknot(blk,crp) | |
353 | char *blk; | |
354 | char *crp; { | |
355 | register int i,j; | |
356 | char c; | |
357 | for(i=0;i<70;i++)blk[i] = 0; | |
358 | for(i=0; (c= *crp) && i<64; crp++){ | |
359 | if(c>'Z') c -= 6; | |
360 | if(c>'9') c -= 7; | |
361 | c -= '.'; | |
362 | for(j=0; j<6; j++, i++) | |
363 | blk[i] = (c>>(5-j)) & 01; | |
364 | } | |
365 | } | |
366 | ||
367 | static | |
368 | char *deblknot(blk) | |
369 | char *blk; { | |
370 | register int i,j; | |
371 | char c; | |
372 | static char iobuf[30]; | |
373 | for(i=0; i<11; i++){ | |
374 | c = 0; | |
375 | for(j=0; j<6; j++){ | |
376 | c <<= 1; | |
377 | c |= blk[6*i+j]; | |
378 | } | |
379 | c += '.'; | |
380 | if(c > '9')c += 7; | |
381 | if(c > 'Z')c += 6; | |
382 | iobuf[i] = c; | |
383 | } | |
384 | iobuf[i] = 0; | |
385 | return(iobuf); | |
386 | } | |
387 | ||
388 | /* | |
389 | * This program implements the | |
390 | * Proposed Federal Information Processing | |
391 | * Data Encryption Standard. | |
392 | * See Federal Register, March 17, 1975 (40FR12134) | |
393 | */ | |
394 | ||
395 | /* | |
396 | * Initial permutation, | |
397 | */ | |
398 | static char IP[] = { | |
399 | 58,50,42,34,26,18,10, 2, | |
400 | 60,52,44,36,28,20,12, 4, | |
401 | 62,54,46,38,30,22,14, 6, | |
402 | 64,56,48,40,32,24,16, 8, | |
403 | 57,49,41,33,25,17, 9, 1, | |
404 | 59,51,43,35,27,19,11, 3, | |
405 | 61,53,45,37,29,21,13, 5, | |
406 | 63,55,47,39,31,23,15, 7, | |
407 | }; | |
408 | ||
409 | /* | |
410 | * Final permutation, FP = IP^(-1) | |
411 | */ | |
412 | static char FP[] = { | |
413 | 40, 8,48,16,56,24,64,32, | |
414 | 39, 7,47,15,55,23,63,31, | |
415 | 38, 6,46,14,54,22,62,30, | |
416 | 37, 5,45,13,53,21,61,29, | |
417 | 36, 4,44,12,52,20,60,28, | |
418 | 35, 3,43,11,51,19,59,27, | |
419 | 34, 2,42,10,50,18,58,26, | |
420 | 33, 1,41, 9,49,17,57,25, | |
421 | }; | |
422 | ||
423 | /* | |
424 | * Permuted-choice 1 from the key bits | |
425 | * to yield C and D. | |
426 | * Note that bits 8,16... are left out: | |
427 | * They are intended for a parity check. | |
428 | */ | |
429 | static char PC1_C[] = { | |
430 | 57,49,41,33,25,17, 9, | |
431 | 1,58,50,42,34,26,18, | |
432 | 10, 2,59,51,43,35,27, | |
433 | 19,11, 3,60,52,44,36, | |
434 | }; | |
435 | ||
436 | static char PC1_D[] = { | |
437 | 63,55,47,39,31,23,15, | |
438 | 7,62,54,46,38,30,22, | |
439 | 14, 6,61,53,45,37,29, | |
440 | 21,13, 5,28,20,12, 4, | |
441 | }; | |
442 | ||
443 | /* | |
444 | * Sequence of shifts used for the key schedule. | |
445 | */ | |
446 | static char shifts[] = { | |
447 | 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1, | |
448 | }; | |
449 | ||
450 | /* | |
451 | * Permuted-choice 2, to pick out the bits from | |
452 | * the CD array that generate the key schedule. | |
453 | */ | |
454 | static char PC2_C[] = { | |
455 | 14,17,11,24, 1, 5, | |
456 | 3,28,15, 6,21,10, | |
457 | 23,19,12, 4,26, 8, | |
458 | 16, 7,27,20,13, 2, | |
459 | }; | |
460 | ||
461 | static char PC2_D[] = { | |
462 | 41,52,31,37,47,55, | |
463 | 30,40,51,45,33,48, | |
464 | 44,49,39,56,34,53, | |
465 | 46,42,50,36,29,32, | |
466 | }; | |
467 | ||
468 | /* | |
469 | * The C and D arrays used to calculate the key schedule. | |
470 | */ | |
471 | ||
472 | static char C[28]; | |
473 | static char D[28]; | |
474 | /* | |
475 | * The key schedule. | |
476 | * Generated from the key. | |
477 | */ | |
478 | static char KS[16][48]; | |
479 | ||
480 | /* | |
481 | * Set up the key schedule from the key. | |
482 | */ | |
483 | ||
484 | static | |
485 | nbssetkey(key) | |
486 | char *key; | |
487 | { | |
488 | register i, j, k; | |
489 | int t; | |
490 | ||
491 | /* | |
492 | * First, generate C and D by permuting | |
493 | * the key. The low order bit of each | |
494 | * 8-bit char is not used, so C and D are only 28 | |
495 | * bits apiece. | |
496 | */ | |
497 | for (i=0; i<28; i++) { | |
498 | C[i] = key[PC1_C[i]-1]; | |
499 | D[i] = key[PC1_D[i]-1]; | |
500 | } | |
501 | /* | |
502 | * To generate Ki, rotate C and D according | |
503 | * to schedule and pick up a permutation | |
504 | * using PC2. | |
505 | */ | |
506 | for (i=0; i<16; i++) { | |
507 | /* | |
508 | * rotate. | |
509 | */ | |
510 | for (k=0; k<shifts[i]; k++) { | |
511 | t = C[0]; | |
512 | for (j=0; j<28-1; j++) | |
513 | C[j] = C[j+1]; | |
514 | C[27] = t; | |
515 | t = D[0]; | |
516 | for (j=0; j<28-1; j++) | |
517 | D[j] = D[j+1]; | |
518 | D[27] = t; | |
519 | } | |
520 | /* | |
521 | * get Ki. Note C and D are concatenated. | |
522 | */ | |
523 | for (j=0; j<24; j++) { | |
524 | KS[i][j] = C[PC2_C[j]-1]; | |
525 | KS[i][j+24] = D[PC2_D[j]-28-1]; | |
526 | } | |
527 | } | |
528 | } | |
529 | ||
530 | ||
531 | /* | |
532 | * The 8 selection functions. | |
533 | * For some reason, they give a 0-origin | |
534 | * index, unlike everything else. | |
535 | */ | |
536 | static char S[8][64] = { | |
537 | 14, 4,13, 1, 2,15,11, 8, 3,10, 6,12, 5, 9, 0, 7, | |
538 | 0,15, 7, 4,14, 2,13, 1,10, 6,12,11, 9, 5, 3, 8, | |
539 | 4, 1,14, 8,13, 6, 2,11,15,12, 9, 7, 3,10, 5, 0, | |
540 | 15,12, 8, 2, 4, 9, 1, 7, 5,11, 3,14,10, 0, 6,13, | |
541 | ||
542 | 15, 1, 8,14, 6,11, 3, 4, 9, 7, 2,13,12, 0, 5,10, | |
543 | 3,13, 4, 7,15, 2, 8,14,12, 0, 1,10, 6, 9,11, 5, | |
544 | 0,14, 7,11,10, 4,13, 1, 5, 8,12, 6, 9, 3, 2,15, | |
545 | 13, 8,10, 1, 3,15, 4, 2,11, 6, 7,12, 0, 5,14, 9, | |
546 | ||
547 | 10, 0, 9,14, 6, 3,15, 5, 1,13,12, 7,11, 4, 2, 8, | |
548 | 13, 7, 0, 9, 3, 4, 6,10, 2, 8, 5,14,12,11,15, 1, | |
549 | 13, 6, 4, 9, 8,15, 3, 0,11, 1, 2,12, 5,10,14, 7, | |
550 | 1,10,13, 0, 6, 9, 8, 7, 4,15,14, 3,11, 5, 2,12, | |
551 | ||
552 | 7,13,14, 3, 0, 6, 9,10, 1, 2, 8, 5,11,12, 4,15, | |
553 | 13, 8,11, 5, 6,15, 0, 3, 4, 7, 2,12, 1,10,14, 9, | |
554 | 10, 6, 9, 0,12,11, 7,13,15, 1, 3,14, 5, 2, 8, 4, | |
555 | 3,15, 0, 6,10, 1,13, 8, 9, 4, 5,11,12, 7, 2,14, | |
556 | ||
557 | 2,12, 4, 1, 7,10,11, 6, 8, 5, 3,15,13, 0,14, 9, | |
558 | 14,11, 2,12, 4, 7,13, 1, 5, 0,15,10, 3, 9, 8, 6, | |
559 | 4, 2, 1,11,10,13, 7, 8,15, 9,12, 5, 6, 3, 0,14, | |
560 | 11, 8,12, 7, 1,14, 2,13, 6,15, 0, 9,10, 4, 5, 3, | |
561 | ||
562 | 12, 1,10,15, 9, 2, 6, 8, 0,13, 3, 4,14, 7, 5,11, | |
563 | 10,15, 4, 2, 7,12, 9, 5, 6, 1,13,14, 0,11, 3, 8, | |
564 | 9,14,15, 5, 2, 8,12, 3, 7, 0, 4,10, 1,13,11, 6, | |
565 | 4, 3, 2,12, 9, 5,15,10,11,14, 1, 7, 6, 0, 8,13, | |
566 | ||
567 | 4,11, 2,14,15, 0, 8,13, 3,12, 9, 7, 5,10, 6, 1, | |
568 | 13, 0,11, 7, 4, 9, 1,10,14, 3, 5,12, 2,15, 8, 6, | |
569 | 1, 4,11,13,12, 3, 7,14,10,15, 6, 8, 0, 5, 9, 2, | |
570 | 6,11,13, 8, 1, 4,10, 7, 9, 5, 0,15,14, 2, 3,12, | |
571 | ||
572 | 13, 2, 8, 4, 6,15,11, 1,10, 9, 3,14, 5, 0,12, 7, | |
573 | 1,15,13, 8,10, 3, 7, 4,12, 5, 6,11, 0,14, 9, 2, | |
574 | 7,11, 4, 1, 9,12,14, 2, 0, 6,10,13,15, 3, 5, 8, | |
575 | 2, 1,14, 7, 4,10, 8,13,15,12, 9, 0, 3, 5, 6,11, | |
576 | }; | |
577 | ||
578 | /* | |
579 | * P is a permutation on the selected combination | |
580 | * of the current L and key. | |
581 | */ | |
582 | static char P[] = { | |
583 | 16, 7,20,21, | |
584 | 29,12,28,17, | |
585 | 1,15,23,26, | |
586 | 5,18,31,10, | |
587 | 2, 8,24,14, | |
588 | 32,27, 3, 9, | |
589 | 19,13,30, 6, | |
590 | 22,11, 4,25, | |
591 | }; | |
592 | ||
593 | /* | |
594 | * The current block, divided into 2 halves. | |
595 | */ | |
596 | static char L[32], R[32]; | |
597 | static char tempL[32]; | |
598 | static char f[32]; | |
599 | ||
600 | /* | |
601 | * The combination of the key and the input, before selection. | |
602 | */ | |
603 | static char preS[48]; | |
604 | ||
605 | /* | |
606 | * The payoff: encrypt a block. | |
607 | */ | |
608 | ||
609 | static | |
610 | blkencrypt(block, edflag) | |
611 | char *block; | |
612 | { | |
613 | int i, ii; | |
614 | register t, j, k; | |
615 | ||
616 | /* | |
617 | * First, permute the bits in the input | |
618 | */ | |
619 | for (j=0; j<64; j++) | |
620 | L[j] = block[IP[j]-1]; | |
621 | /* | |
622 | * Perform an encryption operation 16 times. | |
623 | */ | |
624 | for (ii=0; ii<16; ii++) { | |
625 | /* | |
626 | * Set direction | |
627 | */ | |
628 | if (edflag) | |
629 | i = 15-ii; | |
630 | else | |
631 | i = ii; | |
632 | /* | |
633 | * Save the R array, | |
634 | * which will be the new L. | |
635 | */ | |
636 | for (j=0; j<32; j++) | |
637 | tempL[j] = R[j]; | |
638 | /* | |
639 | * Expand R to 48 bits using the E selector; | |
640 | * exclusive-or with the current key bits. | |
641 | */ | |
642 | for (j=0; j<48; j++) | |
643 | preS[j] = R[E[j]-1] ^ KS[i][j]; | |
644 | /* | |
645 | * The pre-select bits are now considered | |
646 | * in 8 groups of 6 bits each. | |
647 | * The 8 selection functions map these | |
648 | * 6-bit quantities into 4-bit quantities | |
649 | * and the results permuted | |
650 | * to make an f(R, K). | |
651 | * The indexing into the selection functions | |
652 | * is peculiar; it could be simplified by | |
653 | * rewriting the tables. | |
654 | */ | |
655 | for (j=0; j<8; j++) { | |
656 | t = 6*j; | |
657 | k = S[j][(preS[t+0]<<5)+ | |
658 | (preS[t+1]<<3)+ | |
659 | (preS[t+2]<<2)+ | |
660 | (preS[t+3]<<1)+ | |
661 | (preS[t+4]<<0)+ | |
662 | (preS[t+5]<<4)]; | |
663 | t = 4*j; | |
664 | f[t+0] = (k>>3)&01; | |
665 | f[t+1] = (k>>2)&01; | |
666 | f[t+2] = (k>>1)&01; | |
667 | f[t+3] = (k>>0)&01; | |
668 | } | |
669 | /* | |
670 | * The new R is L ^ f(R, K). | |
671 | * The f here has to be permuted first, though. | |
672 | */ | |
673 | for (j=0; j<32; j++) | |
674 | R[j] = L[j] ^ f[P[j]-1]; | |
675 | /* | |
676 | * Finally, the new L (the original R) | |
677 | * is copied back. | |
678 | */ | |
679 | for (j=0; j<32; j++) | |
680 | L[j] = tempL[j]; | |
681 | } | |
682 | /* | |
683 | * The output L and R are reversed. | |
684 | */ | |
685 | for (j=0; j<32; j++) { | |
686 | t = L[j]; | |
687 | L[j] = R[j]; | |
688 | R[j] = t; | |
689 | } | |
690 | /* | |
691 | * The final output | |
692 | * gets the inverse permutation of the very original. | |
693 | */ | |
694 | for (j=0; j<64; j++) | |
695 | block[j] = L[FP[j]-1]; | |
696 | } | |
697 | /* | |
698 | getutmp() | |
699 | return a pointer to the system utmp structure associated with | |
700 | terminal sttyname, e.g. "/dev/tty3" | |
701 | Is version independent-- will work on v6 systems | |
702 | return NULL if error | |
703 | */ | |
704 | static | |
705 | struct utmp *getutmp(sttyname) | |
706 | char *sttyname; | |
707 | { | |
708 | static struct utmp utmpstr; | |
709 | FILE *fdutmp; | |
710 | ||
711 | if(sttyname == NULL || sttyname[0] == 0)return(NULL); | |
712 | ||
713 | fdutmp = fopen("/etc/utmp","r"); | |
714 | if(fdutmp == NULL)return(NULL); | |
715 | ||
716 | while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr) | |
717 | if(strcmp(utmpstr.ut_line,sttyname+5) == 0){ | |
718 | fclose(fdutmp); | |
719 | return(&utmpstr); | |
720 | } | |
721 | fclose(fdutmp); | |
722 | return(NULL); | |
723 | } | |
724 | ||
725 | static | |
726 | sreverse(sto, sfrom) | |
727 | register char *sto, *sfrom; | |
728 | { | |
729 | register int i; | |
730 | ||
731 | i = strlen(sfrom); | |
732 | while (i >= 0) | |
733 | *sto++ = sfrom[i--]; | |
734 | } | |
735 | ||
736 | static | |
737 | char *mkenvkey(mch) | |
738 | char mch; | |
739 | { | |
740 | static char skey[40]; | |
741 | register struct utmp *putmp; | |
742 | char stemp[40], stemp1[40], sttyname[30]; | |
743 | register char *sk,*p; | |
744 | ||
745 | if (isatty(2)) | |
746 | strcpy(sttyname,ttyname(2)); | |
747 | else if (isatty(0)) | |
748 | strcpy(sttyname,ttyname(0)); | |
749 | else if (isatty(1)) | |
750 | strcpy(sttyname,ttyname(1)); | |
751 | else | |
752 | return (NULL); | |
753 | putmp = getutmp(sttyname); | |
754 | if (putmp == NULL) | |
755 | return (NULL); | |
756 | sk = skey; | |
757 | p = putmp->ut_line; | |
758 | while (*p) | |
759 | *sk++ = *p++; | |
760 | *sk++ = mch; | |
761 | sprintf(stemp, "%ld", putmp->ut_time); | |
762 | sreverse(stemp1, stemp); | |
763 | p = stemp1; | |
764 | while (*p) | |
765 | *sk++ = *p++; | |
766 | *sk = 0; | |
767 | return (skey); | |
768 | } | |
769 | ||
770 | mkpwunclear(spasswd,mch,sencpasswd) | |
771 | char mch, *spasswd, *sencpasswd; | |
772 | { | |
773 | register char *skey; | |
774 | ||
775 | if (spasswd[0] == 0) { | |
776 | sencpasswd[0] = 0; | |
777 | return; | |
778 | } | |
779 | skey = mkenvkey(mch); | |
780 | if (skey == NULL) { | |
781 | fprintf(stderr, "Can't make key\n"); | |
782 | exit(1); | |
783 | } | |
784 | nbsencrypt(spasswd, skey, sencpasswd); | |
785 | } | |
786 | ||
787 | mkpwclear(sencpasswd,mch,spasswd) | |
788 | char mch, *spasswd, *sencpasswd; | |
789 | { | |
790 | register char *skey; | |
791 | ||
792 | if (sencpasswd[0] == 0) { | |
793 | spasswd[0] = 0; | |
794 | return; | |
795 | } | |
796 | skey = mkenvkey(mch); | |
797 | if (skey == NULL) { | |
798 | fprintf(stderr, "Can't make key\n"); | |
799 | exit(1); | |
800 | } | |
801 | nbsdecrypt(sencpasswd, skey, spasswd); | |
802 | } |