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