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