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