kerberos.c revision 57442
129088Smarkm/*-
229088Smarkm * Copyright (c) 1991, 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.
3257442Smarkm *
3357442Smarkm * $FreeBSD: head/contrib/telnet/libtelnet/kerberos.c 57442 2000-02-24 19:28:31Z markm $
3429088Smarkm */
3529088Smarkm
3629088Smarkm#ifndef lint
3729181Smarkmstatic const char sccsid[] = "@(#)kerberos.c	8.3 (Berkeley) 5/30/95";
3829088Smarkm#endif /* not lint */
3929088Smarkm
4029088Smarkm/*
4129088Smarkm * Copyright (C) 1990 by the Massachusetts Institute of Technology
4229088Smarkm *
4329088Smarkm * Export of this software from the United States of America is assumed
4429088Smarkm * to require a specific license from the United States Government.
4529088Smarkm * It is the responsibility of any person or organization contemplating
4629088Smarkm * export to obtain such a license before exporting.
4729088Smarkm *
4829088Smarkm * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
4929088Smarkm * distribute this software and its documentation for any purpose and
5029088Smarkm * without fee is hereby granted, provided that the above copyright
5129088Smarkm * notice appear in all copies and that both that copyright notice and
5229088Smarkm * this permission notice appear in supporting documentation, and that
5329088Smarkm * the name of M.I.T. not be used in advertising or publicity pertaining
5429088Smarkm * to distribution of the software without specific, written prior
5529088Smarkm * permission.  M.I.T. makes no representations about the suitability of
5629088Smarkm * this software for any purpose.  It is provided "as is" without express
5729088Smarkm * or implied warranty.
5829088Smarkm */
5929088Smarkm
6029088Smarkm#ifdef	KRB4
6129088Smarkm#include <sys/types.h>
6229088Smarkm#include <arpa/telnet.h>
6329088Smarkm#include <stdio.h>
6457442Smarkm#include <openssl/des.h>	/* BSD wont include this in krb.h, so we do it here */
6529088Smarkm#include <krb.h>
6629088Smarkm#ifdef	__STDC__
6729088Smarkm#include <stdlib.h>
6829088Smarkm#endif
6929088Smarkm#ifdef	NO_STRING_H
7029088Smarkm#include <strings.h>
7129088Smarkm#else
7229088Smarkm#include <string.h>
7329088Smarkm#endif
7429088Smarkm
7529088Smarkm#include "encrypt.h"
7629088Smarkm#include "auth.h"
7729088Smarkm#include "misc.h"
7829088Smarkm
7929088Smarkmint kerberos4_cksum P((unsigned char *, int));
8029088Smarkmint kuserok P((AUTH_DAT *, char *));
8129088Smarkm
8229088Smarkmextern auth_debug_mode;
8329088Smarkm
8429088Smarkmstatic unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
8529088Smarkm			  		AUTHTYPE_KERBEROS_V4, };
8629088Smarkm
8729088Smarkm#define	KRB_AUTH	0		/* Authentication data follows */
8829088Smarkm#define	KRB_REJECT	1		/* Rejected (reason might follow) */
8929088Smarkm#define	KRB_ACCEPT	2		/* Accepted */
9029088Smarkm#define	KRB_CHALLENGE	3		/* Challenge for mutual auth. */
9129088Smarkm#define	KRB_RESPONSE	4		/* Response for mutual auth. */
9229088Smarkm
9329088Smarkm#define KRB_SERVICE_NAME   "rcmd"
9429088Smarkm
9529088Smarkmstatic	KTEXT_ST auth;
9629088Smarkmstatic	char name[ANAME_SZ];
9729088Smarkmstatic	AUTH_DAT adat = { 0 };
9829088Smarkm#ifdef	ENCRYPTION
9929088Smarkmstatic Block	session_key	= { 0 };
10029181Smarkmstatic des_key_schedule sched;
10129088Smarkmstatic Block	challenge	= { 0 };
10229088Smarkm#endif	/* ENCRYPTION */
10329088Smarkm
10429088Smarkm	static int
10529088SmarkmData(ap, type, d, c)
10629088Smarkm	Authenticator *ap;
10729088Smarkm	int type;
10829088Smarkm	void *d;
10929088Smarkm	int c;
11029088Smarkm{
11129088Smarkm	unsigned char *p = str_data + 4;
11229088Smarkm	unsigned char *cd = (unsigned char *)d;
11329088Smarkm
11429088Smarkm	if (c == -1)
11529088Smarkm		c = strlen((char *)cd);
11629088Smarkm
11729088Smarkm	if (auth_debug_mode) {
11829088Smarkm		printf("%s:%d: [%d] (%d)",
11929088Smarkm			str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
12029088Smarkm			str_data[3],
12129088Smarkm			type, c);
12229088Smarkm		printd(d, c);
12329088Smarkm		printf("\r\n");
12429088Smarkm	}
12529088Smarkm	*p++ = ap->type;
12629088Smarkm	*p++ = ap->way;
12729088Smarkm	*p++ = type;
12829088Smarkm	while (c-- > 0) {
12929088Smarkm		if ((*p++ = *cd++) == IAC)
13029088Smarkm			*p++ = IAC;
13129088Smarkm	}
13229088Smarkm	*p++ = IAC;
13329088Smarkm	*p++ = SE;
13429088Smarkm	if (str_data[3] == TELQUAL_IS)
13529088Smarkm		printsub('>', &str_data[2], p - (&str_data[2]));
13629088Smarkm	return(net_write(str_data, p - str_data));
13729088Smarkm}
13829088Smarkm
13929088Smarkm	int
14029088Smarkmkerberos4_init(ap, server)
14129088Smarkm	Authenticator *ap;
14229088Smarkm	int server;
14329088Smarkm{
14429088Smarkm	FILE *fp;
14529088Smarkm
14629088Smarkm	if (server) {
14729088Smarkm		str_data[3] = TELQUAL_REPLY;
14829088Smarkm		if ((fp = fopen(KEYFILE, "r")) == NULL)
14929088Smarkm			return(0);
15029088Smarkm		fclose(fp);
15129088Smarkm	} else {
15229088Smarkm		str_data[3] = TELQUAL_IS;
15329088Smarkm	}
15429088Smarkm	return(1);
15529088Smarkm}
15629088Smarkm
15729088Smarkmchar dst_realm_buf[REALM_SZ], *dest_realm = NULL;
15829088Smarkmint dst_realm_sz = REALM_SZ;
15929088Smarkm
16029088Smarkm	int
16129088Smarkmkerberos4_send(ap)
16229088Smarkm	Authenticator *ap;
16329088Smarkm{
16429088Smarkm	KTEXT_ST auth;
16529088Smarkm	char instance[INST_SZ];
16629088Smarkm	char *realm;
16729088Smarkm	char *krb_realmofhost();
16829088Smarkm	char *krb_get_phost();
16929088Smarkm	CREDENTIALS cred;
17029088Smarkm	int r;
17129088Smarkm
17229088Smarkm	printf("[ Trying KERBEROS4 ... ]\n");
17329088Smarkm	if (!UserNameRequested) {
17429088Smarkm		if (auth_debug_mode) {
17529088Smarkm			printf("Kerberos V4: no user name supplied\r\n");
17629088Smarkm		}
17729088Smarkm		return(0);
17829088Smarkm	}
17929088Smarkm
18029088Smarkm	memset(instance, 0, sizeof(instance));
18129088Smarkm
18229181Smarkm	if ((realm = krb_get_phost(RemoteHostName)))
18329088Smarkm		strncpy(instance, realm, sizeof(instance));
18429088Smarkm
18529088Smarkm	instance[sizeof(instance)-1] = '\0';
18629088Smarkm
18729088Smarkm	realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName);
18829088Smarkm
18929088Smarkm	if (!realm) {
19029088Smarkm		printf("Kerberos V4: no realm for %s\r\n", RemoteHostName);
19129088Smarkm		return(0);
19229088Smarkm	}
19329181Smarkm	if ((r = krb_mk_req(&auth, KRB_SERVICE_NAME, instance, realm, 0L))) {
19429088Smarkm		printf("mk_req failed: %s\r\n", krb_err_txt[r]);
19529088Smarkm		return(0);
19629088Smarkm	}
19729181Smarkm	if ((r = krb_get_cred(KRB_SERVICE_NAME, instance, realm, &cred))) {
19829088Smarkm		printf("get_cred failed: %s\r\n", krb_err_txt[r]);
19929088Smarkm		return(0);
20029088Smarkm	}
20129088Smarkm	if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
20229088Smarkm		if (auth_debug_mode)
20329088Smarkm			printf("Not enough room for user name\r\n");
20429088Smarkm		return(0);
20529088Smarkm	}
20629088Smarkm	if (auth_debug_mode)
20729088Smarkm		printf("Sent %d bytes of authentication data\r\n", auth.length);
20829088Smarkm	if (!Data(ap, KRB_AUTH, (void *)auth.dat, auth.length)) {
20929088Smarkm		if (auth_debug_mode)
21029088Smarkm			printf("Not enough room for authentication data\r\n");
21129088Smarkm		return(0);
21229088Smarkm	}
21329088Smarkm#ifdef	ENCRYPTION
21429088Smarkm	/*
21529088Smarkm	 * If we are doing mutual authentication, get set up to send
21629088Smarkm	 * the challenge, and verify it when the response comes back.
21729088Smarkm	 */
21829088Smarkm	if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
21929088Smarkm		register int i;
22029088Smarkm
22129181Smarkm		des_key_sched(&cred.session, sched);
22229181Smarkm		des_init_random_number_generator(&cred.session);
22329181Smarkm		des_new_random_key(&session_key);
22429181Smarkm		des_ecb_encrypt(&session_key, &session_key, sched, 0);
22529181Smarkm		des_ecb_encrypt(&session_key, &challenge, sched, 0);
22629088Smarkm		/*
22729088Smarkm		 * Increment the challenge by 1, and encrypt it for
22829088Smarkm		 * later comparison.
22929088Smarkm		 */
23029088Smarkm		for (i = 7; i >= 0; --i) {
23129088Smarkm			register int x;
23229088Smarkm			x = (unsigned int)challenge[i] + 1;
23329088Smarkm			challenge[i] = x;	/* ignore overflow */
23429088Smarkm			if (x < 256)		/* if no overflow, all done */
23529088Smarkm				break;
23629088Smarkm		}
23729181Smarkm		des_ecb_encrypt(&challenge, &challenge, sched, 1);
23829088Smarkm	}
23929088Smarkm#endif	/* ENCRYPTION */
24029088Smarkm
24129088Smarkm	if (auth_debug_mode) {
24229088Smarkm		printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
24329088Smarkm		printd(auth.dat, auth.length);
24429088Smarkm		printf("\r\n");
24529088Smarkm		printf("Sent Kerberos V4 credentials to server\r\n");
24629088Smarkm	}
24729088Smarkm	return(1);
24829088Smarkm}
24929088Smarkm
25029088Smarkm	void
25129088Smarkmkerberos4_is(ap, data, cnt)
25229088Smarkm	Authenticator *ap;
25329088Smarkm	unsigned char *data;
25429088Smarkm	int cnt;
25529088Smarkm{
25629088Smarkm#ifdef	ENCRYPTION
25729088Smarkm	Session_Key skey;
25829088Smarkm	Block datablock;
25929088Smarkm#endif	/* ENCRYPTION */
26029088Smarkm	char realm[REALM_SZ];
26129088Smarkm	char instance[INST_SZ];
26229088Smarkm	int r;
26329088Smarkm
26429088Smarkm	if (cnt-- < 1)
26529088Smarkm		return;
26629088Smarkm	switch (*data++) {
26729088Smarkm	case KRB_AUTH:
26829088Smarkm		if (krb_get_lrealm(realm, 1) != KSUCCESS) {
26929088Smarkm			Data(ap, KRB_REJECT, (void *)"No local V4 Realm.", -1);
27029088Smarkm			auth_finished(ap, AUTH_REJECT);
27129088Smarkm			if (auth_debug_mode)
27229088Smarkm				printf("No local realm\r\n");
27329088Smarkm			return;
27429088Smarkm		}
27529088Smarkm		memmove((void *)auth.dat, (void *)data, auth.length = cnt);
27629088Smarkm		if (auth_debug_mode) {
27729088Smarkm			printf("Got %d bytes of authentication data\r\n", cnt);
27829088Smarkm			printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
27929088Smarkm			printd(auth.dat, auth.length);
28029088Smarkm			printf("\r\n");
28129088Smarkm		}
28229088Smarkm		instance[0] = '*'; instance[1] = 0;
28329181Smarkm		if ((r = krb_rd_req(&auth, KRB_SERVICE_NAME,
28429181Smarkm				   instance, 0, &adat, ""))) {
28529088Smarkm			if (auth_debug_mode)
28629088Smarkm				printf("Kerberos failed him as %s\r\n", name);
28729088Smarkm			Data(ap, KRB_REJECT, (void *)krb_err_txt[r], -1);
28829088Smarkm			auth_finished(ap, AUTH_REJECT);
28929088Smarkm			return;
29029088Smarkm		}
29129088Smarkm#ifdef	ENCRYPTION
29229088Smarkm		memmove((void *)session_key, (void *)adat.session, sizeof(Block));
29329088Smarkm#endif	/* ENCRYPTION */
29429088Smarkm		krb_kntoln(&adat, name);
29529088Smarkm
29629088Smarkm		if (UserNameRequested && !kuserok(&adat, UserNameRequested))
29729088Smarkm			Data(ap, KRB_ACCEPT, (void *)0, 0);
29829088Smarkm		else
29929088Smarkm			Data(ap, KRB_REJECT,
30029088Smarkm				(void *)"user is not authorized", -1);
30129088Smarkm		auth_finished(ap, AUTH_USER);
30229088Smarkm		break;
30329088Smarkm
30429088Smarkm	case KRB_CHALLENGE:
30529088Smarkm#ifndef	ENCRYPTION
30629088Smarkm		Data(ap, KRB_RESPONSE, (void *)0, 0);
30729088Smarkm#else	/* ENCRYPTION */
30829088Smarkm		if (!VALIDKEY(session_key)) {
30929088Smarkm			/*
31029088Smarkm			 * We don't have a valid session key, so just
31129088Smarkm			 * send back a response with an empty session
31229088Smarkm			 * key.
31329088Smarkm			 */
31429088Smarkm			Data(ap, KRB_RESPONSE, (void *)0, 0);
31529088Smarkm			break;
31629088Smarkm		}
31729088Smarkm
31829088Smarkm		/*
31929088Smarkm		 * Initialize the random number generator since it's
32029088Smarkm		 * used later on by the encryption routine.
32129088Smarkm		 */
32229181Smarkm		des_init_random_number_generator(&session_key);
32329181Smarkm		des_key_sched(&session_key, sched);
32429088Smarkm		memmove((void *)datablock, (void *)data, sizeof(Block));
32529088Smarkm		/*
32629088Smarkm		 * Take the received encrypted challenge, and encrypt
32729088Smarkm		 * it again to get a unique session_key for the
32829088Smarkm		 * ENCRYPT option.
32929088Smarkm		 */
33029181Smarkm		des_ecb_encrypt(&datablock, &session_key, sched, 1);
33129088Smarkm		skey.type = SK_DES;
33229088Smarkm		skey.length = 8;
33329088Smarkm		skey.data = session_key;
33429088Smarkm		encrypt_session_key(&skey, 1);
33529088Smarkm		/*
33629088Smarkm		 * Now decrypt the received encrypted challenge,
33729088Smarkm		 * increment by one, re-encrypt it and send it back.
33829088Smarkm		 */
33929181Smarkm		des_ecb_encrypt(&datablock, &challenge, sched, 0);
34029088Smarkm		for (r = 7; r >= 0; r--) {
34129088Smarkm			register int t;
34229088Smarkm			t = (unsigned int)challenge[r] + 1;
34329088Smarkm			challenge[r] = t;	/* ignore overflow */
34429088Smarkm			if (t < 256)		/* if no overflow, all done */
34529088Smarkm				break;
34629088Smarkm		}
34729181Smarkm		des_ecb_encrypt(&challenge, &challenge, sched, 1);
34829088Smarkm		Data(ap, KRB_RESPONSE, (void *)challenge, sizeof(challenge));
34929088Smarkm#endif	/* ENCRYPTION */
35029088Smarkm		break;
35129088Smarkm
35229088Smarkm	default:
35329088Smarkm		if (auth_debug_mode)
35429088Smarkm			printf("Unknown Kerberos option %d\r\n", data[-1]);
35529088Smarkm		Data(ap, KRB_REJECT, 0, 0);
35629088Smarkm		break;
35729088Smarkm	}
35829088Smarkm}
35929088Smarkm
36029088Smarkm	void
36129088Smarkmkerberos4_reply(ap, data, cnt)
36229088Smarkm	Authenticator *ap;
36329088Smarkm	unsigned char *data;
36429088Smarkm	int cnt;
36529088Smarkm{
36629088Smarkm#ifdef	ENCRYPTION
36729088Smarkm	Session_Key skey;
36829088Smarkm#endif	/* ENCRYPTION */
36929088Smarkm
37029088Smarkm	if (cnt-- < 1)
37129088Smarkm		return;
37229088Smarkm	switch (*data++) {
37329088Smarkm	case KRB_REJECT:
37429088Smarkm		if (cnt > 0) {
37529088Smarkm			printf("[ Kerberos V4 refuses authentication because %.*s ]\r\n",
37629088Smarkm				cnt, data);
37729088Smarkm		} else
37829088Smarkm			printf("[ Kerberos V4 refuses authentication ]\r\n");
37929088Smarkm		auth_send_retry();
38029088Smarkm		return;
38129088Smarkm	case KRB_ACCEPT:
38229088Smarkm		printf("[ Kerberos V4 accepts you ]\n");
38329088Smarkm		if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
38429088Smarkm			/*
38529088Smarkm			 * Send over the encrypted challenge.
38629088Smarkm		 	 */
38729088Smarkm#ifndef	ENCRYPTION
38829088Smarkm			Data(ap, KRB_CHALLENGE, (void *)0, 0);
38929088Smarkm#else	/* ENCRYPTION */
39029088Smarkm			Data(ap, KRB_CHALLENGE, (void *)session_key,
39129088Smarkm						sizeof(session_key));
39229181Smarkm			des_ecb_encrypt(&session_key, &session_key, sched, 1);
39329088Smarkm			skey.type = SK_DES;
39429088Smarkm			skey.length = 8;
39529088Smarkm			skey.data = session_key;
39629088Smarkm			encrypt_session_key(&skey, 0);
39729088Smarkm#endif	/* ENCRYPTION */
39829088Smarkm			return;
39929088Smarkm		}
40029088Smarkm		auth_finished(ap, AUTH_USER);
40129088Smarkm		return;
40229088Smarkm	case KRB_RESPONSE:
40329088Smarkm#ifdef	ENCRYPTION
40429088Smarkm		/*
40529088Smarkm		 * Verify that the response to the challenge is correct.
40629088Smarkm		 */
40729088Smarkm		if ((cnt != sizeof(Block)) ||
40829088Smarkm		    (0 != memcmp((void *)data, (void *)challenge,
40929088Smarkm						sizeof(challenge))))
41029088Smarkm		{
41129088Smarkm#endif	/* ENCRYPTION */
41229088Smarkm			printf("[ Kerberos V4 challenge failed!!! ]\r\n");
41329088Smarkm			auth_send_retry();
41429088Smarkm			return;
41529088Smarkm#ifdef	ENCRYPTION
41629088Smarkm		}
41729088Smarkm		printf("[ Kerberos V4 challenge successful ]\r\n");
41829088Smarkm		auth_finished(ap, AUTH_USER);
41929088Smarkm#endif	/* ENCRYPTION */
42029088Smarkm		break;
42129088Smarkm	default:
42229088Smarkm		if (auth_debug_mode)
42329088Smarkm			printf("Unknown Kerberos option %d\r\n", data[-1]);
42429088Smarkm		return;
42529088Smarkm	}
42629088Smarkm}
42729088Smarkm
42829088Smarkm	int
42929088Smarkmkerberos4_status(ap, name, level)
43029088Smarkm	Authenticator *ap;
43129088Smarkm	char *name;
43229088Smarkm	int level;
43329088Smarkm{
43429088Smarkm	if (level < AUTH_USER)
43529088Smarkm		return(level);
43629088Smarkm
43729088Smarkm	if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
43829088Smarkm		strcpy(name, UserNameRequested);
43929088Smarkm		return(AUTH_VALID);
44029088Smarkm	} else
44129088Smarkm		return(AUTH_USER);
44229088Smarkm}
44329088Smarkm
44429088Smarkm#define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
44529088Smarkm#define	ADDC(buf, len, c)	if ((len) > 0) {*(buf)++ = (c); --(len);}
44629088Smarkm
44729088Smarkm	void
44829088Smarkmkerberos4_printsub(data, cnt, buf, buflen)
44929088Smarkm	unsigned char *data, *buf;
45029088Smarkm	int cnt, buflen;
45129088Smarkm{
45229088Smarkm	char lbuf[32];
45329088Smarkm	register int i;
45429088Smarkm
45529088Smarkm	buf[buflen-1] = '\0';		/* make sure its NULL terminated */
45629088Smarkm	buflen -= 1;
45729088Smarkm
45829088Smarkm	switch(data[3]) {
45929088Smarkm	case KRB_REJECT:		/* Rejected (reason might follow) */
46029088Smarkm		strncpy((char *)buf, " REJECT ", buflen);
46129088Smarkm		goto common;
46229088Smarkm
46329088Smarkm	case KRB_ACCEPT:		/* Accepted (name might follow) */
46429088Smarkm		strncpy((char *)buf, " ACCEPT ", buflen);
46529088Smarkm	common:
46629088Smarkm		BUMP(buf, buflen);
46729088Smarkm		if (cnt <= 4)
46829088Smarkm			break;
46929088Smarkm		ADDC(buf, buflen, '"');
47029088Smarkm		for (i = 4; i < cnt; i++)
47129088Smarkm			ADDC(buf, buflen, data[i]);
47229088Smarkm		ADDC(buf, buflen, '"');
47329088Smarkm		ADDC(buf, buflen, '\0');
47429088Smarkm		break;
47529088Smarkm
47629088Smarkm	case KRB_AUTH:			/* Authentication data follows */
47729088Smarkm		strncpy((char *)buf, " AUTH", buflen);
47829088Smarkm		goto common2;
47929088Smarkm
48029088Smarkm	case KRB_CHALLENGE:
48129088Smarkm		strncpy((char *)buf, " CHALLENGE", buflen);
48229088Smarkm		goto common2;
48329088Smarkm
48429088Smarkm	case KRB_RESPONSE:
48529088Smarkm		strncpy((char *)buf, " RESPONSE", buflen);
48629088Smarkm		goto common2;
48729088Smarkm
48829088Smarkm	default:
48929088Smarkm		sprintf(lbuf, " %d (unknown)", data[3]);
49029088Smarkm		strncpy((char *)buf, lbuf, buflen);
49129088Smarkm	common2:
49229088Smarkm		BUMP(buf, buflen);
49329088Smarkm		for (i = 4; i < cnt; i++) {
49429088Smarkm			sprintf(lbuf, " %d", data[i]);
49529088Smarkm			strncpy((char *)buf, lbuf, buflen);
49629088Smarkm			BUMP(buf, buflen);
49729088Smarkm		}
49829088Smarkm		break;
49929088Smarkm	}
50029088Smarkm}
50129088Smarkm
50229088Smarkm	int
50329088Smarkmkerberos4_cksum(d, n)
50429088Smarkm	unsigned char *d;
50529088Smarkm	int n;
50629088Smarkm{
50729088Smarkm	int ck = 0;
50829088Smarkm
50929088Smarkm	/*
51029088Smarkm	 * A comment is probably needed here for those not
51129088Smarkm	 * well versed in the "C" language.  Yes, this is
51229088Smarkm	 * supposed to be a "switch" with the body of the
51329088Smarkm	 * "switch" being a "while" statement.  The whole
51429088Smarkm	 * purpose of the switch is to allow us to jump into
51529088Smarkm	 * the middle of the while() loop, and then not have
51629088Smarkm	 * to do any more switch()s.
51729088Smarkm	 *
51829088Smarkm	 * Some compilers will spit out a warning message
51929088Smarkm	 * about the loop not being entered at the top.
52029088Smarkm	 */
52129088Smarkm	switch (n&03)
52229088Smarkm	while (n > 0) {
52329088Smarkm	case 0:
52429088Smarkm		ck ^= (int)*d++ << 24;
52529088Smarkm		--n;
52629088Smarkm	case 3:
52729088Smarkm		ck ^= (int)*d++ << 16;
52829088Smarkm		--n;
52929088Smarkm	case 2:
53029088Smarkm		ck ^= (int)*d++ << 8;
53129088Smarkm		--n;
53229088Smarkm	case 1:
53329088Smarkm		ck ^= (int)*d++;
53429088Smarkm		--n;
53529088Smarkm	}
53629088Smarkm	return(ck);
53729088Smarkm}
53829088Smarkm#endif
53929088Smarkm
54029088Smarkm#ifdef notdef
54129088Smarkm
54229088Smarkmprkey(msg, key)
54329088Smarkm	char *msg;
54429088Smarkm	unsigned char *key;
54529088Smarkm{
54629088Smarkm	register int i;
54729088Smarkm	printf("%s:", msg);
54829088Smarkm	for (i = 0; i < 8; i++)
54929088Smarkm		printf(" %3d", key[i]);
55029088Smarkm	printf("\r\n");
55129088Smarkm}
55229088Smarkm#endif
553