xref: /titanic_41/usr/src/cmd/cmd-inet/usr.bin/telnet/kerberos5.c (revision fe598cdcd847f8359013532d5c691bb6190378c0)
17c478bd9Sstevel@tonic-gate /*
2*fe598cdcSmp153739  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
37c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate  */
57c478bd9Sstevel@tonic-gate 
67c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
77c478bd9Sstevel@tonic-gate 
87c478bd9Sstevel@tonic-gate /*
97c478bd9Sstevel@tonic-gate  * usr/src/cmd/cmd-inet/usr.bin/telnet/kerberos5.c
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * Copyright (c) 1991, 1993
127c478bd9Sstevel@tonic-gate  *	The Regents of the University of California.  All rights reserved.
137c478bd9Sstevel@tonic-gate  *
147c478bd9Sstevel@tonic-gate  * Redistribution and use in source and binary forms, with or without
157c478bd9Sstevel@tonic-gate  * modification, are permitted provided that the following conditions
167c478bd9Sstevel@tonic-gate  * are met:
177c478bd9Sstevel@tonic-gate  * 1. Redistributions of source code must retain the above copyright
187c478bd9Sstevel@tonic-gate  *	notice, this list of conditions and the following disclaimer.
197c478bd9Sstevel@tonic-gate  * 2. Redistributions in binary form must reproduce the above copyright
207c478bd9Sstevel@tonic-gate  *	notice, this list of conditions and the following disclaimer in the
217c478bd9Sstevel@tonic-gate  *	documentation and/or other materials provided with the distribution.
227c478bd9Sstevel@tonic-gate  * 3. All advertising materials mentioning features or use of this software
237c478bd9Sstevel@tonic-gate  *	must display the following acknowledgement:
247c478bd9Sstevel@tonic-gate  *	This product includes software developed by the University of
257c478bd9Sstevel@tonic-gate  *	California, Berkeley and its contributors.
267c478bd9Sstevel@tonic-gate  * 4. Neither the name of the University nor the names of its contributors
277c478bd9Sstevel@tonic-gate  *	may be used to endorse or promote products derived from this software
287c478bd9Sstevel@tonic-gate  *	without specific prior written permission.
297c478bd9Sstevel@tonic-gate  *
307c478bd9Sstevel@tonic-gate  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
317c478bd9Sstevel@tonic-gate  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
327c478bd9Sstevel@tonic-gate  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
337c478bd9Sstevel@tonic-gate  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
347c478bd9Sstevel@tonic-gate  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
357c478bd9Sstevel@tonic-gate  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
367c478bd9Sstevel@tonic-gate  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
377c478bd9Sstevel@tonic-gate  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
387c478bd9Sstevel@tonic-gate  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
397c478bd9Sstevel@tonic-gate  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
407c478bd9Sstevel@tonic-gate  * SUCH DAMAGE.
417c478bd9Sstevel@tonic-gate  */
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate /* based on @(#)kerberos5.c	8.1 (Berkeley) 6/4/93 */
447c478bd9Sstevel@tonic-gate 
457c478bd9Sstevel@tonic-gate /*
467c478bd9Sstevel@tonic-gate  * Copyright (C) 1990 by the Massachusetts Institute of Technology
477c478bd9Sstevel@tonic-gate  *
487c478bd9Sstevel@tonic-gate  * Export of this software from the United States of America may
497c478bd9Sstevel@tonic-gate  * require a specific license from the United States Government.
507c478bd9Sstevel@tonic-gate  * It is the responsibility of any person or organization contemplating
517c478bd9Sstevel@tonic-gate  * export to obtain such a license before exporting.
527c478bd9Sstevel@tonic-gate  *
537c478bd9Sstevel@tonic-gate  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
547c478bd9Sstevel@tonic-gate  * distribute this software and its documentation for any purpose and
557c478bd9Sstevel@tonic-gate  * without fee is hereby granted, provided that the above copyright
567c478bd9Sstevel@tonic-gate  * notice appear in all copies and that both that copyright notice and
577c478bd9Sstevel@tonic-gate  * this permission notice appear in supporting documentation, and that
587c478bd9Sstevel@tonic-gate  * the name of M.I.T. not be used in advertising or publicity pertaining
597c478bd9Sstevel@tonic-gate  * to distribution of the software without specific, written prior
607c478bd9Sstevel@tonic-gate  * permission.  Furthermore if you modify this software you must label
617c478bd9Sstevel@tonic-gate  * your software as modified software and not distribute it in such a
627c478bd9Sstevel@tonic-gate  * fashion that it might be confused with the original M.I.T. software.
637c478bd9Sstevel@tonic-gate  * M.I.T. makes no representations about the suitability of
647c478bd9Sstevel@tonic-gate  * this software for any purpose.  It is provided "as is" without express
657c478bd9Sstevel@tonic-gate  * or implied warranty.
667c478bd9Sstevel@tonic-gate  */
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate #include <arpa/telnet.h>
707c478bd9Sstevel@tonic-gate #include <stdio.h>
717c478bd9Sstevel@tonic-gate #include <ctype.h>
727c478bd9Sstevel@tonic-gate #include <syslog.h>
737c478bd9Sstevel@tonic-gate #include <stdlib.h>
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate /* the following are from the kerberos tree */
767c478bd9Sstevel@tonic-gate #include <k5-int.h>
777c478bd9Sstevel@tonic-gate #include <com_err.h>
787c478bd9Sstevel@tonic-gate #include <netdb.h>
797c478bd9Sstevel@tonic-gate #include <profile/prof_int.h>
807c478bd9Sstevel@tonic-gate #include <sys/param.h>
817c478bd9Sstevel@tonic-gate #include "externs.h"
827c478bd9Sstevel@tonic-gate 
837c478bd9Sstevel@tonic-gate extern	char *RemoteHostName;
847c478bd9Sstevel@tonic-gate extern	boolean_t auth_debug_mode;
857c478bd9Sstevel@tonic-gate extern	int net;
867c478bd9Sstevel@tonic-gate 
87ef2b2792Smp153739 #define	ACCEPTED_ENCTYPE(a) \
88ef2b2792Smp153739 	(a == ENCTYPE_DES_CBC_CRC || a == ENCTYPE_DES_CBC_MD5)
897c478bd9Sstevel@tonic-gate /* for comapatibility with non-Solaris KDC's, this has to be big enough */
907c478bd9Sstevel@tonic-gate #define	KERBEROS_BUFSIZ	8192
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate int	forward_flags = 0;  /* Flags get set in telnet/main.c on -f and -F */
937c478bd9Sstevel@tonic-gate static	void kerberos5_forward(Authenticator *);
947c478bd9Sstevel@tonic-gate 
957c478bd9Sstevel@tonic-gate static	unsigned char str_data[KERBEROS_BUFSIZ] = { IAC, SB,
967c478bd9Sstevel@tonic-gate 		TELOPT_AUTHENTICATION, 0, AUTHTYPE_KERBEROS_V5, };
977c478bd9Sstevel@tonic-gate static	char *appdef[] = { "appdefaults", "telnet", NULL };
987c478bd9Sstevel@tonic-gate static	char *realmdef[] = { "realms", NULL, "telnet", NULL };
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate static	krb5_auth_context auth_context = 0;
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate static	krb5_data auth;	/* telnetd gets session key from here */
1037c478bd9Sstevel@tonic-gate static	krb5_ticket *ticket = NULL;
1047c478bd9Sstevel@tonic-gate 	/* telnet matches the AP_REQ and AP_REP with this */
1057c478bd9Sstevel@tonic-gate 
1067c478bd9Sstevel@tonic-gate static	krb5_keyblock	*session_key = 0;
1077c478bd9Sstevel@tonic-gate char	*telnet_krb5_realm = NULL;
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate /*
1107c478bd9Sstevel@tonic-gate  * Change the kerberos realm
1117c478bd9Sstevel@tonic-gate  */
1127c478bd9Sstevel@tonic-gate void
set_krb5_realm(char * name)1137c478bd9Sstevel@tonic-gate set_krb5_realm(char *name)
1147c478bd9Sstevel@tonic-gate {
1157c478bd9Sstevel@tonic-gate 	if (name == NULL) {
1167c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext("Could not set Kerberos realm, "
1177c478bd9Sstevel@tonic-gate 			"no realm provided.\n"));
1187c478bd9Sstevel@tonic-gate 		return;
1197c478bd9Sstevel@tonic-gate 	}
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate 	if (telnet_krb5_realm)
1227c478bd9Sstevel@tonic-gate 		free(telnet_krb5_realm);
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	telnet_krb5_realm = (char *)strdup(name);
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	if (telnet_krb5_realm == NULL)
1277c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(
1287c478bd9Sstevel@tonic-gate 			"Could not set Kerberos realm, malloc failed\n"));
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate 
1317c478bd9Sstevel@tonic-gate #define	RETURN_NOMEM	{ errno = ENOMEM; return (-1); }
1327c478bd9Sstevel@tonic-gate 
1337c478bd9Sstevel@tonic-gate static int
krb5_send_data(Authenticator * ap,int type,krb5_pointer d,int c)1347c478bd9Sstevel@tonic-gate krb5_send_data(Authenticator *ap, int type, krb5_pointer d, int c)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate 	/* the first 3 bytes are control chars */
1377c478bd9Sstevel@tonic-gate 	unsigned char *p = str_data + 4;
1387c478bd9Sstevel@tonic-gate 	unsigned char *cd = (unsigned char *)d;
1397c478bd9Sstevel@tonic-gate 	/* spaceleft is incremented whenever p is decremented */
1407c478bd9Sstevel@tonic-gate 	size_t spaceleft = sizeof (str_data) - 4;
1417c478bd9Sstevel@tonic-gate 
1427c478bd9Sstevel@tonic-gate 	if (c == -1)
1437c478bd9Sstevel@tonic-gate 		c = strlen((char *)cd);
1447c478bd9Sstevel@tonic-gate 
1457c478bd9Sstevel@tonic-gate 	if (auth_debug_mode) {
1467c478bd9Sstevel@tonic-gate 		(void) printf("%s:%d: [%d] (%d)",
1477c478bd9Sstevel@tonic-gate 			str_data[3] == TELQUAL_IS ? ">>>IS" : ">>>REPLY",
1487c478bd9Sstevel@tonic-gate 			str_data[3], type, c);
1497c478bd9Sstevel@tonic-gate 		printd(d, c);
1507c478bd9Sstevel@tonic-gate 		(void) printf("\r\n");
1517c478bd9Sstevel@tonic-gate 	}
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	if (spaceleft < 3)
1547c478bd9Sstevel@tonic-gate 		RETURN_NOMEM;
1557c478bd9Sstevel@tonic-gate 	*p++ = ap->type;
1567c478bd9Sstevel@tonic-gate 	*p++ = ap->way;
1577c478bd9Sstevel@tonic-gate 	*p++ = type;
1587c478bd9Sstevel@tonic-gate 	spaceleft -= 3;
1597c478bd9Sstevel@tonic-gate 
1607c478bd9Sstevel@tonic-gate 	while (c-- > 0) {
1617c478bd9Sstevel@tonic-gate 		if (spaceleft < 2)
1627c478bd9Sstevel@tonic-gate 			RETURN_NOMEM;
1637c478bd9Sstevel@tonic-gate 		if ((*p++ = *cd++) == IAC) {
1647c478bd9Sstevel@tonic-gate 			*p++ = IAC;
1657c478bd9Sstevel@tonic-gate 			spaceleft -= 2;
1667c478bd9Sstevel@tonic-gate 		}
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 
1697c478bd9Sstevel@tonic-gate 	if (spaceleft < 2)
1707c478bd9Sstevel@tonic-gate 		RETURN_NOMEM;
1717c478bd9Sstevel@tonic-gate 	*p++ = IAC;
1727c478bd9Sstevel@tonic-gate 	*p++ = SE;
1737c478bd9Sstevel@tonic-gate 	if (str_data[3] == TELQUAL_IS)
1747c478bd9Sstevel@tonic-gate 		printsub('>', &str_data[2], p - &str_data[2]);
1757c478bd9Sstevel@tonic-gate 	return (net_write(str_data, p - str_data));
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate krb5_context telnet_context = 0;
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /* ARGSUSED */
1817c478bd9Sstevel@tonic-gate int
kerberos5_init(Authenticator * ap)1827c478bd9Sstevel@tonic-gate kerberos5_init(Authenticator *ap)
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate 	str_data[3] = TELQUAL_IS;
1877c478bd9Sstevel@tonic-gate 	if (krb5auth_flag && (telnet_context == 0)) {
1887c478bd9Sstevel@tonic-gate 		retval = krb5_init_context(&telnet_context);
1897c478bd9Sstevel@tonic-gate 		if (retval)
1907c478bd9Sstevel@tonic-gate 			return (0);
1917c478bd9Sstevel@tonic-gate 	}
1927c478bd9Sstevel@tonic-gate 	return (1);
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate int
kerberos5_send(Authenticator * ap)1967c478bd9Sstevel@tonic-gate kerberos5_send(Authenticator *ap)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
1997c478bd9Sstevel@tonic-gate 	krb5_ccache ccache;
2007c478bd9Sstevel@tonic-gate 	krb5_creds creds;		/* telnet gets session key from here */
2017c478bd9Sstevel@tonic-gate 	krb5_creds *new_creds = 0;
2027c478bd9Sstevel@tonic-gate 	int ap_opts;
2037c478bd9Sstevel@tonic-gate 	char type_check[2];
2047c478bd9Sstevel@tonic-gate 	krb5_data check_data;
2057c478bd9Sstevel@tonic-gate 
2067c478bd9Sstevel@tonic-gate 	krb5_keyblock *newkey = 0;
2077c478bd9Sstevel@tonic-gate 
208ef2b2792Smp153739 	int i;
209ef2b2792Smp153739 	krb5_enctype *ktypes;
210ef2b2792Smp153739 
2117c478bd9Sstevel@tonic-gate 	if (!UserNameRequested) {
2127c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
2137c478bd9Sstevel@tonic-gate 			(void) printf(gettext("telnet: Kerberos V5: "
2147c478bd9Sstevel@tonic-gate 				"no user name supplied\r\n"));
2157c478bd9Sstevel@tonic-gate 		return (0);
2167c478bd9Sstevel@tonic-gate 	}
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 	if ((retval = krb5_cc_default(telnet_context, &ccache))) {
2197c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
2207c478bd9Sstevel@tonic-gate 		    (void) printf(gettext("telnet: Kerberos V5: "
2217c478bd9Sstevel@tonic-gate 			"could not get default ccache\r\n"));
2227c478bd9Sstevel@tonic-gate 		return (0);
2237c478bd9Sstevel@tonic-gate 	}
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	(void) memset((char *)&creds, 0, sizeof (creds));
226*fe598cdcSmp153739 	if (auth_debug_mode)
227*fe598cdcSmp153739 		printf("telnet: calling krb5_sname_to_principal\n");
2287c478bd9Sstevel@tonic-gate 	if ((retval = krb5_sname_to_principal(telnet_context, RemoteHostName,
2297c478bd9Sstevel@tonic-gate 		"host", KRB5_NT_SRV_HST, &creds.server))) {
2307c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
2317c478bd9Sstevel@tonic-gate 		    (void) printf(gettext("telnet: Kerberos V5: error "
2327c478bd9Sstevel@tonic-gate 			"while constructing service name: %s\r\n"),
2337c478bd9Sstevel@tonic-gate 			error_message(retval));
2347c478bd9Sstevel@tonic-gate 		return (0);
2357c478bd9Sstevel@tonic-gate 	}
236*fe598cdcSmp153739 	if (auth_debug_mode)
237*fe598cdcSmp153739 		printf("telnet: done calling krb5_sname_to_principal\n");
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	if (telnet_krb5_realm != NULL) {
2407c478bd9Sstevel@tonic-gate 		krb5_data rdata;
2417c478bd9Sstevel@tonic-gate 
242*fe598cdcSmp153739 		rdata.magic = 0;
2437c478bd9Sstevel@tonic-gate 		rdata.length = strlen(telnet_krb5_realm);
2447c478bd9Sstevel@tonic-gate 		rdata.data = (char *)malloc(rdata.length + 1);
2457c478bd9Sstevel@tonic-gate 		if (rdata.data == NULL) {
2467c478bd9Sstevel@tonic-gate 			(void) fprintf(stderr, gettext("malloc failed\n"));
2477c478bd9Sstevel@tonic-gate 			return (0);
2487c478bd9Sstevel@tonic-gate 		}
2497c478bd9Sstevel@tonic-gate 		(void) strcpy(rdata.data, telnet_krb5_realm);
2507c478bd9Sstevel@tonic-gate 		krb5_princ_set_realm(telnet_context, creds.server, &rdata);
2517c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
2527c478bd9Sstevel@tonic-gate 		    (void) printf(gettext(
2537c478bd9Sstevel@tonic-gate 			"telnet: Kerberos V5: set kerberos realm to %s\r\n"),
2547c478bd9Sstevel@tonic-gate 			telnet_krb5_realm);
2557c478bd9Sstevel@tonic-gate 	}
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 	if ((retval = krb5_cc_get_principal(telnet_context, ccache,
2587c478bd9Sstevel@tonic-gate 		&creds.client)) != NULL) {
2597c478bd9Sstevel@tonic-gate 		if (auth_debug_mode) {
2607c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
2617c478bd9Sstevel@tonic-gate 			    "telnet: Kerberos V5: failure on principal "
2627c478bd9Sstevel@tonic-gate 			    "(%s)\r\n"), error_message(retval));
2637c478bd9Sstevel@tonic-gate 		}
2647c478bd9Sstevel@tonic-gate 		krb5_free_cred_contents(telnet_context, &creds);
2657c478bd9Sstevel@tonic-gate 		return (0);
2667c478bd9Sstevel@tonic-gate 	}
267ef2b2792Smp153739 /*
268ef2b2792Smp153739  * Check to to confirm that at least one of the supported
269ef2b2792Smp153739  * encryption types (des-cbc-md5, des-cbc-crc is available. If
270ef2b2792Smp153739  * one is available then use it to obtain credentials.
271ef2b2792Smp153739  */
2727c478bd9Sstevel@tonic-gate 
273ef2b2792Smp153739 	if ((retval = krb5_get_tgs_ktypes(telnet_context, creds.server,
274ef2b2792Smp153739 		&ktypes))) {
275ef2b2792Smp153739 		if (auth_debug_mode) {
276ef2b2792Smp153739 			(void) printf(gettext(
277ef2b2792Smp153739 			    "telnet: Kerberos V5: could not determine "
278ef2b2792Smp153739 				"TGS encryption types "
279ef2b2792Smp153739 				"(see default_tgs_enctypes in krb5.conf) "
280ef2b2792Smp153739 			    "(%s)\r\n"), error_message(retval));
281ef2b2792Smp153739 		}
282ef2b2792Smp153739 		krb5_free_cred_contents(telnet_context, &creds);
283ef2b2792Smp153739 		return (0);
284ef2b2792Smp153739 	}
285ef2b2792Smp153739 
286ef2b2792Smp153739 	for (i = 0; ktypes[i]; i++) {
287ef2b2792Smp153739 		if (ACCEPTED_ENCTYPE(ktypes[i]))
288ef2b2792Smp153739 			break;
289ef2b2792Smp153739 	}
290ef2b2792Smp153739 
291ef2b2792Smp153739 	if (ktypes[i] == 0) {
292ef2b2792Smp153739 		if (auth_debug_mode) {
293ef2b2792Smp153739 			(void) printf(gettext(
294ef2b2792Smp153739 				"telnet: Kerberos V5: "
295ef2b2792Smp153739 				"failure on encryption types. "
296ef2b2792Smp153739 				"Cannot find des-cbc-md5 or des-cbc-crc "
297ef2b2792Smp153739 				"in list of TGS encryption types "
298ef2b2792Smp153739 				"(see default_tgs_enctypes in krb5.conf)\n"));
299ef2b2792Smp153739 		}
300ef2b2792Smp153739 		krb5_free_cred_contents(telnet_context, &creds);
301ef2b2792Smp153739 		return (0);
302ef2b2792Smp153739 	}
303ef2b2792Smp153739 
304ef2b2792Smp153739 	creds.keyblock.enctype = ktypes[i];
3057c478bd9Sstevel@tonic-gate 	if ((retval = krb5_get_credentials(telnet_context, 0,
3067c478bd9Sstevel@tonic-gate 		ccache, &creds, &new_creds))) {
3077c478bd9Sstevel@tonic-gate 		if (auth_debug_mode) {
3087c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3097c478bd9Sstevel@tonic-gate 			    "telnet: Kerberos V5: failure on credentials "
3107c478bd9Sstevel@tonic-gate 			    "(%s)\r\n"), error_message(retval));
3117c478bd9Sstevel@tonic-gate 		}
3127c478bd9Sstevel@tonic-gate 		krb5_free_cred_contents(telnet_context, &creds);
3137c478bd9Sstevel@tonic-gate 		return (0);
3147c478bd9Sstevel@tonic-gate 	}
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate 	ap_opts = ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) ?
3177c478bd9Sstevel@tonic-gate 			AP_OPTS_MUTUAL_REQUIRED : 0;
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	ap_opts |= AP_OPTS_USE_SUBKEY;
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate 	if (auth_context) {
3227c478bd9Sstevel@tonic-gate 		krb5_auth_con_free(telnet_context, auth_context);
3237c478bd9Sstevel@tonic-gate 		auth_context = 0;
3247c478bd9Sstevel@tonic-gate 	}
3257c478bd9Sstevel@tonic-gate 	if ((retval = krb5_auth_con_init(telnet_context, &auth_context))) {
3267c478bd9Sstevel@tonic-gate 		if (auth_debug_mode) {
3277c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3287c478bd9Sstevel@tonic-gate 				"Kerberos V5: failed to init auth_context "
3297c478bd9Sstevel@tonic-gate 				"(%s)\r\n"), error_message(retval));
3307c478bd9Sstevel@tonic-gate 		}
3317c478bd9Sstevel@tonic-gate 		return (0);
3327c478bd9Sstevel@tonic-gate 	}
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate 	krb5_auth_con_setflags(telnet_context, auth_context,
3357c478bd9Sstevel@tonic-gate 		KRB5_AUTH_CONTEXT_RET_TIME);
3367c478bd9Sstevel@tonic-gate 
3377c478bd9Sstevel@tonic-gate 	type_check[0] = ap->type;
3387c478bd9Sstevel@tonic-gate 	type_check[1] = ap->way;
3397c478bd9Sstevel@tonic-gate 	check_data.magic = KV5M_DATA;
3407c478bd9Sstevel@tonic-gate 	check_data.length = 2;
3417c478bd9Sstevel@tonic-gate 	check_data.data = (char *)&type_check;
3427c478bd9Sstevel@tonic-gate 
3437c478bd9Sstevel@tonic-gate 	retval = krb5_mk_req_extended(telnet_context, &auth_context, ap_opts,
3447c478bd9Sstevel@tonic-gate 		&check_data, new_creds, &auth);
3457c478bd9Sstevel@tonic-gate 
3467c478bd9Sstevel@tonic-gate 	krb5_auth_con_getlocalsubkey(telnet_context, auth_context, &newkey);
3477c478bd9Sstevel@tonic-gate 	if (session_key) {
3487c478bd9Sstevel@tonic-gate 		krb5_free_keyblock(telnet_context, session_key);
3497c478bd9Sstevel@tonic-gate 		session_key = 0;
3507c478bd9Sstevel@tonic-gate 	}
3517c478bd9Sstevel@tonic-gate 
3527c478bd9Sstevel@tonic-gate 	if (newkey) {
3537c478bd9Sstevel@tonic-gate 		/*
3547c478bd9Sstevel@tonic-gate 		 * keep the key in our private storage, but don't use it
3557c478bd9Sstevel@tonic-gate 		 * yet---see kerberos5_reply() below
3567c478bd9Sstevel@tonic-gate 		 */
357ef2b2792Smp153739 		if (!(ACCEPTED_ENCTYPE(newkey->enctype))) {
358ef2b2792Smp153739 		    if (!(ACCEPTED_ENCTYPE(new_creds->keyblock.enctype)))
3597c478bd9Sstevel@tonic-gate 			/* use the session key in credentials instead */
3607c478bd9Sstevel@tonic-gate 			krb5_copy_keyblock(telnet_context,
3617c478bd9Sstevel@tonic-gate 				&new_creds->keyblock, &session_key);
3627c478bd9Sstevel@tonic-gate 		} else
3637c478bd9Sstevel@tonic-gate 			krb5_copy_keyblock(telnet_context,
3647c478bd9Sstevel@tonic-gate 				newkey, &session_key);
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 		krb5_free_keyblock(telnet_context, newkey);
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 	krb5_free_cred_contents(telnet_context, &creds);
3707c478bd9Sstevel@tonic-gate 	krb5_free_creds(telnet_context, new_creds);
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	if (retval) {
3737c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
3747c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3757c478bd9Sstevel@tonic-gate 			    "telnet: Kerberos V5: mk_req failed (%s)\r\n"),
3767c478bd9Sstevel@tonic-gate 			    error_message(retval));
3777c478bd9Sstevel@tonic-gate 		return (0);
3787c478bd9Sstevel@tonic-gate 	}
3797c478bd9Sstevel@tonic-gate 
3807c478bd9Sstevel@tonic-gate 	if ((auth_sendname((uchar_t *)UserNameRequested,
3817c478bd9Sstevel@tonic-gate 		strlen(UserNameRequested))) == NULL) {
3827c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
3837c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
3847c478bd9Sstevel@tonic-gate 				"telnet: Not enough room for user name\r\n"));
3857c478bd9Sstevel@tonic-gate 		return (0);
3867c478bd9Sstevel@tonic-gate 	}
3877c478bd9Sstevel@tonic-gate 	retval = krb5_send_data(ap, KRB_AUTH, auth.data, auth.length);
3887c478bd9Sstevel@tonic-gate 	if (auth_debug_mode && retval) {
3897c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
3907c478bd9Sstevel@tonic-gate 		    "telnet: Sent Kerberos V5 credentials to server\r\n"));
3917c478bd9Sstevel@tonic-gate 	} else if (auth_debug_mode) {
3927c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
3937c478bd9Sstevel@tonic-gate 		    "telnet: Not enough room for authentication data\r\n"));
3947c478bd9Sstevel@tonic-gate 		return (0);
3957c478bd9Sstevel@tonic-gate 	}
3967c478bd9Sstevel@tonic-gate 	return (1);
3977c478bd9Sstevel@tonic-gate }
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate void
kerberos5_reply(Authenticator * ap,unsigned char * data,int cnt)4007c478bd9Sstevel@tonic-gate kerberos5_reply(Authenticator *ap, unsigned char *data, int cnt)
4017c478bd9Sstevel@tonic-gate {
4027c478bd9Sstevel@tonic-gate 	Session_Key skey;
4037c478bd9Sstevel@tonic-gate 	static boolean_t mutual_complete = B_FALSE;
4047c478bd9Sstevel@tonic-gate 
4057c478bd9Sstevel@tonic-gate 	if (cnt-- < 1)
4067c478bd9Sstevel@tonic-gate 		return;
4077c478bd9Sstevel@tonic-gate 	switch (*data++) {
4087c478bd9Sstevel@tonic-gate 	case KRB_REJECT:
4097c478bd9Sstevel@tonic-gate 		if (cnt > 0)
4107c478bd9Sstevel@tonic-gate 		    (void) printf(gettext(
4117c478bd9Sstevel@tonic-gate 			"[ Kerberos V5 refuses authentication because "
4127c478bd9Sstevel@tonic-gate 			"%.*s ]\r\n"), cnt, data);
4137c478bd9Sstevel@tonic-gate 		else
4147c478bd9Sstevel@tonic-gate 		    (void) printf(gettext(
4157c478bd9Sstevel@tonic-gate 			"[ Kerberos V5 refuses authentication ]\r\n"));
4167c478bd9Sstevel@tonic-gate 		auth_send_retry();
4177c478bd9Sstevel@tonic-gate 		return;
4187c478bd9Sstevel@tonic-gate 	case KRB_ACCEPT:
4197c478bd9Sstevel@tonic-gate 		if (!mutual_complete) {
4207c478bd9Sstevel@tonic-gate 			if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
4217c478bd9Sstevel@tonic-gate 			    (void) printf(gettext(
4227c478bd9Sstevel@tonic-gate 				"[ Kerberos V5 accepted you, but didn't "
4237c478bd9Sstevel@tonic-gate 				"provide mutual authentication! ]\r\n"));
4247c478bd9Sstevel@tonic-gate 			    auth_send_retry();
4257c478bd9Sstevel@tonic-gate 			    return;
4267c478bd9Sstevel@tonic-gate 			}
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate 			if (session_key) {
4297c478bd9Sstevel@tonic-gate 			    skey.type = SK_DES;
4307c478bd9Sstevel@tonic-gate 			    skey.length = 8;
4317c478bd9Sstevel@tonic-gate 			    skey.data = session_key->contents;
4327c478bd9Sstevel@tonic-gate 			    encrypt_session_key(&skey);
4337c478bd9Sstevel@tonic-gate 			}
4347c478bd9Sstevel@tonic-gate 		}
4357c478bd9Sstevel@tonic-gate 		if (cnt)
4367c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
4377c478bd9Sstevel@tonic-gate 			    "[ Kerberos V5 accepts you as ``%.*s'' ]\r\n"),
4387c478bd9Sstevel@tonic-gate 			    cnt, data);
4397c478bd9Sstevel@tonic-gate 		else
4407c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
4417c478bd9Sstevel@tonic-gate 			    "[ Kerberos V5 accepts you ]\r\n"));
4427c478bd9Sstevel@tonic-gate 		auth_finished(ap, AUTH_USER);
4437c478bd9Sstevel@tonic-gate 
4447c478bd9Sstevel@tonic-gate 		if (forward_flags & OPTS_FORWARD_CREDS)
4457c478bd9Sstevel@tonic-gate 			kerberos5_forward(ap);
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 		break;
4487c478bd9Sstevel@tonic-gate 	case KRB_RESPONSE:
4497c478bd9Sstevel@tonic-gate 		if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL) {
4507c478bd9Sstevel@tonic-gate 			/* the rest of the reply should contain a krb_ap_rep */
4517c478bd9Sstevel@tonic-gate 			krb5_ap_rep_enc_part *reply;
4527c478bd9Sstevel@tonic-gate 			krb5_data inbuf;
4537c478bd9Sstevel@tonic-gate 			krb5_error_code retval;
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate 			inbuf.length = cnt;
4567c478bd9Sstevel@tonic-gate 			inbuf.data = (char *)data;
4577c478bd9Sstevel@tonic-gate 
4587c478bd9Sstevel@tonic-gate 			retval = krb5_rd_rep(telnet_context, auth_context,
4597c478bd9Sstevel@tonic-gate 				&inbuf, &reply);
4607c478bd9Sstevel@tonic-gate 			if (retval) {
4617c478bd9Sstevel@tonic-gate 				(void) printf(gettext(
4627c478bd9Sstevel@tonic-gate 					"[ Mutual authentication failed: "
4637c478bd9Sstevel@tonic-gate 					"%s ]\r\n"), error_message(retval));
4647c478bd9Sstevel@tonic-gate 				auth_send_retry();
4657c478bd9Sstevel@tonic-gate 				return;
4667c478bd9Sstevel@tonic-gate 			}
4677c478bd9Sstevel@tonic-gate 			krb5_free_ap_rep_enc_part(telnet_context, reply);
4687c478bd9Sstevel@tonic-gate 
4697c478bd9Sstevel@tonic-gate 			if (session_key) {
4707c478bd9Sstevel@tonic-gate 				skey.type = SK_DES;
4717c478bd9Sstevel@tonic-gate 				skey.length = 8;
4727c478bd9Sstevel@tonic-gate 				skey.data = session_key->contents;
4737c478bd9Sstevel@tonic-gate 				encrypt_session_key(&skey);
4747c478bd9Sstevel@tonic-gate 			}
4757c478bd9Sstevel@tonic-gate 			mutual_complete = B_TRUE;
4767c478bd9Sstevel@tonic-gate 		}
4777c478bd9Sstevel@tonic-gate 		return;
4787c478bd9Sstevel@tonic-gate 	case KRB_FORWARD_ACCEPT:
4797c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
4807c478bd9Sstevel@tonic-gate 			"[ Kerberos V5 accepted forwarded credentials ]\r\n"));
4817c478bd9Sstevel@tonic-gate 		return;
4827c478bd9Sstevel@tonic-gate 	case KRB_FORWARD_REJECT:
4837c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
4847c478bd9Sstevel@tonic-gate 			"[ Kerberos V5 refuses forwarded credentials because "
4857c478bd9Sstevel@tonic-gate 			"%.*s ]\r\n"), cnt, data);
4867c478bd9Sstevel@tonic-gate 		return;
4877c478bd9Sstevel@tonic-gate 	default:
4887c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
4897c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
4907c478bd9Sstevel@tonic-gate 				"Unknown Kerberos option %d\r\n"), data[-1]);
4917c478bd9Sstevel@tonic-gate 		return;
4927c478bd9Sstevel@tonic-gate 	}
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate /* ARGSUSED */
4967c478bd9Sstevel@tonic-gate int
kerberos5_status(Authenticator * ap,char * name,int level)4977c478bd9Sstevel@tonic-gate kerberos5_status(Authenticator *ap, char *name, int level)
4987c478bd9Sstevel@tonic-gate {
4997c478bd9Sstevel@tonic-gate 	if (level < AUTH_USER)
5007c478bd9Sstevel@tonic-gate 		return (level);
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	if (UserNameRequested && krb5_kuserok(telnet_context,
5037c478bd9Sstevel@tonic-gate 		ticket->enc_part2->client, UserNameRequested)) {
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate 		/* the name buffer comes from telnetd/telnetd{-ktd}.c */
5067c478bd9Sstevel@tonic-gate 		(void) strncpy(name, UserNameRequested, MAXNAMELEN);
5077c478bd9Sstevel@tonic-gate 		name[MAXNAMELEN-1] = '\0';
5087c478bd9Sstevel@tonic-gate 		return (AUTH_VALID);
5097c478bd9Sstevel@tonic-gate 	} else
5107c478bd9Sstevel@tonic-gate 		return (AUTH_USER);
5117c478bd9Sstevel@tonic-gate }
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate #define	BUMP(buf, len)		while (*(buf)) {++(buf), --(len); }
5147c478bd9Sstevel@tonic-gate #define	ADDC(buf, len, c)	if ((len) > 0) {*(buf)++ = (c); --(len); }
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * Used with the set opt command to print suboptions
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate void
kerberos5_printsub(unsigned char * data,int cnt,unsigned char * buf,int buflen)5207c478bd9Sstevel@tonic-gate kerberos5_printsub(unsigned char *data, int cnt, unsigned char *buf, int buflen)
5217c478bd9Sstevel@tonic-gate {
5227c478bd9Sstevel@tonic-gate 	char lbuf[AUTH_LBUF_BUFSIZ];
5237c478bd9Sstevel@tonic-gate 	register int i;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 	buf[buflen-1] = '\0';		/* make sure its NULL terminated */
5267c478bd9Sstevel@tonic-gate 	buflen -= 1;
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	switch (data[3]) {
5297c478bd9Sstevel@tonic-gate 	case KRB_REJECT:		/* Rejected (reason might follow) */
5307c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " REJECT ", buflen);
5317c478bd9Sstevel@tonic-gate 		goto common;
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate 	case KRB_ACCEPT:		/* Accepted (name might follow) */
5347c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " ACCEPT ", buflen);
5357c478bd9Sstevel@tonic-gate 	common:
5367c478bd9Sstevel@tonic-gate 		BUMP(buf, buflen);
5377c478bd9Sstevel@tonic-gate 		if (cnt <= 4)
5387c478bd9Sstevel@tonic-gate 			break;
5397c478bd9Sstevel@tonic-gate 		ADDC(buf, buflen, '"');
5407c478bd9Sstevel@tonic-gate 		for (i = 4; i < cnt; i++)
5417c478bd9Sstevel@tonic-gate 			ADDC(buf, buflen, data[i]);
5427c478bd9Sstevel@tonic-gate 		ADDC(buf, buflen, '"');
5437c478bd9Sstevel@tonic-gate 		ADDC(buf, buflen, '\0');
5447c478bd9Sstevel@tonic-gate 		break;
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 	case KRB_AUTH:			/* Authentication data follows */
5477c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " AUTH", buflen);
5487c478bd9Sstevel@tonic-gate 		goto common2;
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	case KRB_RESPONSE:
5517c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " RESPONSE", buflen);
5527c478bd9Sstevel@tonic-gate 		goto common2;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	case KRB_FORWARD:		/* Forwarded credentials follow */
5557c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " FORWARD", buflen);
5567c478bd9Sstevel@tonic-gate 		goto common2;
5577c478bd9Sstevel@tonic-gate 
5587c478bd9Sstevel@tonic-gate 	case KRB_FORWARD_ACCEPT:	/* Forwarded credentials accepted */
5597c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " FORWARD_ACCEPT", buflen);
5607c478bd9Sstevel@tonic-gate 		goto common2;
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	case KRB_FORWARD_REJECT:	/* Forwarded credentials rejected */
5637c478bd9Sstevel@tonic-gate 					/* (reason might follow) */
5647c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, " FORWARD_REJECT", buflen);
5657c478bd9Sstevel@tonic-gate 		goto common2;
5667c478bd9Sstevel@tonic-gate 
5677c478bd9Sstevel@tonic-gate 	default:
5687c478bd9Sstevel@tonic-gate 		(void) snprintf(lbuf, AUTH_LBUF_BUFSIZ,
5697c478bd9Sstevel@tonic-gate 			gettext(" %d (unknown)"),
5707c478bd9Sstevel@tonic-gate 			data[3]);
5717c478bd9Sstevel@tonic-gate 		(void) strncpy((char *)buf, lbuf, buflen);
5727c478bd9Sstevel@tonic-gate 	common2:
5737c478bd9Sstevel@tonic-gate 		BUMP(buf, buflen);
5747c478bd9Sstevel@tonic-gate 		for (i = 4; i < cnt; i++) {
5757c478bd9Sstevel@tonic-gate 			(void) snprintf(lbuf, AUTH_LBUF_BUFSIZ, " %d", data[i]);
5767c478bd9Sstevel@tonic-gate 			(void) strncpy((char *)buf, lbuf, buflen);
5777c478bd9Sstevel@tonic-gate 			BUMP(buf, buflen);
5787c478bd9Sstevel@tonic-gate 		}
5797c478bd9Sstevel@tonic-gate 		break;
5807c478bd9Sstevel@tonic-gate 	}
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate void
krb5_profile_get_options(char * host,char * realm,profile_options_boolean * optionsp)5847c478bd9Sstevel@tonic-gate krb5_profile_get_options(char *host, char *realm,
5857c478bd9Sstevel@tonic-gate 	profile_options_boolean *optionsp)
5867c478bd9Sstevel@tonic-gate {
5877c478bd9Sstevel@tonic-gate 	char	**realms = NULL;
5887c478bd9Sstevel@tonic-gate 	krb5_error_code err = 0;
5897c478bd9Sstevel@tonic-gate 
5907c478bd9Sstevel@tonic-gate 	if (!telnet_context) {
5917c478bd9Sstevel@tonic-gate 	    err = krb5_init_context(&telnet_context);
5927c478bd9Sstevel@tonic-gate 	    if (err) {
5937c478bd9Sstevel@tonic-gate 		(void) fprintf(stderr, gettext(
5947c478bd9Sstevel@tonic-gate 			"Error initializing Kerberos 5 library: %s\n"),
5957c478bd9Sstevel@tonic-gate 			error_message(err));
5967c478bd9Sstevel@tonic-gate 		return;
5977c478bd9Sstevel@tonic-gate 	    }
5987c478bd9Sstevel@tonic-gate 	}
5997c478bd9Sstevel@tonic-gate 
6007c478bd9Sstevel@tonic-gate 	if ((realmdef[1] = realm) == NULL) {
6017c478bd9Sstevel@tonic-gate 		err = krb5_get_host_realm(telnet_context, host, &realms);
6027c478bd9Sstevel@tonic-gate 		if (err) {
6037c478bd9Sstevel@tonic-gate 		    (void) fprintf(stderr, gettext(
6047c478bd9Sstevel@tonic-gate 			"Error getting Kerberos 5 realms for: %s (%s)\n"),
6057c478bd9Sstevel@tonic-gate 			host, error_message(err));
6067c478bd9Sstevel@tonic-gate 		    return;
6077c478bd9Sstevel@tonic-gate 		}
6087c478bd9Sstevel@tonic-gate 		realmdef[1] = realms[0];
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	profile_get_options_boolean(telnet_context->profile,
6127c478bd9Sstevel@tonic-gate 		realmdef, optionsp);
6137c478bd9Sstevel@tonic-gate 	profile_get_options_boolean(telnet_context->profile,
6147c478bd9Sstevel@tonic-gate 		appdef, optionsp);
6157c478bd9Sstevel@tonic-gate }
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate static void
kerberos5_forward(Authenticator * ap)6187c478bd9Sstevel@tonic-gate kerberos5_forward(Authenticator *ap)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate 	krb5_error_code retval;
6217c478bd9Sstevel@tonic-gate 	krb5_ccache ccache;
6227c478bd9Sstevel@tonic-gate 	krb5_principal client = 0;
6237c478bd9Sstevel@tonic-gate 	krb5_principal server = 0;
6247c478bd9Sstevel@tonic-gate 	krb5_data forw_creds;
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 	forw_creds.data = 0;
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 	if ((retval = krb5_cc_default(telnet_context, &ccache))) {
6297c478bd9Sstevel@tonic-gate 	    if (auth_debug_mode)
6307c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
6317c478bd9Sstevel@tonic-gate 			"Kerberos V5: could not get default ccache - %s\r\n"),
6327c478bd9Sstevel@tonic-gate 			error_message(retval));
6337c478bd9Sstevel@tonic-gate 	    return;
6347c478bd9Sstevel@tonic-gate 	}
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	retval = krb5_cc_get_principal(telnet_context, ccache, &client);
6377c478bd9Sstevel@tonic-gate 	if (retval) {
6387c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
6397c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
6407c478bd9Sstevel@tonic-gate 				"Kerberos V5: could not get default "
6417c478bd9Sstevel@tonic-gate 				"principal - %s\r\n"), error_message(retval));
6427c478bd9Sstevel@tonic-gate 		goto cleanup;
6437c478bd9Sstevel@tonic-gate 	}
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 	retval = krb5_sname_to_principal(telnet_context, RemoteHostName,
6467c478bd9Sstevel@tonic-gate 		"host", KRB5_NT_SRV_HST, &server);
6477c478bd9Sstevel@tonic-gate 	if (retval) {
6487c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
6497c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
6507c478bd9Sstevel@tonic-gate 				"Kerberos V5: could not make server "
6517c478bd9Sstevel@tonic-gate 				"principal - %s\r\n"), error_message(retval));
6527c478bd9Sstevel@tonic-gate 		goto cleanup;
6537c478bd9Sstevel@tonic-gate 	}
6547c478bd9Sstevel@tonic-gate 
6557c478bd9Sstevel@tonic-gate 	retval = krb5_auth_con_genaddrs(telnet_context, auth_context, net,
6567c478bd9Sstevel@tonic-gate 				KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR);
6577c478bd9Sstevel@tonic-gate 	if (retval) {
6587c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
6597c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
6607c478bd9Sstevel@tonic-gate 				"Kerberos V5: could not gen local full "
6617c478bd9Sstevel@tonic-gate 				"address - %s\r\n"), error_message(retval));
6627c478bd9Sstevel@tonic-gate 		goto cleanup;
6637c478bd9Sstevel@tonic-gate 	}
6647c478bd9Sstevel@tonic-gate 
6657c478bd9Sstevel@tonic-gate 	retval = krb5_fwd_tgt_creds(telnet_context, auth_context, 0, client,
6667c478bd9Sstevel@tonic-gate 		server, ccache, forward_flags & OPTS_FORWARDABLE_CREDS,
6677c478bd9Sstevel@tonic-gate 		&forw_creds);
6687c478bd9Sstevel@tonic-gate 	if (retval) {
6697c478bd9Sstevel@tonic-gate 		if (auth_debug_mode)
6707c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
6717c478bd9Sstevel@tonic-gate 				"Kerberos V5: error getting forwarded "
6727c478bd9Sstevel@tonic-gate 				"creds - %s\r\n"), error_message(retval));
6737c478bd9Sstevel@tonic-gate 		goto cleanup;
6747c478bd9Sstevel@tonic-gate 	}
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 	/* Send forwarded credentials */
6777c478bd9Sstevel@tonic-gate 	if (!krb5_send_data(ap, KRB_FORWARD, forw_creds.data,
6787c478bd9Sstevel@tonic-gate 		forw_creds.length)) {
6797c478bd9Sstevel@tonic-gate 		    if (auth_debug_mode)
6807c478bd9Sstevel@tonic-gate 			(void) printf(gettext(
6817c478bd9Sstevel@tonic-gate 			    "Not enough room for authentication data\r\n"));
6827c478bd9Sstevel@tonic-gate 	} else if (auth_debug_mode)
6837c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
6847c478bd9Sstevel@tonic-gate 		    "Forwarded local Kerberos V5 credentials to server\r\n"));
6857c478bd9Sstevel@tonic-gate cleanup:
6867c478bd9Sstevel@tonic-gate 	if (client)
6877c478bd9Sstevel@tonic-gate 		krb5_free_principal(telnet_context, client);
6887c478bd9Sstevel@tonic-gate 	if (server)
6897c478bd9Sstevel@tonic-gate 		krb5_free_principal(telnet_context, server);
6907c478bd9Sstevel@tonic-gate 	if (forw_creds.data)
6917c478bd9Sstevel@tonic-gate 		free(forw_creds.data);
6927c478bd9Sstevel@tonic-gate 	/* LINTED */
6937c478bd9Sstevel@tonic-gate 	krb5_cc_close(telnet_context, ccache);
6947c478bd9Sstevel@tonic-gate }
695