xref: /freebsd/contrib/telnet/libtelnet/kerberos5.c (revision a3c858005cae175e277f6f6735ca9eaea7eaf3c3)
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.
13*83129c0bSEd 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 /*
3181cb6ddcSMark Murray  * Copyright (C) 1990 by the Massachusetts Institute of Technology
3281cb6ddcSMark Murray  *
3381cb6ddcSMark Murray  * Export of this software from the United States of America may
3481cb6ddcSMark Murray  * require a specific license from the United States Government.
3581cb6ddcSMark Murray  * It is the responsibility of any person or organization contemplating
3681cb6ddcSMark Murray  * export to obtain such a license before exporting.
3781cb6ddcSMark Murray  *
3881cb6ddcSMark Murray  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
3981cb6ddcSMark Murray  * distribute this software and its documentation for any purpose and
4081cb6ddcSMark Murray  * without fee is hereby granted, provided that the above copyright
4181cb6ddcSMark Murray  * notice appear in all copies and that both that copyright notice and
4281cb6ddcSMark Murray  * this permission notice appear in supporting documentation, and that
4381cb6ddcSMark Murray  * the name of M.I.T. not be used in advertising or publicity pertaining
4481cb6ddcSMark Murray  * to distribution of the software without specific, written prior
4581cb6ddcSMark Murray  * permission.  M.I.T. makes no representations about the suitability of
4681cb6ddcSMark Murray  * this software for any purpose.  It is provided "as is" without express
4781cb6ddcSMark Murray  * or implied warranty.
4881cb6ddcSMark Murray  */
4981cb6ddcSMark Murray 
5081cb6ddcSMark Murray #ifdef	KRB5
518fa113e5SMark Murray 
5281cb6ddcSMark Murray #include <arpa/telnet.h>
5321f083c0SMark Murray #include <stdio.h>
5421f083c0SMark Murray #include <stdlib.h>
5521f083c0SMark Murray #include <string.h>
568fa113e5SMark Murray #include <unistd.h>
578fa113e5SMark Murray #include <netdb.h>
588fa113e5SMark Murray #include <ctype.h>
598fa113e5SMark Murray #include <pwd.h>
608fa113e5SMark Murray #define Authenticator k5_Authenticator
618fa113e5SMark Murray #include <krb5.h>
628fa113e5SMark Murray #undef Authenticator
6381cb6ddcSMark Murray 
6481cb6ddcSMark Murray #include "encrypt.h"
6581cb6ddcSMark Murray #include "auth.h"
6681cb6ddcSMark Murray #include "misc.h"
6781cb6ddcSMark Murray 
6881cb6ddcSMark Murray int forward_flags = 0;  /* Flags get set in telnet/main.c on -f and -F */
6981cb6ddcSMark Murray 
7081cb6ddcSMark Murray /* These values need to be the same as those defined in telnet/main.c. */
7181cb6ddcSMark Murray /* Either define them in both places, or put in some common header file. */
7281cb6ddcSMark Murray #define OPTS_FORWARD_CREDS	0x00000002
7381cb6ddcSMark Murray #define OPTS_FORWARDABLE_CREDS	0x00000001
7481cb6ddcSMark Murray 
758fa113e5SMark Murray void kerberos5_forward (Authenticator *);
7681cb6ddcSMark Murray 
7781cb6ddcSMark Murray static unsigned char str_data[1024] = { IAC, SB, TELOPT_AUTHENTICATION, 0,
7881cb6ddcSMark Murray 			  		AUTHTYPE_KERBEROS_V5, };
7981cb6ddcSMark Murray 
8081cb6ddcSMark Murray #define	KRB_AUTH		0	/* Authentication data follows */
8181cb6ddcSMark Murray #define	KRB_REJECT		1	/* Rejected (reason might follow) */
8281cb6ddcSMark Murray #define	KRB_ACCEPT		2	/* Accepted */
8381cb6ddcSMark Murray #define	KRB_RESPONSE		3	/* Response for mutual auth. */
8481cb6ddcSMark Murray 
8581cb6ddcSMark Murray #define KRB_FORWARD     	4       /* Forwarded credentials follow */
8681cb6ddcSMark Murray #define KRB_FORWARD_ACCEPT     	5       /* Forwarded credentials accepted */
8781cb6ddcSMark Murray #define KRB_FORWARD_REJECT     	6       /* Forwarded credentials rejected */
8881cb6ddcSMark Murray 
8981cb6ddcSMark Murray static	krb5_data auth;
908fa113e5SMark Murray static  krb5_ticket *ticket;
9181cb6ddcSMark Murray 
928fa113e5SMark Murray static krb5_context context;
938fa113e5SMark Murray static krb5_auth_context auth_context;
9481cb6ddcSMark Murray 
953ef51c5fSStanislav Sedov static void
print_krb5_error(krb5_context context,krb5_error_code code,const char * msg)963ef51c5fSStanislav Sedov print_krb5_error(krb5_context context, krb5_error_code code, const char *msg)
973ef51c5fSStanislav Sedov {
983ef51c5fSStanislav Sedov 	const char *error_message;
993ef51c5fSStanislav Sedov 
1003ef51c5fSStanislav Sedov 	error_message = krb5_get_error_message(context, code);
1013ef51c5fSStanislav Sedov 	printf(msg, error_message);
1023ef51c5fSStanislav Sedov 	krb5_free_error_message(context, error_message);
1033ef51c5fSStanislav Sedov }
1043ef51c5fSStanislav Sedov 
10581cb6ddcSMark Murray static int
Data(Authenticator * ap,int type,const char * d,int c)1068fa113e5SMark Murray Data(Authenticator *ap, int type, const char *d, int c)
10781cb6ddcSMark Murray {
10881cb6ddcSMark Murray     unsigned char *p = str_data + 4;
1098fa113e5SMark Murray     const unsigned char *cd = d;
11081cb6ddcSMark Murray 
11181cb6ddcSMark Murray     if (c == -1)
1128fa113e5SMark Murray 	c = strlen(cd);
11381cb6ddcSMark Murray 
11481cb6ddcSMark Murray     if (auth_debug_mode) {
11581cb6ddcSMark Murray 	printf("%s:%d: [%d] (%d)",
11681cb6ddcSMark Murray 	       str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
11781cb6ddcSMark Murray 	       str_data[3],
11881cb6ddcSMark Murray 	       type, c);
11981cb6ddcSMark Murray 	printd(d, c);
12081cb6ddcSMark Murray 	printf("\r\n");
12181cb6ddcSMark Murray     }
12281cb6ddcSMark Murray     *p++ = ap->type;
12381cb6ddcSMark Murray     *p++ = ap->way;
12481cb6ddcSMark Murray     *p++ = type;
12581cb6ddcSMark Murray     while (c-- > 0) {
12681cb6ddcSMark Murray 	if ((*p++ = *cd++) == IAC)
12781cb6ddcSMark Murray 	    *p++ = IAC;
12881cb6ddcSMark Murray     }
12981cb6ddcSMark Murray     *p++ = IAC;
13081cb6ddcSMark Murray     *p++ = SE;
13181cb6ddcSMark Murray     if (str_data[3] == TELQUAL_IS)
13281cb6ddcSMark Murray 	printsub('>', &str_data[2], p - &str_data[2]);
13381cb6ddcSMark Murray     return(net_write(str_data, p - str_data));
13481cb6ddcSMark Murray }
13581cb6ddcSMark Murray 
13681cb6ddcSMark Murray int
kerberos5_init(Authenticator * ap __unused,int server)1378fa113e5SMark Murray kerberos5_init(Authenticator *ap __unused, int server)
13881cb6ddcSMark Murray {
1398fa113e5SMark Murray     krb5_error_code ret;
1408fa113e5SMark Murray 
1418fa113e5SMark Murray     ret = krb5_init_context(&context);
1428fa113e5SMark Murray     if (ret)
1438fa113e5SMark Murray 	return 0;
1448fa113e5SMark Murray     if (server) {
1458fa113e5SMark Murray 	krb5_keytab kt;
1468fa113e5SMark Murray 	krb5_kt_cursor cursor;
1478fa113e5SMark Murray 
1488fa113e5SMark Murray 	ret = krb5_kt_default(context, &kt);
1498fa113e5SMark Murray 	if (ret)
1508fa113e5SMark Murray 	    return 0;
1518fa113e5SMark Murray 
1528fa113e5SMark Murray 	ret = krb5_kt_start_seq_get (context, kt, &cursor);
1538fa113e5SMark Murray 	if (ret) {
1548fa113e5SMark Murray 	    krb5_kt_close (context, kt);
1558fa113e5SMark Murray 	    return 0;
1568fa113e5SMark Murray 	}
1578fa113e5SMark Murray 	krb5_kt_end_seq_get (context, kt, &cursor);
1588fa113e5SMark Murray 	krb5_kt_close (context, kt);
1598fa113e5SMark Murray 
16081cb6ddcSMark Murray 	str_data[3] = TELQUAL_REPLY;
1618fa113e5SMark Murray     } else
16281cb6ddcSMark Murray 	str_data[3] = TELQUAL_IS;
16381cb6ddcSMark Murray     return(1);
16481cb6ddcSMark Murray }
16581cb6ddcSMark Murray 
1668fa113e5SMark Murray extern int net;
1678fa113e5SMark Murray 
1688fa113e5SMark Murray static int
kerberos5_send(const char * name,Authenticator * ap)1698fa113e5SMark Murray kerberos5_send(const char *name, Authenticator *ap)
17081cb6ddcSMark Murray {
1718fa113e5SMark Murray     krb5_error_code ret;
17281cb6ddcSMark Murray     krb5_ccache ccache;
17381cb6ddcSMark Murray     int ap_opts;
1748fa113e5SMark Murray     krb5_data cksum_data;
1758fa113e5SMark Murray     char foo[2];
17681cb6ddcSMark Murray 
17781cb6ddcSMark Murray     if (!UserNameRequested) {
17881cb6ddcSMark Murray 	if (auth_debug_mode) {
17981cb6ddcSMark Murray 	    printf("Kerberos V5: no user name supplied\r\n");
18081cb6ddcSMark Murray 	}
18181cb6ddcSMark Murray 	return(0);
18281cb6ddcSMark Murray     }
18381cb6ddcSMark Murray 
1848fa113e5SMark Murray     ret = krb5_cc_default(context, &ccache);
1858fa113e5SMark Murray     if (ret) {
18681cb6ddcSMark Murray 	if (auth_debug_mode) {
1873ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "Kerberos V5: could not get default ccache: %s\r\n");
18881cb6ddcSMark Murray 	}
1898fa113e5SMark Murray 	return 0;
19081cb6ddcSMark Murray     }
19181cb6ddcSMark Murray 
19281cb6ddcSMark Murray     if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
19381cb6ddcSMark Murray 	ap_opts = AP_OPTS_MUTUAL_REQUIRED;
19481cb6ddcSMark Murray     else
19581cb6ddcSMark Murray 	ap_opts = 0;
19681d1ffeeSJacques Vidrine     ap_opts |= AP_OPTS_USE_SUBKEY;
19781cb6ddcSMark Murray 
1988fa113e5SMark Murray     ret = krb5_auth_con_init (context, &auth_context);
1998fa113e5SMark Murray     if (ret) {
20081cb6ddcSMark Murray 	if (auth_debug_mode) {
2013ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "Kerberos V5: krb5_auth_con_init failed (%s)\r\n");
20281cb6ddcSMark Murray 	}
20381cb6ddcSMark Murray 	return(0);
20481cb6ddcSMark Murray     }
20581cb6ddcSMark Murray 
2068fa113e5SMark Murray     ret = krb5_auth_con_setaddrs_from_fd (context,
2078fa113e5SMark Murray 					  auth_context,
2088fa113e5SMark Murray 					  &net);
2098fa113e5SMark Murray     if (ret) {
2108fa113e5SMark Murray 	if (auth_debug_mode) {
2113ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "Kerberos V5:"
2123ef51c5fSStanislav Sedov 		    " krb5_auth_con_setaddrs_from_fd failed (%s)\r\n");
2138fa113e5SMark Murray 	}
2148fa113e5SMark Murray 	return(0);
2158fa113e5SMark Murray     }
2168fa113e5SMark Murray 
217eacee0ffSJacques Vidrine     krb5_auth_con_setkeytype (context, auth_context, KEYTYPE_DES);
2188fa113e5SMark Murray 
2198fa113e5SMark Murray     foo[0] = ap->type;
2208fa113e5SMark Murray     foo[1] = ap->way;
2218fa113e5SMark Murray 
2228fa113e5SMark Murray     cksum_data.length = sizeof(foo);
2238fa113e5SMark Murray     cksum_data.data   = foo;
2248fa113e5SMark Murray 
2258fa113e5SMark Murray 
2268fa113e5SMark Murray     {
2278fa113e5SMark Murray 	krb5_principal service;
2288fa113e5SMark Murray 	char sname[128];
2298fa113e5SMark Murray 
2308fa113e5SMark Murray 
2318fa113e5SMark Murray 	ret = krb5_sname_to_principal (context,
2328fa113e5SMark Murray 				       RemoteHostName,
2338fa113e5SMark Murray 				       NULL,
2348fa113e5SMark Murray 				       KRB5_NT_SRV_HST,
2358fa113e5SMark Murray 				       &service);
2368fa113e5SMark Murray 	if(ret) {
2378fa113e5SMark Murray 	    if (auth_debug_mode) {
2383ef51c5fSStanislav Sedov 		const char *err_str;
2393ef51c5fSStanislav Sedov 
2403ef51c5fSStanislav Sedov 		err_str = krb5_get_error_message(context, ret);
2413ef51c5fSStanislav Sedov 		printf("Kerberosr V5:"
2428fa113e5SMark Murray 			" krb5_sname_to_principal(%s) failed (%s)\r\n",
2433ef51c5fSStanislav Sedov 			RemoteHostName, err_str);
2443ef51c5fSStanislav Sedov 		krb5_free_error_message(context, err_str);
2458fa113e5SMark Murray 	    }
2468fa113e5SMark Murray 	    return 0;
2478fa113e5SMark Murray 	}
2488fa113e5SMark Murray 	ret = krb5_unparse_name_fixed(context, service, sname, sizeof(sname));
2498fa113e5SMark Murray 	if(ret) {
2508fa113e5SMark Murray 	    if (auth_debug_mode) {
2513ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5:"
2523ef51c5fSStanislav Sedov 			" krb5_unparse_name_fixed failed (%s)\r\n");
2538fa113e5SMark Murray 	    }
2548fa113e5SMark Murray 	    return 0;
2558fa113e5SMark Murray 	}
2568fa113e5SMark Murray 	printf("[ Trying %s (%s)... ]\r\n", name, sname);
2578fa113e5SMark Murray 	ret = krb5_mk_req_exact(context, &auth_context, ap_opts,
2588fa113e5SMark Murray 				service,
2598fa113e5SMark Murray 				&cksum_data, ccache, &auth);
2608fa113e5SMark Murray 	krb5_free_principal (context, service);
2618fa113e5SMark Murray 
2628fa113e5SMark Murray     }
2638fa113e5SMark Murray     if (ret) {
2648fa113e5SMark Murray 	if (1 || auth_debug_mode) {
2653ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "Kerberos V5: mk_req failed (%s)\r\n");
2668fa113e5SMark Murray 	}
2678fa113e5SMark Murray 	return(0);
2688fa113e5SMark Murray     }
2698fa113e5SMark Murray 
2708fa113e5SMark Murray     if (!auth_sendname((unsigned char *)UserNameRequested,
2718fa113e5SMark Murray 		       strlen(UserNameRequested))) {
27281cb6ddcSMark Murray 	if (auth_debug_mode)
27381cb6ddcSMark Murray 	    printf("Not enough room for user name\r\n");
27481cb6ddcSMark Murray 	return(0);
27581cb6ddcSMark Murray     }
27681cb6ddcSMark Murray     if (!Data(ap, KRB_AUTH, auth.data, auth.length)) {
27781cb6ddcSMark Murray 	if (auth_debug_mode)
27881cb6ddcSMark Murray 	    printf("Not enough room for authentication data\r\n");
27981cb6ddcSMark Murray 	return(0);
28081cb6ddcSMark Murray     }
28181cb6ddcSMark Murray     if (auth_debug_mode) {
28281cb6ddcSMark Murray 	printf("Sent Kerberos V5 credentials to server\r\n");
28381cb6ddcSMark Murray     }
28481cb6ddcSMark Murray     return(1);
28581cb6ddcSMark Murray }
28681cb6ddcSMark Murray 
2878fa113e5SMark Murray int
kerberos5_send_mutual(Authenticator * ap)2888fa113e5SMark Murray kerberos5_send_mutual(Authenticator *ap)
28981cb6ddcSMark Murray {
2908fa113e5SMark Murray     return kerberos5_send("mutual KERBEROS5", ap);
2918fa113e5SMark Murray }
2928fa113e5SMark Murray 
2938fa113e5SMark Murray int
kerberos5_send_oneway(Authenticator * ap)2948fa113e5SMark Murray kerberos5_send_oneway(Authenticator *ap)
2958fa113e5SMark Murray {
2968fa113e5SMark Murray     return kerberos5_send("KERBEROS5", ap);
2978fa113e5SMark Murray }
2988fa113e5SMark Murray 
2998fa113e5SMark Murray void
kerberos5_is(Authenticator * ap,unsigned char * data,int cnt)3008fa113e5SMark Murray kerberos5_is(Authenticator *ap, unsigned char *data, int cnt)
3018fa113e5SMark Murray {
3028fa113e5SMark Murray     krb5_error_code ret;
30381cb6ddcSMark Murray     krb5_data outbuf;
3048fa113e5SMark Murray     krb5_keyblock *key_block;
30581cb6ddcSMark Murray     char *name;
3068fa113e5SMark Murray     krb5_principal server;
3078fa113e5SMark Murray     int zero = 0;
30881cb6ddcSMark Murray 
30981cb6ddcSMark Murray     if (cnt-- < 1)
31081cb6ddcSMark Murray 	return;
31181cb6ddcSMark Murray     switch (*data++) {
31281cb6ddcSMark Murray     case KRB_AUTH:
31381cb6ddcSMark Murray 	auth.data = (char *)data;
31481cb6ddcSMark Murray 	auth.length = cnt;
31581cb6ddcSMark Murray 
3168fa113e5SMark Murray 	auth_context = NULL;
3178fa113e5SMark Murray 
3188fa113e5SMark Murray 	ret = krb5_auth_con_init (context, &auth_context);
3198fa113e5SMark Murray 	if (ret) {
3208fa113e5SMark Murray 	    Data(ap, KRB_REJECT, "krb5_auth_con_init failed", -1);
32181cb6ddcSMark Murray 	    auth_finished(ap, AUTH_REJECT);
3228fa113e5SMark Murray 	    if (auth_debug_mode)
3233ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: krb5_auth_con_init failed (%s)\r\n");
32481cb6ddcSMark Murray 	    return;
32581cb6ddcSMark Murray 	}
32681cb6ddcSMark Murray 
3278fa113e5SMark Murray 	ret = krb5_auth_con_setaddrs_from_fd (context,
3288fa113e5SMark Murray 					      auth_context,
3298fa113e5SMark Murray 					      &zero);
3308fa113e5SMark Murray 	if (ret) {
3318fa113e5SMark Murray 	    Data(ap, KRB_REJECT, "krb5_auth_con_setaddrs_from_fd failed", -1);
33281cb6ddcSMark Murray 	    auth_finished(ap, AUTH_REJECT);
3338fa113e5SMark Murray 	    if (auth_debug_mode)
3343ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: "
3353ef51c5fSStanislav Sedov 		       "krb5_auth_con_setaddrs_from_fd failed (%s)\r\n");
33681cb6ddcSMark Murray 	    return;
33781cb6ddcSMark Murray 	}
33881cb6ddcSMark Murray 
3398fa113e5SMark Murray 	ret = krb5_sock_to_principal (context,
3408fa113e5SMark Murray 				      0,
3418fa113e5SMark Murray 				      "host",
3428fa113e5SMark Murray 				      KRB5_NT_SRV_HST,
3438fa113e5SMark Murray 				      &server);
3448fa113e5SMark Murray 	if (ret) {
3458fa113e5SMark Murray 	    Data(ap, KRB_REJECT, "krb5_sock_to_principal failed", -1);
34681cb6ddcSMark Murray 	    auth_finished(ap, AUTH_REJECT);
3478fa113e5SMark Murray 	    if (auth_debug_mode)
3483ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: "
3493ef51c5fSStanislav Sedov 		       "krb5_sock_to_principal failed (%s)\r\n");
35081cb6ddcSMark Murray 	    return;
35181cb6ddcSMark Murray 	}
35281cb6ddcSMark Murray 
3538fa113e5SMark Murray 	ret = krb5_rd_req(context,
3548fa113e5SMark Murray 			  &auth_context,
3558fa113e5SMark Murray 			  &auth,
3568fa113e5SMark Murray 			  server,
3578fa113e5SMark Murray 			  NULL,
3588fa113e5SMark Murray 			  NULL,
3598fa113e5SMark Murray 			  &ticket);
36081cb6ddcSMark Murray 
3618fa113e5SMark Murray 	krb5_free_principal (context, server);
3628fa113e5SMark Murray 	if (ret) {
3638fa113e5SMark Murray 	    char *errbuf;
3643ef51c5fSStanislav Sedov 	    const char *err_str;
36581cb6ddcSMark Murray 
3663ef51c5fSStanislav Sedov 	    err_str = krb5_get_error_message(context, ret);
3678fa113e5SMark Murray 	    asprintf(&errbuf,
3683ef51c5fSStanislav Sedov 		     "Read req failed: %s", err_str);
3693ef51c5fSStanislav Sedov 	    krb5_free_error_message(context, err_str);
37081cb6ddcSMark Murray 	    Data(ap, KRB_REJECT, errbuf, -1);
37181cb6ddcSMark Murray 	    if (auth_debug_mode)
37281cb6ddcSMark Murray 		printf("%s\r\n", errbuf);
3738fa113e5SMark Murray 	    free (errbuf);
37481cb6ddcSMark Murray 	    return;
37581cb6ddcSMark Murray 	}
37681cb6ddcSMark Murray 
3778fa113e5SMark Murray 	{
3788fa113e5SMark Murray 	    char foo[2];
3798fa113e5SMark Murray 
3808fa113e5SMark Murray 	    foo[0] = ap->type;
3818fa113e5SMark Murray 	    foo[1] = ap->way;
3828fa113e5SMark Murray 
3838fa113e5SMark Murray 	    ret = krb5_verify_authenticator_checksum(context,
3848fa113e5SMark Murray 						     auth_context,
3858fa113e5SMark Murray 						     foo,
3868fa113e5SMark Murray 						     sizeof(foo));
3878fa113e5SMark Murray 
3888fa113e5SMark Murray 	    if (ret) {
3898fa113e5SMark Murray 		char *errbuf;
3903ef51c5fSStanislav Sedov 		const char *err_str;
3913ef51c5fSStanislav Sedov 
3923ef51c5fSStanislav Sedov 		err_str = krb5_get_error_message(context, ret);
3933ef51c5fSStanislav Sedov 		asprintf(&errbuf, "Bad checksum: %s", err_str);
3943ef51c5fSStanislav Sedov 		krb5_free_error_message(context, err_str);
3958fa113e5SMark Murray 		Data(ap, KRB_REJECT, errbuf, -1);
3968fa113e5SMark Murray 		if (auth_debug_mode)
3978fa113e5SMark Murray 		    printf ("%s\r\n", errbuf);
3988fa113e5SMark Murray 		free(errbuf);
3998fa113e5SMark Murray 		return;
4008fa113e5SMark Murray 	    }
4018fa113e5SMark Murray 	}
4028fa113e5SMark Murray 	ret = krb5_auth_con_getremotesubkey (context,
4038fa113e5SMark Murray 					     auth_context,
4048fa113e5SMark Murray 					     &key_block);
4058fa113e5SMark Murray 
4068fa113e5SMark Murray 	if (ret) {
4078fa113e5SMark Murray 	    Data(ap, KRB_REJECT, "krb5_auth_con_getremotesubkey failed", -1);
4088fa113e5SMark Murray 	    auth_finished(ap, AUTH_REJECT);
4098fa113e5SMark Murray 	    if (auth_debug_mode)
4103ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: "
4113ef51c5fSStanislav Sedov 		       "krb5_auth_con_getremotesubkey failed (%s)\r\n");
4128fa113e5SMark Murray 	    return;
4138fa113e5SMark Murray 	}
4148fa113e5SMark Murray 
41581d1ffeeSJacques Vidrine 	if (key_block == NULL) {
41681d1ffeeSJacques Vidrine 	    ret = krb5_auth_con_getkey(context,
41781d1ffeeSJacques Vidrine 				       auth_context,
41881d1ffeeSJacques Vidrine 				       &key_block);
41981d1ffeeSJacques Vidrine 	}
42081d1ffeeSJacques Vidrine 	if (ret) {
42181d1ffeeSJacques Vidrine 	    Data(ap, KRB_REJECT, "krb5_auth_con_getkey failed", -1);
42281d1ffeeSJacques Vidrine 	    auth_finished(ap, AUTH_REJECT);
42381d1ffeeSJacques Vidrine 	    if (auth_debug_mode)
4243ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: "
4253ef51c5fSStanislav Sedov 		       "krb5_auth_con_getkey failed (%s)\r\n");
42681d1ffeeSJacques Vidrine 	    return;
42781d1ffeeSJacques Vidrine 	}
42881d1ffeeSJacques Vidrine 	if (key_block == NULL) {
42981d1ffeeSJacques Vidrine 	    Data(ap, KRB_REJECT, "no subkey received", -1);
43081d1ffeeSJacques Vidrine 	    auth_finished(ap, AUTH_REJECT);
43181d1ffeeSJacques Vidrine 	    if (auth_debug_mode)
43281d1ffeeSJacques Vidrine 		printf("Kerberos V5: "
43381d1ffeeSJacques Vidrine 		       "krb5_auth_con_getremotesubkey returned NULL key\r\n");
43481d1ffeeSJacques Vidrine 	    return;
43581d1ffeeSJacques Vidrine 	}
43681d1ffeeSJacques Vidrine 
4378fa113e5SMark Murray 	if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
4388fa113e5SMark Murray 	    ret = krb5_mk_rep(context, auth_context, &outbuf);
4398fa113e5SMark Murray 	    if (ret) {
4408fa113e5SMark Murray 		Data(ap, KRB_REJECT,
4418fa113e5SMark Murray 		     "krb5_mk_rep failed", -1);
4428fa113e5SMark Murray 		auth_finished(ap, AUTH_REJECT);
4438fa113e5SMark Murray 		if (auth_debug_mode)
4443ef51c5fSStanislav Sedov 		    print_krb5_error(context, ret, "Kerberos V5: "
4453ef51c5fSStanislav Sedov 			   "krb5_mk_rep failed (%s)\r\n");
4468fa113e5SMark Murray 		return;
44781cb6ddcSMark Murray 	    }
44881cb6ddcSMark Murray 	    Data(ap, KRB_RESPONSE, outbuf.data, outbuf.length);
44981cb6ddcSMark Murray 	}
4508fa113e5SMark Murray 	if (krb5_unparse_name(context, ticket->client, &name))
45181cb6ddcSMark Murray 	    name = 0;
4528fa113e5SMark Murray 
4538fa113e5SMark Murray 	if(UserNameRequested && krb5_kuserok(context,
4548fa113e5SMark Murray 					     ticket->client,
4558fa113e5SMark Murray 					     UserNameRequested)) {
45681cb6ddcSMark Murray 	    Data(ap, KRB_ACCEPT, name, name ? -1 : 0);
45781cb6ddcSMark Murray 	    if (auth_debug_mode) {
45881cb6ddcSMark Murray 		printf("Kerberos5 identifies him as ``%s''\r\n",
45981cb6ddcSMark Murray 		       name ? name : "");
46081cb6ddcSMark Murray 	    }
46181cb6ddcSMark Murray 
4628fa113e5SMark Murray 	    if(key_block->keytype == ETYPE_DES_CBC_MD5 ||
4638fa113e5SMark Murray 	       key_block->keytype == ETYPE_DES_CBC_MD4 ||
4648fa113e5SMark Murray 	       key_block->keytype == ETYPE_DES_CBC_CRC) {
4658fa113e5SMark Murray 		Session_Key skey;
46681cb6ddcSMark Murray 
46781cb6ddcSMark Murray 		skey.type = SK_DES;
46881cb6ddcSMark Murray 		skey.length = 8;
4698fa113e5SMark Murray 		skey.data = key_block->keyvalue.data;
4708fa113e5SMark Murray 		encrypt_session_key(&skey, 0);
4718fa113e5SMark Murray 	    }
4728fa113e5SMark Murray 
4738fa113e5SMark Murray 	} else {
4748fa113e5SMark Murray 	    char *msg;
4758fa113e5SMark Murray 
4768fa113e5SMark Murray 	    asprintf (&msg, "user `%s' is not authorized to "
4778fa113e5SMark Murray 		      "login as `%s'",
4788fa113e5SMark Murray 		      name ? name : "<unknown>",
4798fa113e5SMark Murray 		      UserNameRequested ? UserNameRequested : "<nobody>");
4808fa113e5SMark Murray 	    if (msg == NULL)
4818fa113e5SMark Murray 		Data(ap, KRB_REJECT, NULL, 0);
4828fa113e5SMark Murray 	    else {
4838fa113e5SMark Murray 		Data(ap, KRB_REJECT, (void *)msg, -1);
4848fa113e5SMark Murray 		free(msg);
4858fa113e5SMark Murray 	    }
4868fa113e5SMark Murray 	    auth_finished (ap, AUTH_REJECT);
4878fa113e5SMark Murray 	    krb5_free_keyblock_contents(context, key_block);
48881cb6ddcSMark Murray 	    break;
4898fa113e5SMark Murray 	}
4908fa113e5SMark Murray 	auth_finished(ap, AUTH_USER);
4918fa113e5SMark Murray 	krb5_free_keyblock_contents(context, key_block);
4928fa113e5SMark Murray 
4938fa113e5SMark Murray 	break;
4948fa113e5SMark Murray     case KRB_FORWARD: {
4958fa113e5SMark Murray 	struct passwd *pwd;
4968fa113e5SMark Murray 	char ccname[1024];	/* XXX */
4978fa113e5SMark Murray 	krb5_data inbuf;
4988fa113e5SMark Murray 	krb5_ccache ccache;
49981cb6ddcSMark Murray 	inbuf.data = (char *)data;
50081cb6ddcSMark Murray 	inbuf.length = cnt;
50181cb6ddcSMark Murray 
5028fa113e5SMark Murray 	pwd = getpwnam (UserNameRequested);
5038fa113e5SMark Murray 	if (pwd == NULL)
5048fa113e5SMark Murray 	    break;
5058fa113e5SMark Murray 
5068fa113e5SMark Murray 	snprintf (ccname, sizeof(ccname),
5078fa113e5SMark Murray 		  "FILE:/tmp/krb5cc_%u", pwd->pw_uid);
5088fa113e5SMark Murray 
5098fa113e5SMark Murray 	ret = krb5_cc_resolve (context, ccname, &ccache);
5108fa113e5SMark Murray 	if (ret) {
5118fa113e5SMark Murray 	    if (auth_debug_mode)
5123ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: could not get ccache: %s\r\n");
5138fa113e5SMark Murray 	    break;
5148fa113e5SMark Murray 	}
5158fa113e5SMark Murray 
5168fa113e5SMark Murray 	ret = krb5_cc_initialize (context,
5178fa113e5SMark Murray 				  ccache,
5188fa113e5SMark Murray 				  ticket->client);
5198fa113e5SMark Murray 	if (ret) {
5208fa113e5SMark Murray 	    if (auth_debug_mode)
5213ef51c5fSStanislav Sedov 		print_krb5_error(context, ret, "Kerberos V5: could not init ccache: %s\r\n");
5228fa113e5SMark Murray 	    break;
5238fa113e5SMark Murray 	}
5248fa113e5SMark Murray 
5258fa113e5SMark Murray #if defined(DCE)
5268fa113e5SMark Murray 	esetenv("KRB5CCNAME", ccname, 1);
5278fa113e5SMark Murray #endif
5288fa113e5SMark Murray 	ret = krb5_rd_cred2 (context,
5298fa113e5SMark Murray 			     auth_context,
5308fa113e5SMark Murray 			     ccache,
5318fa113e5SMark Murray 			     &inbuf);
5328fa113e5SMark Murray 	if(ret) {
5338fa113e5SMark Murray 	    char *errbuf;
5343ef51c5fSStanislav Sedov 	    const char *err_str;
5358fa113e5SMark Murray 
5363ef51c5fSStanislav Sedov 	    err_str = krb5_get_error_message(context, ret);
5378fa113e5SMark Murray 	    asprintf (&errbuf,
5383ef51c5fSStanislav Sedov 		      "Read forwarded creds failed: %s", err_str);
5393ef51c5fSStanislav Sedov 	    krb5_free_error_message(context, err_str);
5408fa113e5SMark Murray 	    if(errbuf == NULL)
5418fa113e5SMark Murray 		Data(ap, KRB_FORWARD_REJECT, NULL, 0);
5428fa113e5SMark Murray 	    else
54381cb6ddcSMark Murray 		Data(ap, KRB_FORWARD_REJECT, errbuf, -1);
54481cb6ddcSMark Murray 	    if (auth_debug_mode)
5458fa113e5SMark Murray 		printf("Could not read forwarded credentials: %s\r\n",
5468fa113e5SMark Murray 		       errbuf);
5478fa113e5SMark Murray 	    free (errbuf);
5488fa113e5SMark Murray 	} else {
54981cb6ddcSMark Murray 	    Data(ap, KRB_FORWARD_ACCEPT, 0, 0);
5508fa113e5SMark Murray #if defined(DCE)
5518fa113e5SMark Murray 	    dfsfwd = 1;
5528fa113e5SMark Murray #endif
5538fa113e5SMark Murray 	}
5548fa113e5SMark Murray 	chown (ccname + 5, pwd->pw_uid, -1);
55581cb6ddcSMark Murray 	if (auth_debug_mode)
55681cb6ddcSMark Murray 	    printf("Forwarded credentials obtained\r\n");
55781cb6ddcSMark Murray 	break;
5588fa113e5SMark Murray     }
55981cb6ddcSMark Murray     default:
56081cb6ddcSMark Murray 	if (auth_debug_mode)
56181cb6ddcSMark Murray 	    printf("Unknown Kerberos option %d\r\n", data[-1]);
56281cb6ddcSMark Murray 	Data(ap, KRB_REJECT, 0, 0);
56381cb6ddcSMark Murray 	break;
56481cb6ddcSMark Murray     }
56581cb6ddcSMark Murray }
56681cb6ddcSMark Murray 
56781cb6ddcSMark Murray void
kerberos5_reply(Authenticator * ap,unsigned char * data,int cnt)5688fa113e5SMark Murray kerberos5_reply(Authenticator *ap, unsigned char *data, int cnt)
56981cb6ddcSMark Murray {
57081cb6ddcSMark Murray     static int mutual_complete = 0;
57181cb6ddcSMark Murray 
57281cb6ddcSMark Murray     if (cnt-- < 1)
57381cb6ddcSMark Murray 	return;
57481cb6ddcSMark Murray     switch (*data++) {
57581cb6ddcSMark Murray     case KRB_REJECT:
57681cb6ddcSMark Murray 	if (cnt > 0) {
57781cb6ddcSMark Murray 	    printf("[ Kerberos V5 refuses authentication because %.*s ]\r\n",
57881cb6ddcSMark Murray 		   cnt, data);
57981cb6ddcSMark Murray 	} else
58081cb6ddcSMark Murray 	    printf("[ Kerberos V5 refuses authentication ]\r\n");
58181cb6ddcSMark Murray 	auth_send_retry();
58281cb6ddcSMark Murray 	return;
5838fa113e5SMark Murray     case KRB_ACCEPT: {
5848fa113e5SMark Murray 	krb5_error_code ret;
5858fa113e5SMark Murray 	Session_Key skey;
5868fa113e5SMark Murray 	krb5_keyblock *keyblock;
5878fa113e5SMark Murray 
58881cb6ddcSMark Murray 	if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL &&
58981cb6ddcSMark Murray 	    !mutual_complete) {
5908fa113e5SMark Murray 	    printf("[ Kerberos V5 accepted you, but didn't provide mutual authentication! ]\r\n");
59181cb6ddcSMark Murray 	    auth_send_retry();
59281cb6ddcSMark Murray 	    return;
59381cb6ddcSMark Murray 	}
59481cb6ddcSMark Murray 	if (cnt)
5958fa113e5SMark Murray 	    printf("[ Kerberos V5 accepts you as ``%.*s'' ]\r\n", cnt, data);
59681cb6ddcSMark Murray 	else
5978fa113e5SMark Murray 	    printf("[ Kerberos V5 accepts you ]\r\n");
5988fa113e5SMark Murray 
5998fa113e5SMark Murray 	ret = krb5_auth_con_getlocalsubkey (context,
6008fa113e5SMark Murray 					    auth_context,
6018fa113e5SMark Murray 					    &keyblock);
6028fa113e5SMark Murray 	if (ret)
6038fa113e5SMark Murray 	    ret = krb5_auth_con_getkey (context,
6048fa113e5SMark Murray 					auth_context,
6058fa113e5SMark Murray 					&keyblock);
6068fa113e5SMark Murray 	if(ret) {
6073ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "[ krb5_auth_con_getkey: %s ]\r\n");
6088fa113e5SMark Murray 	    auth_send_retry();
6098fa113e5SMark Murray 	    return;
6108fa113e5SMark Murray 	}
6118fa113e5SMark Murray 
6128fa113e5SMark Murray 	skey.type = SK_DES;
6138fa113e5SMark Murray 	skey.length = 8;
6148fa113e5SMark Murray 	skey.data = keyblock->keyvalue.data;
6158fa113e5SMark Murray 	encrypt_session_key(&skey, 0);
6168fa113e5SMark Murray 	krb5_free_keyblock_contents (context, keyblock);
61781cb6ddcSMark Murray 	auth_finished(ap, AUTH_USER);
61881cb6ddcSMark Murray 	if (forward_flags & OPTS_FORWARD_CREDS)
61981cb6ddcSMark Murray 	    kerberos5_forward(ap);
62081cb6ddcSMark Murray 	break;
6218fa113e5SMark Murray     }
62281cb6ddcSMark Murray     case KRB_RESPONSE:
62381cb6ddcSMark Murray 	if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
62481cb6ddcSMark Murray 	    /* the rest of the reply should contain a krb_ap_rep */
62581cb6ddcSMark Murray 	  krb5_ap_rep_enc_part *reply;
62681cb6ddcSMark Murray 	  krb5_data inbuf;
6278fa113e5SMark Murray 	  krb5_error_code ret;
62881cb6ddcSMark Murray 
62981cb6ddcSMark Murray 	  inbuf.length = cnt;
63081cb6ddcSMark Murray 	  inbuf.data = (char *)data;
63181cb6ddcSMark Murray 
6328fa113e5SMark Murray 	  ret = krb5_rd_rep(context, auth_context, &inbuf, &reply);
6338fa113e5SMark Murray 	  if (ret) {
6343ef51c5fSStanislav Sedov 	      print_krb5_error(context, ret, "[ Mutual authentication failed: %s ]\r\n");
63581cb6ddcSMark Murray 	      auth_send_retry();
63681cb6ddcSMark Murray 	      return;
63781cb6ddcSMark Murray 	  }
6388fa113e5SMark Murray 	  krb5_free_ap_rep_enc_part(context, reply);
63981cb6ddcSMark Murray 	  mutual_complete = 1;
64081cb6ddcSMark Murray 	}
64181cb6ddcSMark Murray 	return;
64281cb6ddcSMark Murray     case KRB_FORWARD_ACCEPT:
6438fa113e5SMark Murray 	printf("[ Kerberos V5 accepted forwarded credentials ]\r\n");
64481cb6ddcSMark Murray 	return;
64581cb6ddcSMark Murray     case KRB_FORWARD_REJECT:
64681cb6ddcSMark Murray 	printf("[ Kerberos V5 refuses forwarded credentials because %.*s ]\r\n",
64781cb6ddcSMark Murray 	       cnt, data);
64881cb6ddcSMark Murray 	return;
64981cb6ddcSMark Murray     default:
65081cb6ddcSMark Murray 	if (auth_debug_mode)
65181cb6ddcSMark Murray 	    printf("Unknown Kerberos option %d\r\n", data[-1]);
65281cb6ddcSMark Murray 	return;
65381cb6ddcSMark Murray     }
65481cb6ddcSMark Murray }
65581cb6ddcSMark Murray 
65681cb6ddcSMark Murray int
kerberos5_status(Authenticator * ap __unused,char * name,int level)6578fa113e5SMark Murray kerberos5_status(Authenticator *ap __unused, char *name, int level)
65881cb6ddcSMark Murray {
65981cb6ddcSMark Murray     if (level < AUTH_USER)
66081cb6ddcSMark Murray 	return(level);
66181cb6ddcSMark Murray 
66281cb6ddcSMark Murray     if (UserNameRequested &&
6638fa113e5SMark Murray 	krb5_kuserok(context,
6648fa113e5SMark Murray 		     ticket->client,
6658fa113e5SMark Murray 		     UserNameRequested))
66681cb6ddcSMark Murray 	{
66781cb6ddcSMark Murray 	    strcpy(name, UserNameRequested);
66881cb6ddcSMark Murray 	    return(AUTH_VALID);
66981cb6ddcSMark Murray 	} else
67081cb6ddcSMark Murray 	    return(AUTH_USER);
67181cb6ddcSMark Murray }
67281cb6ddcSMark Murray 
67381cb6ddcSMark Murray #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len);}
67481cb6ddcSMark Murray #define	ADDC(buf, len, c)	if ((len) > 0) {*(buf)++ = (c); --(len);}
67581cb6ddcSMark Murray 
67681cb6ddcSMark Murray void
kerberos5_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)6778fa113e5SMark Murray kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
67881cb6ddcSMark Murray {
6798fa113e5SMark Murray     int i;
68081cb6ddcSMark Murray 
68181cb6ddcSMark Murray     buf[buflen-1] = '\0';		/* make sure its NULL terminated */
68281cb6ddcSMark Murray     buflen -= 1;
68381cb6ddcSMark Murray 
68481cb6ddcSMark Murray     switch(data[3]) {
68581cb6ddcSMark Murray     case KRB_REJECT:		/* Rejected (reason might follow) */
6868fa113e5SMark Murray 	strlcpy((char *)buf, " REJECT ", buflen);
68781cb6ddcSMark Murray 	goto common;
68881cb6ddcSMark Murray 
68981cb6ddcSMark Murray     case KRB_ACCEPT:		/* Accepted (name might follow) */
6908fa113e5SMark Murray 	strlcpy((char *)buf, " ACCEPT ", buflen);
69181cb6ddcSMark Murray     common:
69281cb6ddcSMark Murray 	BUMP(buf, buflen);
69381cb6ddcSMark Murray 	if (cnt <= 4)
69481cb6ddcSMark Murray 	    break;
69581cb6ddcSMark Murray 	ADDC(buf, buflen, '"');
69681cb6ddcSMark Murray 	for (i = 4; i < cnt; i++)
69781cb6ddcSMark Murray 	    ADDC(buf, buflen, data[i]);
69881cb6ddcSMark Murray 	ADDC(buf, buflen, '"');
69981cb6ddcSMark Murray 	ADDC(buf, buflen, '\0');
70081cb6ddcSMark Murray 	break;
70181cb6ddcSMark Murray 
70281cb6ddcSMark Murray 
70381cb6ddcSMark Murray     case KRB_AUTH:			/* Authentication data follows */
7048fa113e5SMark Murray 	strlcpy((char *)buf, " AUTH", buflen);
70581cb6ddcSMark Murray 	goto common2;
70681cb6ddcSMark Murray 
70781cb6ddcSMark Murray     case KRB_RESPONSE:
7088fa113e5SMark Murray 	strlcpy((char *)buf, " RESPONSE", buflen);
70981cb6ddcSMark Murray 	goto common2;
71081cb6ddcSMark Murray 
71181cb6ddcSMark Murray     case KRB_FORWARD:		/* Forwarded credentials follow */
7128fa113e5SMark Murray 	strlcpy((char *)buf, " FORWARD", buflen);
71381cb6ddcSMark Murray 	goto common2;
71481cb6ddcSMark Murray 
71581cb6ddcSMark Murray     case KRB_FORWARD_ACCEPT:	/* Forwarded credentials accepted */
7168fa113e5SMark Murray 	strlcpy((char *)buf, " FORWARD_ACCEPT", buflen);
71781cb6ddcSMark Murray 	goto common2;
71881cb6ddcSMark Murray 
71981cb6ddcSMark Murray     case KRB_FORWARD_REJECT:	/* Forwarded credentials rejected */
72081cb6ddcSMark Murray 	/* (reason might follow) */
7218fa113e5SMark Murray 	strlcpy((char *)buf, " FORWARD_REJECT", buflen);
72281cb6ddcSMark Murray 	goto common2;
72381cb6ddcSMark Murray 
72481cb6ddcSMark Murray     default:
7258fa113e5SMark Murray 	snprintf(buf, buflen, " %d (unknown)", data[3]);
72681cb6ddcSMark Murray     common2:
72781cb6ddcSMark Murray 	BUMP(buf, buflen);
72881cb6ddcSMark Murray 	for (i = 4; i < cnt; i++) {
7298fa113e5SMark Murray 	    snprintf(buf, buflen, " %d", data[i]);
73081cb6ddcSMark Murray 	    BUMP(buf, buflen);
73181cb6ddcSMark Murray 	}
73281cb6ddcSMark Murray 	break;
73381cb6ddcSMark Murray     }
73481cb6ddcSMark Murray }
73581cb6ddcSMark Murray 
73681cb6ddcSMark Murray void
kerberos5_forward(Authenticator * ap)7378fa113e5SMark Murray kerberos5_forward(Authenticator *ap)
73881cb6ddcSMark Murray {
7398fa113e5SMark Murray     krb5_error_code ret;
74081cb6ddcSMark Murray     krb5_ccache     ccache;
7418fa113e5SMark Murray     krb5_creds      creds;
7428fa113e5SMark Murray     krb5_kdc_flags  flags;
7438fa113e5SMark Murray     krb5_data       out_data;
7448fa113e5SMark Murray     krb5_principal  principal;
74581cb6ddcSMark Murray 
7468fa113e5SMark Murray     ret = krb5_cc_default (context, &ccache);
7478fa113e5SMark Murray     if (ret) {
74881cb6ddcSMark Murray 	if (auth_debug_mode)
7493ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "KerberosV5: could not get default ccache: %s\r\n");
75081cb6ddcSMark Murray 	return;
75181cb6ddcSMark Murray     }
75281cb6ddcSMark Murray 
7538fa113e5SMark Murray     ret = krb5_cc_get_principal (context, ccache, &principal);
7548fa113e5SMark Murray     if (ret) {
75581cb6ddcSMark Murray 	if (auth_debug_mode)
7563ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "KerberosV5: could not get principal: %s\r\n");
75781cb6ddcSMark Murray 	return;
75881cb6ddcSMark Murray     }
75981cb6ddcSMark Murray 
7608fa113e5SMark Murray     memset (&creds, 0, sizeof(creds));
7618fa113e5SMark Murray 
7628fa113e5SMark Murray     creds.client = principal;
7638fa113e5SMark Murray 
7648fa113e5SMark Murray     ret = krb5_build_principal (context,
7658fa113e5SMark Murray 				&creds.server,
7668fa113e5SMark Murray 				strlen(principal->realm),
7678fa113e5SMark Murray 				principal->realm,
7688fa113e5SMark Murray 				"krbtgt",
7698fa113e5SMark Murray 				principal->realm,
7708fa113e5SMark Murray 				NULL);
7718fa113e5SMark Murray 
7728fa113e5SMark Murray     if (ret) {
77381cb6ddcSMark Murray 	if (auth_debug_mode)
7743ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "KerberosV5: could not get principal: %s\r\n");
77581cb6ddcSMark Murray 	return;
77681cb6ddcSMark Murray     }
77781cb6ddcSMark Murray 
7788fa113e5SMark Murray     creds.times.endtime = 0;
77981cb6ddcSMark Murray 
7808fa113e5SMark Murray     flags.i = 0;
7818fa113e5SMark Murray     flags.b.forwarded = 1;
7828fa113e5SMark Murray     if (forward_flags & OPTS_FORWARDABLE_CREDS)
7838fa113e5SMark Murray 	flags.b.forwardable = 1;
78481cb6ddcSMark Murray 
7858fa113e5SMark Murray     ret = krb5_get_forwarded_creds (context,
7868fa113e5SMark Murray 				    auth_context,
7878fa113e5SMark Murray 				    ccache,
7888fa113e5SMark Murray 				    flags.i,
78981cb6ddcSMark Murray 				    RemoteHostName,
7908fa113e5SMark Murray 				    &creds,
7918fa113e5SMark Murray 				    &out_data);
7928fa113e5SMark Murray     if (ret) {
79381cb6ddcSMark Murray 	if (auth_debug_mode)
7943ef51c5fSStanislav Sedov 	    print_krb5_error(context, ret, "Kerberos V5: error getting forwarded creds: %s\r\n");
79581cb6ddcSMark Murray 	return;
79681cb6ddcSMark Murray     }
79781cb6ddcSMark Murray 
7988fa113e5SMark Murray     if(!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) {
79981cb6ddcSMark Murray 	if (auth_debug_mode)
80081cb6ddcSMark Murray 	    printf("Not enough room for authentication data\r\n");
8018fa113e5SMark Murray     } else {
80281cb6ddcSMark Murray 	if (auth_debug_mode)
80381cb6ddcSMark Murray 	    printf("Forwarded local Kerberos V5 credentials to server\r\n");
80481cb6ddcSMark Murray     }
80581cb6ddcSMark Murray }
8068fa113e5SMark Murray 
8078fa113e5SMark Murray #if defined(DCE)
8088fa113e5SMark Murray /* if this was a K5 authentication try and join a PAG for the user. */
8098fa113e5SMark Murray void
kerberos5_dfspag(void)8108fa113e5SMark Murray kerberos5_dfspag(void)
8118fa113e5SMark Murray {
8128fa113e5SMark Murray     if (dfsk5ok) {
8138fa113e5SMark Murray 	dfspag = krb5_dfs_pag(context, dfsfwd, ticket->client,
8148fa113e5SMark Murray 			      UserNameRequested);
8158fa113e5SMark Murray     }
8168fa113e5SMark Murray }
8178fa113e5SMark Murray #endif
81881cb6ddcSMark Murray 
81981cb6ddcSMark Murray #endif /* KRB5 */
820