181cb6ddcSMark Murray /*-
281cb6ddcSMark Murray * Copyright (c) 1991, 1993
381cb6ddcSMark Murray * The Regents of the University of California. All rights reserved.
481cb6ddcSMark Murray *
581cb6ddcSMark Murray * Redistribution and use in source and binary forms, with or without
681cb6ddcSMark Murray * modification, are permitted provided that the following conditions
781cb6ddcSMark Murray * are met:
881cb6ddcSMark Murray * 1. Redistributions of source code must retain the above copyright
981cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer.
1081cb6ddcSMark Murray * 2. Redistributions in binary form must reproduce the above copyright
1181cb6ddcSMark Murray * notice, this list of conditions and the following disclaimer in the
1281cb6ddcSMark Murray * documentation and/or other materials provided with the distribution.
1383129c0bSEd Maste * 3. Neither the name of the University nor the names of its contributors
1481cb6ddcSMark Murray * may be used to endorse or promote products derived from this software
1581cb6ddcSMark Murray * without specific prior written permission.
1681cb6ddcSMark Murray *
1781cb6ddcSMark Murray * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1881cb6ddcSMark Murray * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1981cb6ddcSMark Murray * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2081cb6ddcSMark Murray * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2181cb6ddcSMark Murray * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2281cb6ddcSMark Murray * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2381cb6ddcSMark Murray * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2481cb6ddcSMark Murray * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2581cb6ddcSMark Murray * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2681cb6ddcSMark Murray * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2781cb6ddcSMark Murray * SUCH DAMAGE.
2881cb6ddcSMark Murray */
2981cb6ddcSMark Murray
3081cb6ddcSMark Murray #ifndef lint
3104c426ccSMark Murray static const char sccsid[] = "@(#)kerberos.c 8.3 (Berkeley) 5/30/95";
3281cb6ddcSMark Murray #endif /* not lint */
3381cb6ddcSMark Murray
3481cb6ddcSMark Murray /*
3581cb6ddcSMark Murray * Copyright (C) 1990 by the Massachusetts Institute of Technology
3681cb6ddcSMark Murray *
3781cb6ddcSMark Murray * Export of this software from the United States of America is assumed
3881cb6ddcSMark Murray * to require a specific license from the United States Government.
3981cb6ddcSMark Murray * It is the responsibility of any person or organization contemplating
4081cb6ddcSMark Murray * export to obtain such a license before exporting.
4181cb6ddcSMark Murray *
4281cb6ddcSMark Murray * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
4381cb6ddcSMark Murray * distribute this software and its documentation for any purpose and
4481cb6ddcSMark Murray * without fee is hereby granted, provided that the above copyright
4581cb6ddcSMark Murray * notice appear in all copies and that both that copyright notice and
4681cb6ddcSMark Murray * this permission notice appear in supporting documentation, and that
4781cb6ddcSMark Murray * the name of M.I.T. not be used in advertising or publicity pertaining
4881cb6ddcSMark Murray * to distribution of the software without specific, written prior
4981cb6ddcSMark Murray * permission. M.I.T. makes no representations about the suitability of
5081cb6ddcSMark Murray * this software for any purpose. It is provided "as is" without express
5181cb6ddcSMark Murray * or implied warranty.
5281cb6ddcSMark Murray */
5381cb6ddcSMark Murray
5481cb6ddcSMark Murray #ifdef KRB4
5581cb6ddcSMark Murray #include <sys/types.h>
5681cb6ddcSMark Murray #include <arpa/telnet.h>
57bf4f84d4SMark Murray #include <openssl/des.h> /* BSD wont include this in krb.h, so we do it here */
5881cb6ddcSMark Murray #include <krb.h>
598fa113e5SMark Murray #include <stdio.h>
6081cb6ddcSMark Murray #include <stdlib.h>
6181cb6ddcSMark Murray #include <string.h>
6281cb6ddcSMark Murray
6381cb6ddcSMark Murray #include "encrypt.h"
6481cb6ddcSMark Murray #include "auth.h"
6581cb6ddcSMark Murray #include "misc.h"
6681cb6ddcSMark Murray
673138440aSMark Murray int kerberos4_cksum(unsigned char *, int);
683138440aSMark Murray int kuserok(AUTH_DAT *, char *);
6981cb6ddcSMark Murray
708fa113e5SMark Murray extern int auth_debug_mode;
7181cb6ddcSMark Murray
7281cb6ddcSMark Murray static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
7381cb6ddcSMark Murray AUTHTYPE_KERBEROS_V4, };
7481cb6ddcSMark Murray
7581cb6ddcSMark Murray #define KRB_AUTH 0 /* Authentication data follows */
7681cb6ddcSMark Murray #define KRB_REJECT 1 /* Rejected (reason might follow) */
7781cb6ddcSMark Murray #define KRB_ACCEPT 2 /* Accepted */
7881cb6ddcSMark Murray #define KRB_CHALLENGE 3 /* Challenge for mutual auth. */
7981cb6ddcSMark Murray #define KRB_RESPONSE 4 /* Response for mutual auth. */
8081cb6ddcSMark Murray
8181cb6ddcSMark Murray static KTEXT_ST auth;
8281cb6ddcSMark Murray static char name[ANAME_SZ];
838fa113e5SMark Murray static AUTH_DAT adat = { 0, "", "", "", 0, {}, 0, 0, 0, { 0, "", 0 } };
8481cb6ddcSMark Murray #ifdef ENCRYPTION
8581cb6ddcSMark Murray static Block session_key = { 0 };
86b285c5dfSJung-uk Kim static DES_key_schedule sched;
8781cb6ddcSMark Murray static Block challenge = { 0 };
8881cb6ddcSMark Murray #endif /* ENCRYPTION */
8981cb6ddcSMark Murray
908fa113e5SMark Murray static char krb_service_name[] = "rcmd";
918fa113e5SMark Murray static char empty[] = "";
928fa113e5SMark Murray
9381cb6ddcSMark Murray static int
Data(Authenticator * ap,int type,const unsigned char * d,int c)948fa113e5SMark Murray Data(Authenticator *ap, int type, const unsigned char *d, int c)
9581cb6ddcSMark Murray {
9681cb6ddcSMark Murray unsigned char *p = str_data + 4;
978fa113e5SMark Murray const unsigned char *cd = d;
9881cb6ddcSMark Murray
9981cb6ddcSMark Murray if (c == -1)
1008fa113e5SMark Murray c = strlen(cd);
10181cb6ddcSMark Murray
10281cb6ddcSMark Murray if (auth_debug_mode) {
10381cb6ddcSMark Murray printf("%s:%d: [%d] (%d)",
10481cb6ddcSMark Murray str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
10581cb6ddcSMark Murray str_data[3],
10681cb6ddcSMark Murray type, c);
10781cb6ddcSMark Murray printd(d, c);
10881cb6ddcSMark Murray printf("\r\n");
10981cb6ddcSMark Murray }
11081cb6ddcSMark Murray *p++ = ap->type;
11181cb6ddcSMark Murray *p++ = ap->way;
11281cb6ddcSMark Murray *p++ = type;
11381cb6ddcSMark Murray while (c-- > 0) {
11481cb6ddcSMark Murray if ((*p++ = *cd++) == IAC)
11581cb6ddcSMark Murray *p++ = IAC;
11681cb6ddcSMark Murray }
11781cb6ddcSMark Murray *p++ = IAC;
11881cb6ddcSMark Murray *p++ = SE;
11981cb6ddcSMark Murray if (str_data[3] == TELQUAL_IS)
12081cb6ddcSMark Murray printsub('>', &str_data[2], p - (&str_data[2]));
12181cb6ddcSMark Murray return(net_write(str_data, p - str_data));
12281cb6ddcSMark Murray }
12381cb6ddcSMark Murray
12481cb6ddcSMark Murray int
kerberos4_init(Authenticator * ap __unused,int server)1258fa113e5SMark Murray kerberos4_init(Authenticator *ap __unused, int server)
12681cb6ddcSMark Murray {
12781cb6ddcSMark Murray FILE *fp;
12881cb6ddcSMark Murray
12981cb6ddcSMark Murray if (server) {
13081cb6ddcSMark Murray str_data[3] = TELQUAL_REPLY;
13181cb6ddcSMark Murray if ((fp = fopen(KEYFILE, "r")) == NULL)
13281cb6ddcSMark Murray return(0);
13381cb6ddcSMark Murray fclose(fp);
13481cb6ddcSMark Murray } else {
13581cb6ddcSMark Murray str_data[3] = TELQUAL_IS;
13681cb6ddcSMark Murray }
13781cb6ddcSMark Murray return(1);
13881cb6ddcSMark Murray }
13981cb6ddcSMark Murray
14081cb6ddcSMark Murray char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
14181cb6ddcSMark Murray int dst_realm_sz = REALM_SZ;
14281cb6ddcSMark Murray
14381cb6ddcSMark Murray int
kerberos4_send(Authenticator * ap)1448fa113e5SMark Murray kerberos4_send(Authenticator *ap)
14581cb6ddcSMark Murray {
1468fa113e5SMark Murray KTEXT_ST lauth;
14781cb6ddcSMark Murray char instance[INST_SZ];
14881cb6ddcSMark Murray char *realm;
14981cb6ddcSMark Murray CREDENTIALS cred;
15081cb6ddcSMark Murray int r;
15181cb6ddcSMark Murray
15281cb6ddcSMark Murray printf("[ Trying KERBEROS4 ... ]\n");
15381cb6ddcSMark Murray if (!UserNameRequested) {
15481cb6ddcSMark Murray if (auth_debug_mode) {
15581cb6ddcSMark Murray printf("Kerberos V4: no user name supplied\r\n");
15681cb6ddcSMark Murray }
15781cb6ddcSMark Murray return(0);
15881cb6ddcSMark Murray }
15981cb6ddcSMark Murray
16081cb6ddcSMark Murray memset(instance, 0, sizeof(instance));
16181cb6ddcSMark Murray
16204c426ccSMark Murray if ((realm = krb_get_phost(RemoteHostName)))
16381cb6ddcSMark Murray strncpy(instance, realm, sizeof(instance));
16481cb6ddcSMark Murray
16581cb6ddcSMark Murray instance[sizeof(instance)-1] = '\0';
16681cb6ddcSMark Murray
16781cb6ddcSMark Murray realm = dest_realm ? dest_realm : krb_realmofhost(RemoteHostName);
16881cb6ddcSMark Murray
16981cb6ddcSMark Murray if (!realm) {
17081cb6ddcSMark Murray printf("Kerberos V4: no realm for %s\r\n", RemoteHostName);
17181cb6ddcSMark Murray return(0);
17281cb6ddcSMark Murray }
1738fa113e5SMark Murray if ((r = krb_mk_req(&lauth, krb_service_name, instance, realm, 0L))) {
17481cb6ddcSMark Murray printf("mk_req failed: %s\r\n", krb_err_txt[r]);
17581cb6ddcSMark Murray return(0);
17681cb6ddcSMark Murray }
1778fa113e5SMark Murray if ((r = krb_get_cred(krb_service_name, instance, realm, &cred))) {
17881cb6ddcSMark Murray printf("get_cred failed: %s\r\n", krb_err_txt[r]);
17981cb6ddcSMark Murray return(0);
18081cb6ddcSMark Murray }
18181cb6ddcSMark Murray if (!auth_sendname(UserNameRequested, strlen(UserNameRequested))) {
18281cb6ddcSMark Murray if (auth_debug_mode)
18381cb6ddcSMark Murray printf("Not enough room for user name\r\n");
18481cb6ddcSMark Murray return(0);
18581cb6ddcSMark Murray }
18681cb6ddcSMark Murray if (auth_debug_mode)
1878fa113e5SMark Murray printf("Sent %d bytes of authentication data\r\n", lauth.length);
1888fa113e5SMark Murray if (!Data(ap, KRB_AUTH, (void *)lauth.dat, lauth.length)) {
18981cb6ddcSMark Murray if (auth_debug_mode)
19081cb6ddcSMark Murray printf("Not enough room for authentication data\r\n");
19181cb6ddcSMark Murray return(0);
19281cb6ddcSMark Murray }
19381cb6ddcSMark Murray #ifdef ENCRYPTION
19481cb6ddcSMark Murray /*
19581cb6ddcSMark Murray * If we are doing mutual authentication, get set up to send
19681cb6ddcSMark Murray * the challenge, and verify it when the response comes back.
19781cb6ddcSMark Murray */
19881cb6ddcSMark Murray if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
19981cb6ddcSMark Murray register int i;
20081cb6ddcSMark Murray
201b285c5dfSJung-uk Kim DES_key_sched(&cred.session, sched);
202b285c5dfSJung-uk Kim DES_random_key(&session_key);
203b285c5dfSJung-uk Kim DES_ecb_encrypt(&session_key, &session_key, sched, 0);
204b285c5dfSJung-uk Kim DES_ecb_encrypt(&session_key, &challenge, sched, 0);
20581cb6ddcSMark Murray /*
20681cb6ddcSMark Murray * Increment the challenge by 1, and encrypt it for
20781cb6ddcSMark Murray * later comparison.
20881cb6ddcSMark Murray */
20981cb6ddcSMark Murray for (i = 7; i >= 0; --i) {
21081cb6ddcSMark Murray register int x;
21181cb6ddcSMark Murray x = (unsigned int)challenge[i] + 1;
21281cb6ddcSMark Murray challenge[i] = x; /* ignore overflow */
21381cb6ddcSMark Murray if (x < 256) /* if no overflow, all done */
21481cb6ddcSMark Murray break;
21581cb6ddcSMark Murray }
216b285c5dfSJung-uk Kim DES_ecb_encrypt(&challenge, &challenge, sched, 1);
21781cb6ddcSMark Murray }
21881cb6ddcSMark Murray #endif /* ENCRYPTION */
21981cb6ddcSMark Murray
22081cb6ddcSMark Murray if (auth_debug_mode) {
2218fa113e5SMark Murray printf("CK: %d:", kerberos4_cksum(lauth.dat, lauth.length));
2228fa113e5SMark Murray printd(lauth.dat, lauth.length);
22381cb6ddcSMark Murray printf("\r\n");
22481cb6ddcSMark Murray printf("Sent Kerberos V4 credentials to server\r\n");
22581cb6ddcSMark Murray }
22681cb6ddcSMark Murray return(1);
22781cb6ddcSMark Murray }
22881cb6ddcSMark Murray
22981cb6ddcSMark Murray void
kerberos4_is(Authenticator * ap,unsigned char * data,int cnt)2308fa113e5SMark Murray kerberos4_is(Authenticator *ap, unsigned char *data, int cnt)
23181cb6ddcSMark Murray {
23281cb6ddcSMark Murray #ifdef ENCRYPTION
23381cb6ddcSMark Murray Session_Key skey;
23481cb6ddcSMark Murray Block datablock;
23581cb6ddcSMark Murray #endif /* ENCRYPTION */
23681cb6ddcSMark Murray char realm[REALM_SZ];
23781cb6ddcSMark Murray char instance[INST_SZ];
23881cb6ddcSMark Murray int r;
23981cb6ddcSMark Murray
24081cb6ddcSMark Murray if (cnt-- < 1)
24181cb6ddcSMark Murray return;
24281cb6ddcSMark Murray switch (*data++) {
24381cb6ddcSMark Murray case KRB_AUTH:
24481cb6ddcSMark Murray if (krb_get_lrealm(realm, 1) != KSUCCESS) {
2458fa113e5SMark Murray Data(ap, KRB_REJECT, "No local V4 Realm.", -1);
24681cb6ddcSMark Murray auth_finished(ap, AUTH_REJECT);
24781cb6ddcSMark Murray if (auth_debug_mode)
24881cb6ddcSMark Murray printf("No local realm\r\n");
24981cb6ddcSMark Murray return;
25081cb6ddcSMark Murray }
25181cb6ddcSMark Murray memmove((void *)auth.dat, (void *)data, auth.length = cnt);
25281cb6ddcSMark Murray if (auth_debug_mode) {
25381cb6ddcSMark Murray printf("Got %d bytes of authentication data\r\n", cnt);
25481cb6ddcSMark Murray printf("CK: %d:", kerberos4_cksum(auth.dat, auth.length));
25581cb6ddcSMark Murray printd(auth.dat, auth.length);
25681cb6ddcSMark Murray printf("\r\n");
25781cb6ddcSMark Murray }
25881cb6ddcSMark Murray instance[0] = '*'; instance[1] = 0;
2598fa113e5SMark Murray if ((r = krb_rd_req(&auth, krb_service_name,
2608fa113e5SMark Murray instance, 0, &adat, empty))) {
26181cb6ddcSMark Murray if (auth_debug_mode)
26281cb6ddcSMark Murray printf("Kerberos failed him as %s\r\n", name);
2638fa113e5SMark Murray Data(ap, KRB_REJECT, krb_err_txt[r], -1);
26481cb6ddcSMark Murray auth_finished(ap, AUTH_REJECT);
26581cb6ddcSMark Murray return;
26681cb6ddcSMark Murray }
26781cb6ddcSMark Murray #ifdef ENCRYPTION
26881cb6ddcSMark Murray memmove((void *)session_key, (void *)adat.session, sizeof(Block));
26981cb6ddcSMark Murray #endif /* ENCRYPTION */
27081cb6ddcSMark Murray krb_kntoln(&adat, name);
27181cb6ddcSMark Murray
27281cb6ddcSMark Murray if (UserNameRequested && !kuserok(&adat, UserNameRequested))
2738fa113e5SMark Murray Data(ap, KRB_ACCEPT, NULL, 0);
27481cb6ddcSMark Murray else
2758fa113e5SMark Murray Data(ap, KRB_REJECT, "user is not authorized", -1);
27681cb6ddcSMark Murray auth_finished(ap, AUTH_USER);
27781cb6ddcSMark Murray break;
27881cb6ddcSMark Murray
27981cb6ddcSMark Murray case KRB_CHALLENGE:
28081cb6ddcSMark Murray #ifndef ENCRYPTION
2818fa113e5SMark Murray Data(ap, KRB_RESPONSE, NULL, 0);
28281cb6ddcSMark Murray #else /* ENCRYPTION */
28381cb6ddcSMark Murray if (!VALIDKEY(session_key)) {
28481cb6ddcSMark Murray /*
28581cb6ddcSMark Murray * We don't have a valid session key, so just
28681cb6ddcSMark Murray * send back a response with an empty session
28781cb6ddcSMark Murray * key.
28881cb6ddcSMark Murray */
2898fa113e5SMark Murray Data(ap, KRB_RESPONSE, NULL, 0);
29081cb6ddcSMark Murray break;
29181cb6ddcSMark Murray }
29281cb6ddcSMark Murray
293b285c5dfSJung-uk Kim DES_key_sched(&session_key, sched);
29481cb6ddcSMark Murray memmove((void *)datablock, (void *)data, sizeof(Block));
29581cb6ddcSMark Murray /*
29681cb6ddcSMark Murray * Take the received encrypted challenge, and encrypt
29781cb6ddcSMark Murray * it again to get a unique session_key for the
29881cb6ddcSMark Murray * ENCRYPT option.
29981cb6ddcSMark Murray */
300b285c5dfSJung-uk Kim DES_ecb_encrypt(&datablock, &session_key, sched, 1);
30181cb6ddcSMark Murray skey.type = SK_DES;
30281cb6ddcSMark Murray skey.length = 8;
30381cb6ddcSMark Murray skey.data = session_key;
30481cb6ddcSMark Murray encrypt_session_key(&skey, 1);
30581cb6ddcSMark Murray /*
30681cb6ddcSMark Murray * Now decrypt the received encrypted challenge,
30781cb6ddcSMark Murray * increment by one, re-encrypt it and send it back.
30881cb6ddcSMark Murray */
309b285c5dfSJung-uk Kim DES_ecb_encrypt(&datablock, &challenge, sched, 0);
31081cb6ddcSMark Murray for (r = 7; r >= 0; r--) {
31181cb6ddcSMark Murray register int t;
31281cb6ddcSMark Murray t = (unsigned int)challenge[r] + 1;
31381cb6ddcSMark Murray challenge[r] = t; /* ignore overflow */
31481cb6ddcSMark Murray if (t < 256) /* if no overflow, all done */
31581cb6ddcSMark Murray break;
31681cb6ddcSMark Murray }
317b285c5dfSJung-uk Kim DES_ecb_encrypt(&challenge, &challenge, sched, 1);
3188fa113e5SMark Murray Data(ap, KRB_RESPONSE, challenge, sizeof(challenge));
31981cb6ddcSMark Murray #endif /* ENCRYPTION */
32081cb6ddcSMark Murray break;
32181cb6ddcSMark Murray
32281cb6ddcSMark Murray default:
32381cb6ddcSMark Murray if (auth_debug_mode)
32481cb6ddcSMark Murray printf("Unknown Kerberos option %d\r\n", data[-1]);
3258fa113e5SMark Murray Data(ap, KRB_REJECT, NULL, 0);
32681cb6ddcSMark Murray break;
32781cb6ddcSMark Murray }
32881cb6ddcSMark Murray }
32981cb6ddcSMark Murray
33081cb6ddcSMark Murray void
kerberos4_reply(Authenticator * ap,unsigned char * data,int cnt)3318fa113e5SMark Murray kerberos4_reply(Authenticator *ap, unsigned char *data, int cnt)
33281cb6ddcSMark Murray {
33381cb6ddcSMark Murray #ifdef ENCRYPTION
33481cb6ddcSMark Murray Session_Key skey;
33581cb6ddcSMark Murray #endif /* ENCRYPTION */
33681cb6ddcSMark Murray
33781cb6ddcSMark Murray if (cnt-- < 1)
33881cb6ddcSMark Murray return;
33981cb6ddcSMark Murray switch (*data++) {
34081cb6ddcSMark Murray case KRB_REJECT:
34181cb6ddcSMark Murray if (cnt > 0) {
34281cb6ddcSMark Murray printf("[ Kerberos V4 refuses authentication because %.*s ]\r\n",
34381cb6ddcSMark Murray cnt, data);
34481cb6ddcSMark Murray } else
34581cb6ddcSMark Murray printf("[ Kerberos V4 refuses authentication ]\r\n");
34681cb6ddcSMark Murray auth_send_retry();
34781cb6ddcSMark Murray return;
34881cb6ddcSMark Murray case KRB_ACCEPT:
34981cb6ddcSMark Murray printf("[ Kerberos V4 accepts you ]\n");
35081cb6ddcSMark Murray if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
35181cb6ddcSMark Murray /*
35281cb6ddcSMark Murray * Send over the encrypted challenge.
35381cb6ddcSMark Murray */
35481cb6ddcSMark Murray #ifndef ENCRYPTION
3558fa113e5SMark Murray Data(ap, KRB_CHALLENGE, NULL, 0);
35681cb6ddcSMark Murray #else /* ENCRYPTION */
3578fa113e5SMark Murray Data(ap, KRB_CHALLENGE, session_key,
35881cb6ddcSMark Murray sizeof(session_key));
359b285c5dfSJung-uk Kim DES_ecb_encrypt(&session_key, &session_key, sched, 1);
36081cb6ddcSMark Murray skey.type = SK_DES;
36181cb6ddcSMark Murray skey.length = 8;
36281cb6ddcSMark Murray skey.data = session_key;
36381cb6ddcSMark Murray encrypt_session_key(&skey, 0);
36481cb6ddcSMark Murray #endif /* ENCRYPTION */
36581cb6ddcSMark Murray return;
36681cb6ddcSMark Murray }
36781cb6ddcSMark Murray auth_finished(ap, AUTH_USER);
36881cb6ddcSMark Murray return;
36981cb6ddcSMark Murray case KRB_RESPONSE:
37081cb6ddcSMark Murray #ifdef ENCRYPTION
37181cb6ddcSMark Murray /*
37281cb6ddcSMark Murray * Verify that the response to the challenge is correct.
37381cb6ddcSMark Murray */
37481cb6ddcSMark Murray if ((cnt != sizeof(Block)) ||
37581cb6ddcSMark Murray (0 != memcmp((void *)data, (void *)challenge,
37681cb6ddcSMark Murray sizeof(challenge))))
37781cb6ddcSMark Murray {
37881cb6ddcSMark Murray #endif /* ENCRYPTION */
37981cb6ddcSMark Murray printf("[ Kerberos V4 challenge failed!!! ]\r\n");
38081cb6ddcSMark Murray auth_send_retry();
38181cb6ddcSMark Murray return;
38281cb6ddcSMark Murray #ifdef ENCRYPTION
38381cb6ddcSMark Murray }
38481cb6ddcSMark Murray printf("[ Kerberos V4 challenge successful ]\r\n");
38581cb6ddcSMark Murray auth_finished(ap, AUTH_USER);
38681cb6ddcSMark Murray #endif /* ENCRYPTION */
38781cb6ddcSMark Murray break;
38881cb6ddcSMark Murray default:
38981cb6ddcSMark Murray if (auth_debug_mode)
39081cb6ddcSMark Murray printf("Unknown Kerberos option %d\r\n", data[-1]);
39181cb6ddcSMark Murray return;
39281cb6ddcSMark Murray }
39381cb6ddcSMark Murray }
39481cb6ddcSMark Murray
39581cb6ddcSMark Murray int
kerberos4_status(Authenticator * ap __unused,char * nam,int level)3968fa113e5SMark Murray kerberos4_status(Authenticator *ap __unused, char *nam, int level)
39781cb6ddcSMark Murray {
39881cb6ddcSMark Murray if (level < AUTH_USER)
39981cb6ddcSMark Murray return(level);
40081cb6ddcSMark Murray
40181cb6ddcSMark Murray if (UserNameRequested && !kuserok(&adat, UserNameRequested)) {
4028fa113e5SMark Murray strcpy(nam, UserNameRequested);
40381cb6ddcSMark Murray return(AUTH_VALID);
40481cb6ddcSMark Murray } else
40581cb6ddcSMark Murray return(AUTH_USER);
40681cb6ddcSMark Murray }
40781cb6ddcSMark Murray
40881cb6ddcSMark Murray #define BUMP(buf, len) while (*(buf)) {++(buf), --(len);}
40981cb6ddcSMark Murray #define ADDC(buf, len, c) if ((len) > 0) {*(buf)++ = (c); --(len);}
41081cb6ddcSMark Murray
41181cb6ddcSMark Murray void
kerberos4_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)4128fa113e5SMark Murray kerberos4_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
41381cb6ddcSMark Murray {
41481cb6ddcSMark Murray char lbuf[32];
41581cb6ddcSMark Murray register int i;
41681cb6ddcSMark Murray
41781cb6ddcSMark Murray buf[buflen-1] = '\0'; /* make sure its NULL terminated */
41881cb6ddcSMark Murray buflen -= 1;
41981cb6ddcSMark Murray
42081cb6ddcSMark Murray switch(data[3]) {
42181cb6ddcSMark Murray case KRB_REJECT: /* Rejected (reason might follow) */
42281cb6ddcSMark Murray strncpy((char *)buf, " REJECT ", buflen);
42381cb6ddcSMark Murray goto common;
42481cb6ddcSMark Murray
42581cb6ddcSMark Murray case KRB_ACCEPT: /* Accepted (name might follow) */
42681cb6ddcSMark Murray strncpy((char *)buf, " ACCEPT ", buflen);
42781cb6ddcSMark Murray common:
42881cb6ddcSMark Murray BUMP(buf, buflen);
42981cb6ddcSMark Murray if (cnt <= 4)
43081cb6ddcSMark Murray break;
43181cb6ddcSMark Murray ADDC(buf, buflen, '"');
43281cb6ddcSMark Murray for (i = 4; i < cnt; i++)
43381cb6ddcSMark Murray ADDC(buf, buflen, data[i]);
43481cb6ddcSMark Murray ADDC(buf, buflen, '"');
43581cb6ddcSMark Murray ADDC(buf, buflen, '\0');
43681cb6ddcSMark Murray break;
43781cb6ddcSMark Murray
43881cb6ddcSMark Murray case KRB_AUTH: /* Authentication data follows */
43981cb6ddcSMark Murray strncpy((char *)buf, " AUTH", buflen);
44081cb6ddcSMark Murray goto common2;
44181cb6ddcSMark Murray
44281cb6ddcSMark Murray case KRB_CHALLENGE:
44381cb6ddcSMark Murray strncpy((char *)buf, " CHALLENGE", buflen);
44481cb6ddcSMark Murray goto common2;
44581cb6ddcSMark Murray
44681cb6ddcSMark Murray case KRB_RESPONSE:
44781cb6ddcSMark Murray strncpy((char *)buf, " RESPONSE", buflen);
44881cb6ddcSMark Murray goto common2;
44981cb6ddcSMark Murray
45081cb6ddcSMark Murray default:
45181cb6ddcSMark Murray sprintf(lbuf, " %d (unknown)", data[3]);
45281cb6ddcSMark Murray strncpy((char *)buf, lbuf, buflen);
45381cb6ddcSMark Murray common2:
45481cb6ddcSMark Murray BUMP(buf, buflen);
45581cb6ddcSMark Murray for (i = 4; i < cnt; i++) {
45681cb6ddcSMark Murray sprintf(lbuf, " %d", data[i]);
45781cb6ddcSMark Murray strncpy((char *)buf, lbuf, buflen);
45881cb6ddcSMark Murray BUMP(buf, buflen);
45981cb6ddcSMark Murray }
46081cb6ddcSMark Murray break;
46181cb6ddcSMark Murray }
46281cb6ddcSMark Murray }
46381cb6ddcSMark Murray
46481cb6ddcSMark Murray int
kerberos4_cksum(unsigned char * d,int n)4658fa113e5SMark Murray kerberos4_cksum(unsigned char *d, int n)
46681cb6ddcSMark Murray {
46781cb6ddcSMark Murray int ck = 0;
46881cb6ddcSMark Murray
46981cb6ddcSMark Murray /*
47081cb6ddcSMark Murray * A comment is probably needed here for those not
47181cb6ddcSMark Murray * well versed in the "C" language. Yes, this is
47281cb6ddcSMark Murray * supposed to be a "switch" with the body of the
47381cb6ddcSMark Murray * "switch" being a "while" statement. The whole
47481cb6ddcSMark Murray * purpose of the switch is to allow us to jump into
47581cb6ddcSMark Murray * the middle of the while() loop, and then not have
47681cb6ddcSMark Murray * to do any more switch()s.
47781cb6ddcSMark Murray *
47881cb6ddcSMark Murray * Some compilers will spit out a warning message
47981cb6ddcSMark Murray * about the loop not being entered at the top.
48081cb6ddcSMark Murray */
48181cb6ddcSMark Murray switch (n&03)
48281cb6ddcSMark Murray while (n > 0) {
48381cb6ddcSMark Murray case 0:
48481cb6ddcSMark Murray ck ^= (int)*d++ << 24;
48581cb6ddcSMark Murray --n;
48681cb6ddcSMark Murray case 3:
48781cb6ddcSMark Murray ck ^= (int)*d++ << 16;
48881cb6ddcSMark Murray --n;
48981cb6ddcSMark Murray case 2:
49081cb6ddcSMark Murray ck ^= (int)*d++ << 8;
49181cb6ddcSMark Murray --n;
49281cb6ddcSMark Murray case 1:
49381cb6ddcSMark Murray ck ^= (int)*d++;
49481cb6ddcSMark Murray --n;
49581cb6ddcSMark Murray }
49681cb6ddcSMark Murray return(ck);
49781cb6ddcSMark Murray }
49881cb6ddcSMark Murray #endif
499