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