xref: /original-bsd/lib/libcompat/4.3/ruserpass.c (revision 18f6d767)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static char sccsid[] = "@(#)ruserpass.c 4.2 10/10/82";
4 
5 #include <stdio.h>
6 #include <utmp.h>
7 #include <ctype.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <errno.h>
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;
132 	extern int errno;
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) {
140 		if (errno != ENOENT)
141 			perror(buf);
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 }
803