129088Smarkm/*-
229088Smarkm * Copyright (c) 1992, 1993
329088Smarkm *	The Regents of the University of California.  All rights reserved.
429088Smarkm *
529088Smarkm * Redistribution and use in source and binary forms, with or without
629088Smarkm * modification, are permitted provided that the following conditions
729088Smarkm * are met:
829088Smarkm * 1. Redistributions of source code must retain the above copyright
929088Smarkm *    notice, this list of conditions and the following disclaimer.
1029088Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1129088Smarkm *    notice, this list of conditions and the following disclaimer in the
1229088Smarkm *    documentation and/or other materials provided with the distribution.
1329088Smarkm * 3. All advertising materials mentioning features or use of this software
1429088Smarkm *    must display the following acknowledgement:
1529088Smarkm *	This product includes software developed by the University of
1629088Smarkm *	California, Berkeley and its contributors.
1729088Smarkm * 4. Neither the name of the University nor the names of its contributors
1829088Smarkm *    may be used to endorse or promote products derived from this software
1929088Smarkm *    without specific prior written permission.
2029088Smarkm *
2129088Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2229088Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2329088Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2429088Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2529088Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2629088Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2729088Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2829088Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2929088Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3029088Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3129088Smarkm * SUCH DAMAGE.
3229088Smarkm */
3329088Smarkm
3484305Smarkm#include <sys/cdefs.h>
3587139Smarkm
3684305Smarkm__FBSDID("$FreeBSD$");
3784305Smarkm
3829088Smarkm#ifndef lint
3929088Smarkmstatic char sccsid[] = "@(#)rsaencpwd.c	8.3 (Berkeley) 5/30/95";
4029088Smarkm#endif /* not lint */
4129088Smarkm
4229088Smarkm
4329088Smarkm#ifdef	RSA_ENCPWD
4429088Smarkm/*
4529088Smarkm * COPYRIGHT (C) 1990 DIGITAL EQUIPMENT CORPORATION
4629088Smarkm * ALL RIGHTS RESERVED
4729088Smarkm *
4829088Smarkm * "Digital Equipment Corporation authorizes the reproduction,
4929088Smarkm * distribution and modification of this software subject to the following
5029088Smarkm * restrictions:
5129088Smarkm *
5229088Smarkm * 1.  Any partial or whole copy of this software, or any modification
5329088Smarkm * thereof, must include this copyright notice in its entirety.
5429088Smarkm *
5529088Smarkm * 2.  This software is supplied "as is" with no warranty of any kind,
5629088Smarkm * expressed or implied, for any purpose, including any warranty of fitness
5729088Smarkm * or merchantibility.  DIGITAL assumes no responsibility for the use or
5829088Smarkm * reliability of this software, nor promises to provide any form of
5929088Smarkm * support for it on any basis.
6029088Smarkm *
6129088Smarkm * 3.  Distribution of this software is authorized only if no profit or
6229088Smarkm * remuneration of any kind is received in exchange for such distribution.
6329088Smarkm *
6429088Smarkm * 4.  This software produces public key authentication certificates
6529088Smarkm * bearing an expiration date established by DIGITAL and RSA Data
6629088Smarkm * Security, Inc.  It may cease to generate certificates after the expiration
6729088Smarkm * date.  Any modification of this software that changes or defeats
6829088Smarkm * the expiration date or its effect is unauthorized.
6929088Smarkm *
7029088Smarkm * 5.  Software that will renew or extend the expiration date of
7129088Smarkm * authentication certificates produced by this software may be obtained
7229088Smarkm * from RSA Data Security, Inc., 10 Twin Dolphin Drive, Redwood City, CA
7329088Smarkm * 94065, (415)595-8782, or from DIGITAL"
7429088Smarkm *
7529088Smarkm */
7629088Smarkm
7729088Smarkm#include <sys/types.h>
7829088Smarkm#include <arpa/telnet.h>
7929088Smarkm#include <pwd.h>
8029088Smarkm#include <stdio.h>
8129088Smarkm#include <stdlib.h>
8229088Smarkm#include <string.h>
8329088Smarkm
8429088Smarkm#include "encrypt.h"
8529088Smarkm#include "auth.h"
8629088Smarkm#include "misc.h"
8729088Smarkm#include "cdc.h"
8829088Smarkm
8929088Smarkmextern auth_debug_mode;
9029088Smarkm
9129088Smarkmstatic unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
9229088Smarkm			  		AUTHTYPE_RSA_ENCPWD, };
9329088Smarkmstatic unsigned char str_name[1024] = { IAC, SB, TELOPT_AUTHENTICATION,
9429088Smarkm					TELQUAL_NAME, };
9529088Smarkm
9629088Smarkm#define	RSA_ENCPWD_AUTH	0	/* Authentication data follows */
9729088Smarkm#define	RSA_ENCPWD_REJECT	1	/* Rejected (reason might follow) */
9829088Smarkm#define RSA_ENCPWD_ACCEPT	2	/* Accepted */
9929088Smarkm#define	RSA_ENCPWD_CHALLENGEKEY	3	/* Challenge and public key */
10029088Smarkm
10129088Smarkm#define NAME_SZ   40
10229088Smarkm#define CHAL_SZ   20
10329088Smarkm#define PWD_SZ    40
10429088Smarkm
10529088Smarkmstatic	KTEXT_ST auth;
10629088Smarkmstatic	char name[NAME_SZ];
10729088Smarkmstatic	char user_passwd[PWD_SZ];
10829088Smarkmstatic  char key_file[2*NAME_SZ];
10929088Smarkmstatic  char lhostname[NAME_SZ];
11029088Smarkmstatic char  challenge[CHAL_SZ];
11129088Smarkmstatic int   challenge_len;
11229088Smarkm
11329088Smarkm	static int
11429088SmarkmData(ap, type, d, c)
11529088Smarkm	Authenticator *ap;
11629088Smarkm	int type;
11729088Smarkm	void *d;
11829088Smarkm	int c;
11929088Smarkm{
12029088Smarkm	unsigned char *p = str_data + 4;
12129088Smarkm	unsigned char *cd = (unsigned char *)d;
12229088Smarkm
12329088Smarkm	if (c == -1)
12429088Smarkm		c = strlen((char *)cd);
12529088Smarkm
12629088Smarkm	if (0) {
12729088Smarkm		printf("%s:%d: [%d] (%d)",
12829088Smarkm			str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
12929088Smarkm			str_data[3],
13029088Smarkm			type, c);
13129088Smarkm		printd(d, c);
13229088Smarkm		printf("\r\n");
13329088Smarkm	}
13429088Smarkm	*p++ = ap->type;
13529088Smarkm	*p++ = ap->way;
13629088Smarkm	if (type != NULL) *p++ = type;
13729088Smarkm	while (c-- > 0) {
13829088Smarkm		if ((*p++ = *cd++) == IAC)
13929088Smarkm			*p++ = IAC;
14029088Smarkm	}
14129088Smarkm	*p++ = IAC;
14229088Smarkm	*p++ = SE;
14329088Smarkm	if (str_data[3] == TELQUAL_IS)
14429088Smarkm		printsub('>', &str_data[2], p - (&str_data[2]));
14529088Smarkm	return(net_write(str_data, p - str_data));
14629088Smarkm}
14729088Smarkm
14829088Smarkm	int
14929088Smarkmrsaencpwd_init(ap, server)
15029088Smarkm	Authenticator *ap;
15129088Smarkm	int server;
15229088Smarkm{
15329088Smarkm	char  *cp;
15429088Smarkm	FILE  *fp;
15529088Smarkm
15629088Smarkm	if (server) {
15729088Smarkm		str_data[3] = TELQUAL_REPLY;
15829088Smarkm		memset(key_file, 0, sizeof(key_file));
15929088Smarkm		gethostname(lhostname, sizeof(lhostname));
16029088Smarkm		if ((cp = strchr(lhostname, '.')) != 0)  *cp = '\0';
16129088Smarkm		strcpy(key_file, "/etc/.");
16229088Smarkm		strcat(key_file, lhostname);
16329088Smarkm		strcat(key_file, "_privkey");
16429088Smarkm		if ((fp=fopen(key_file, "r"))==NULL) return(0);
16529088Smarkm		fclose(fp);
16629088Smarkm	} else {
16729088Smarkm		str_data[3] = TELQUAL_IS;
16829088Smarkm	}
16929088Smarkm	return(1);
17029088Smarkm}
17129088Smarkm
17229088Smarkm	int
17329088Smarkmrsaencpwd_send(ap)
17429088Smarkm	Authenticator *ap;
17529088Smarkm{
17629088Smarkm
17729088Smarkm	printf("[ Trying RSAENCPWD ... ]\n");
17829088Smarkm	if (!UserNameRequested) {
17929088Smarkm		return(0);
18029088Smarkm	}
18129088Smarkm	if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
18229088Smarkm		return(0);
18329088Smarkm	}
18429088Smarkm	if (!Data(ap, NULL, (void *)NULL, 0)) {
18529088Smarkm		return(0);
18629088Smarkm	}
18729088Smarkm
18829088Smarkm
18929088Smarkm	return(1);
19029088Smarkm}
19129088Smarkm
19229088Smarkm	void
19329088Smarkmrsaencpwd_is(ap, data, cnt)
19429088Smarkm	Authenticator *ap;
19529088Smarkm	unsigned char *data;
19629088Smarkm	int cnt;
19729088Smarkm{
19829088Smarkm	Session_Key skey;
19929088Smarkm	Block datablock;
20029088Smarkm	char  r_passwd[PWD_SZ], r_user[NAME_SZ];
20129088Smarkm	char  *cp, key[160];
20229088Smarkm	char  chalkey[160], *ptr;
20329088Smarkm	FILE  *fp;
20429088Smarkm	int r, i, j, chalkey_len, len;
20529088Smarkm	time_t now;
20629088Smarkm
20729088Smarkm	cnt--;
20829088Smarkm	switch (*data++) {
20929088Smarkm	case RSA_ENCPWD_AUTH:
21029088Smarkm		memmove((void *)auth.dat, (void *)data, auth.length = cnt);
21129088Smarkm
21229088Smarkm		if ((fp=fopen(key_file, "r"))==NULL) {
21329088Smarkm		  Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
21429088Smarkm		  auth_finished(ap, AUTH_REJECT);
21529088Smarkm		  return;
21629088Smarkm		}
21729088Smarkm		/*
21829088Smarkm		 *  get privkey
21929088Smarkm		 */
22029088Smarkm		fscanf(fp, "%x;", &len);
22129088Smarkm		for (i=0;i<len;i++) {
22229088Smarkm		  j = getc(fp);  key[i]=j;
22329088Smarkm		}
22429088Smarkm		fclose(fp);
22529088Smarkm
22629088Smarkm		r = accept_rsa_encpwd(&auth, key, challenge,
22729088Smarkm				      challenge_len, r_passwd);
22829088Smarkm		if (r < 0) {
22929088Smarkm		  Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
23029088Smarkm		  auth_finished(ap, AUTH_REJECT);
23129088Smarkm		  return;
23229088Smarkm		}
23329088Smarkm		auth_encrypt_userpwd(r_passwd);
23429088Smarkm		if (rsaencpwd_passwdok(UserNameRequested, UserPassword) == 0) {
23529088Smarkm		  /*
23629088Smarkm		   *  illegal username and password
23729088Smarkm		   */
23829088Smarkm		  Data(ap, RSA_ENCPWD_REJECT, (void *)"Illegal password", -1);
23929088Smarkm		  auth_finished(ap, AUTH_REJECT);
24029088Smarkm		  return;
24129088Smarkm		}
24229088Smarkm
24329088Smarkm		Data(ap, RSA_ENCPWD_ACCEPT, (void *)0, 0);
24429088Smarkm		auth_finished(ap, AUTH_USER);
24529088Smarkm		break;
24629088Smarkm
24729088Smarkm
24829088Smarkm	case IAC:
24929088Smarkm
25029088Smarkm		/*
25129088Smarkm		 * If we are doing mutual authentication, get set up to send
25229088Smarkm		 * the challenge, and verify it when the response comes back.
25329088Smarkm		 */
25429088Smarkm		if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_ONE_WAY) {
25529088Smarkm		  register int i;
25629088Smarkm
25729088Smarkm
25829088Smarkm		  time(&now);
25929088Smarkm		  if ((now % 2) == 0) {
26029088Smarkm		    sprintf(challenge, "%x", now);
26129088Smarkm		    challenge_len = strlen(challenge);
26229088Smarkm		  } else {
26329088Smarkm		    strcpy(challenge, "randchal");
26429088Smarkm		    challenge_len = 8;
26529088Smarkm		  }
26629088Smarkm
26729088Smarkm		  if ((fp=fopen(key_file, "r"))==NULL) {
26829088Smarkm		    Data(ap, RSA_ENCPWD_REJECT, (void *)"Auth failed", -1);
26929088Smarkm		    auth_finished(ap, AUTH_REJECT);
27029088Smarkm		    return;
27129088Smarkm		  }
27229088Smarkm		  /*
27329088Smarkm		   *  skip privkey
27429088Smarkm		   */
27529088Smarkm		  fscanf(fp, "%x;", &len);
27629088Smarkm		  for (i=0;i<len;i++) {
27729088Smarkm		    j = getc(fp);
27829088Smarkm		  }
27929088Smarkm		  /*
28029088Smarkm		   * get pubkey
28129088Smarkm		   */
28229088Smarkm		  fscanf(fp, "%x;", &len);
28329088Smarkm		  for (i=0;i<len;i++) {
28429088Smarkm		    j = getc(fp);  key[i]=j;
28529088Smarkm		  }
28629088Smarkm		  fclose(fp);
28729088Smarkm		  chalkey[0] = 0x30;
28829088Smarkm		  ptr = (char *) &chalkey[1];
28929088Smarkm		  chalkey_len = 1+NumEncodeLengthOctets(i)+i+1+NumEncodeLengthOctets(challenge_len)+challenge_len;
29029088Smarkm		  EncodeLength(ptr, chalkey_len);
29129088Smarkm		  ptr +=NumEncodeLengthOctets(chalkey_len);
29229088Smarkm		  *ptr++ = 0x04;  /* OCTET STRING */
29329088Smarkm		  *ptr++ = challenge_len;
29429088Smarkm		  memmove(ptr, challenge, challenge_len);
29529088Smarkm		  ptr += challenge_len;
29629088Smarkm		  *ptr++ = 0x04;  /* OCTET STRING */
29729088Smarkm		  EncodeLength(ptr, i);
29829088Smarkm		  ptr += NumEncodeLengthOctets(i);
29929088Smarkm		  memmove(ptr, key, i);
30029088Smarkm		  chalkey_len = 1+NumEncodeLengthOctets(chalkey_len)+chalkey_len;
30129088Smarkm		  Data(ap, RSA_ENCPWD_CHALLENGEKEY, (void *)chalkey, chalkey_len);
30229088Smarkm		}
30329088Smarkm		break;
30429088Smarkm
30529088Smarkm	default:
30629088Smarkm		Data(ap, RSA_ENCPWD_REJECT, 0, 0);
30729088Smarkm		break;
30829088Smarkm	}
30929088Smarkm}
31029088Smarkm
31129088Smarkm
31229088Smarkm	void
31329088Smarkmrsaencpwd_reply(ap, data, cnt)
31429088Smarkm	Authenticator *ap;
31529088Smarkm	unsigned char *data;
31629088Smarkm	int cnt;
31729088Smarkm{
31829088Smarkm	Session_Key skey;
31929088Smarkm	KTEXT_ST token;
32029088Smarkm	Block enckey;
32129088Smarkm	int r, pubkey_len;
32229088Smarkm	char	randchal[CHAL_SZ], *cp;
32329088Smarkm	char	chalkey[160], pubkey[128], *ptr;
32429088Smarkm
32529088Smarkm	if (cnt-- < 1)
32629088Smarkm		return;
32729088Smarkm	switch (*data++) {
32829088Smarkm	case RSA_ENCPWD_REJECT:
32929088Smarkm		if (cnt > 0) {
33029088Smarkm			printf("[ RSA_ENCPWD refuses authentication because %.*s ]\r\n",
33129088Smarkm				cnt, data);
33229088Smarkm		} else
33329088Smarkm			printf("[ RSA_ENCPWD refuses authentication ]\r\n");
33429088Smarkm		auth_send_retry();
33529088Smarkm		return;
33629088Smarkm	case RSA_ENCPWD_ACCEPT:
33729088Smarkm		printf("[ RSA_ENCPWD accepts you ]\n");
33829088Smarkm		auth_finished(ap, AUTH_USER);
33929088Smarkm		return;
34029088Smarkm	case RSA_ENCPWD_CHALLENGEKEY:
34129088Smarkm		/*
34229088Smarkm		 * Verify that the response to the challenge is correct.
34329088Smarkm		 */
34429088Smarkm
34529088Smarkm		memmove((void *)chalkey, (void *)data, cnt);
34629088Smarkm		ptr = (char *) &chalkey[0];
34729088Smarkm		ptr += DecodeHeaderLength(chalkey);
34829088Smarkm		if (*ptr != 0x04) {
34929088Smarkm		  return;
35029088Smarkm		}
35129088Smarkm		*ptr++;
35229088Smarkm		challenge_len = DecodeValueLength(ptr);
35329088Smarkm		ptr += NumEncodeLengthOctets(challenge_len);
35429088Smarkm		memmove(challenge, ptr, challenge_len);
35529088Smarkm		ptr += challenge_len;
35629088Smarkm		if (*ptr != 0x04) {
35729088Smarkm		  return;
35829088Smarkm		}
35929088Smarkm		*ptr++;
36029088Smarkm		pubkey_len = DecodeValueLength(ptr);
36129088Smarkm		ptr += NumEncodeLengthOctets(pubkey_len);
36229088Smarkm		memmove(pubkey, ptr, pubkey_len);
36329088Smarkm		memset(user_passwd, 0, sizeof(user_passwd));
36429088Smarkm		local_des_read_pw_string(user_passwd, sizeof(user_passwd)-1, "Password: ", 0);
36529088Smarkm		UserPassword = user_passwd;
36629088Smarkm		Challenge = challenge;
36729088Smarkm		r = init_rsa_encpwd(&token, user_passwd, challenge, challenge_len, pubkey);
36829088Smarkm		if (r < 0) {
36929088Smarkm		  token.length = 1;
37029088Smarkm		}
37129088Smarkm
37229088Smarkm		if (!Data(ap, RSA_ENCPWD_AUTH, (void *)token.dat, token.length)) {
37329088Smarkm		  return;
37429088Smarkm		}
37529088Smarkm
37629088Smarkm		break;
37729088Smarkm
37829088Smarkm	default:
37929088Smarkm		return;
38029088Smarkm	}
38129088Smarkm}
38229088Smarkm
38329088Smarkm	int
38429088Smarkmrsaencpwd_status(ap, name, level)
38529088Smarkm	Authenticator *ap;
38629088Smarkm	char *name;
38729088Smarkm	int level;
38829088Smarkm{
38929088Smarkm
39029088Smarkm	if (level < AUTH_USER)
39129088Smarkm		return(level);
39229088Smarkm
39329088Smarkm	if (UserNameRequested && rsaencpwd_passwdok(UserNameRequested, UserPassword)) {
39429088Smarkm		strcpy(name, UserNameRequested);
39529088Smarkm		return(AUTH_VALID);
39629088Smarkm	} else {
39729088Smarkm		return(AUTH_USER);
39829088Smarkm	}
39929088Smarkm}
40029088Smarkm
40129088Smarkm#define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
40229088Smarkm#define	ADDC(buf, len, c)	if ((len) > 0) {*(buf)++ = (c); --(len);}
40329088Smarkm
40429088Smarkm	void
40529088Smarkmrsaencpwd_printsub(data, cnt, buf, buflen)
40629088Smarkm	unsigned char *data, *buf;
40729088Smarkm	int cnt, buflen;
40829088Smarkm{
40929088Smarkm	char lbuf[32];
41029088Smarkm	register int i;
41129088Smarkm
41229088Smarkm	buf[buflen-1] = '\0';		/* make sure its NULL terminated */
41329088Smarkm	buflen -= 1;
41429088Smarkm
41529088Smarkm	switch(data[3]) {
41629088Smarkm	case RSA_ENCPWD_REJECT:	/* Rejected (reason might follow) */
41729088Smarkm		strncpy((char *)buf, " REJECT ", buflen);
41829088Smarkm		goto common;
41929088Smarkm
42029088Smarkm	case RSA_ENCPWD_ACCEPT:	/* Accepted (name might follow) */
42129088Smarkm		strncpy((char *)buf, " ACCEPT ", buflen);
42229088Smarkm	common:
42329088Smarkm		BUMP(buf, buflen);
42429088Smarkm		if (cnt <= 4)
42529088Smarkm			break;
42629088Smarkm		ADDC(buf, buflen, '"');
42729088Smarkm		for (i = 4; i < cnt; i++)
42829088Smarkm			ADDC(buf, buflen, data[i]);
42929088Smarkm		ADDC(buf, buflen, '"');
43029088Smarkm		ADDC(buf, buflen, '\0');
43129088Smarkm		break;
43229088Smarkm
43329088Smarkm	case RSA_ENCPWD_AUTH:		/* Authentication data follows */
43429088Smarkm		strncpy((char *)buf, " AUTH", buflen);
43529088Smarkm		goto common2;
43629088Smarkm
43729088Smarkm	case RSA_ENCPWD_CHALLENGEKEY:
43829088Smarkm		strncpy((char *)buf, " CHALLENGEKEY", buflen);
43929088Smarkm		goto common2;
44029088Smarkm
44129088Smarkm	default:
44229088Smarkm		sprintf(lbuf, " %d (unknown)", data[3]);
44329088Smarkm		strncpy((char *)buf, lbuf, buflen);
44429088Smarkm	common2:
44529088Smarkm		BUMP(buf, buflen);
44629088Smarkm		for (i = 4; i < cnt; i++) {
44729088Smarkm			sprintf(lbuf, " %d", data[i]);
44829088Smarkm			strncpy((char *)buf, lbuf, buflen);
44929088Smarkm			BUMP(buf, buflen);
45029088Smarkm		}
45129088Smarkm		break;
45229088Smarkm	}
45329088Smarkm}
45429088Smarkm
45529088Smarkmint rsaencpwd_passwdok(name, passwd)
45629088Smarkmchar *name, *passwd;
45729088Smarkm{
45829088Smarkm  char *crypt();
45929088Smarkm  char *salt, *p;
46029088Smarkm  struct passwd *pwd;
46129088Smarkm  int   passwdok_status = 0;
46229088Smarkm
46329088Smarkm  if (pwd = getpwnam(name))
46429088Smarkm    salt = pwd->pw_passwd;
46529088Smarkm  else salt = "xx";
46629088Smarkm
46729088Smarkm  p = crypt(passwd, salt);
46829088Smarkm
46929088Smarkm  if (pwd && !strcmp(p, pwd->pw_passwd)) {
47029088Smarkm    passwdok_status = 1;
47129088Smarkm  } else passwdok_status = 0;
47229088Smarkm  return(passwdok_status);
47329088Smarkm}
47429088Smarkm
47529088Smarkm#endif
476