/*
 * Copyright (c) 1999 Dug Song.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "includes.h"
RCSID("$OpenBSD: auth-krb4.c,v 1.24 2001/06/26 16:15:22 dugsong Exp $");

#include "ssh.h"
#include "ssh1.h"
#include "packet.h"
#include "xmalloc.h"
#include "log.h"
#include "servconf.h"
#include "uidswap.h"
#include "auth.h"

#ifdef AFS
#include "radix.h"
#endif

#ifdef KRB4
extern ServerOptions options;

static int
krb4_init(void *context)
{
	static int cleanup_registered = 0;
	Authctxt *authctxt = (Authctxt *)context;
	const char *tkt_root = TKT_ROOT;
	struct stat st;
	int fd;
	
	if (!authctxt->krb4_ticket_file) {
		/* Set unique ticket string manually since we're still root. */
		authctxt->krb4_ticket_file = xmalloc(MAXPATHLEN);
#ifdef AFS
		if (lstat("/ticket", &st) != -1)
			tkt_root = "/ticket/";
#endif /* AFS */
		snprintf(authctxt->krb4_ticket_file, MAXPATHLEN, "%s%u_%d",
		    tkt_root, authctxt->pw->pw_uid, getpid());
		krb_set_tkt_string(authctxt->krb4_ticket_file);
	}
	/* Register ticket cleanup in case of fatal error. */
	if (!cleanup_registered) {
		fatal_add_cleanup(krb4_cleanup_proc, authctxt);
		cleanup_registered = 1;
	}
	/* Try to create our ticket file. */
	if ((fd = mkstemp(authctxt->krb4_ticket_file)) != -1) {
		close(fd);
		return (1);
	}
	/* Ticket file exists - make sure user owns it (just passed ticket). */
	if (lstat(authctxt->krb4_ticket_file, &st) != -1) {
		if (st.st_mode == (S_IFREG | S_IRUSR | S_IWUSR) &&
		    st.st_uid == authctxt->pw->pw_uid)
			return (1);
	}
	/* Failure - cancel cleanup function, leaving ticket for inspection. */
	log("WARNING: bad ticket file %s", authctxt->krb4_ticket_file);
	
	fatal_remove_cleanup(krb4_cleanup_proc, authctxt);
	cleanup_registered = 0;
	
	xfree(authctxt->krb4_ticket_file);
	authctxt->krb4_ticket_file = NULL;
	
	return (0);
}

/*
 * try krb4 authentication,
 * return 1 on success, 0 on failure, -1 if krb4 is not available
 */
int
auth_krb4_password(Authctxt *authctxt, const char *password)
{
	AUTH_DAT adata;
	KTEXT_ST tkt;
	struct hostent *hp;
	struct passwd *pw;
	char localhost[MAXHOSTNAMELEN], phost[INST_SZ], realm[REALM_SZ];
	u_int32_t faddr;
	int r;
	
	if ((pw = authctxt->pw) == NULL)
		return (0);
	
	/*
	 * Try Kerberos password authentication only for non-root
	 * users and only if Kerberos is installed.
	 */
	if (pw->pw_uid != 0 && krb_get_lrealm(realm, 1) == KSUCCESS) {
		/* Set up our ticket file. */
		if (!krb4_init(authctxt)) {
			log("Couldn't initialize Kerberos ticket file for %s!",
			    pw->pw_name);
			goto failure;
		}
		/* Try to get TGT using our password. */
		r = krb_get_pw_in_tkt((char *) pw->pw_name, "", realm,
		    "krbtgt", realm, DEFAULT_TKT_LIFE, (char *)password);
		if (r != INTK_OK) {
			debug("Kerberos v4 password authentication for %s "
			    "failed: %s", pw->pw_name, krb_err_txt[r]);
			goto failure;
		}
		/* Successful authentication. */
		chown(tkt_string(), pw->pw_uid, pw->pw_gid);
		
		/*
		 * Now that we have a TGT, try to get a local
		 * "rcmd" ticket to ensure that we are not talking
		 * to a bogus Kerberos server.
		 */
		gethostname(localhost, sizeof(localhost));
		strlcpy(phost, (char *)krb_get_phost(localhost),
		    sizeof(phost));
		r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);
		
		if (r == KSUCCESS) {
			if ((hp = gethostbyname(localhost)) == NULL) {
				log("Couldn't get local host address!");
				goto failure;
			}
			memmove((void *)&faddr, (void *)hp->h_addr,
			    sizeof(faddr));
			
			/* Verify our "rcmd" ticket. */
			r = krb_rd_req(&tkt, KRB4_SERVICE_NAME, phost,
			    faddr, &adata, "");
			if (r == RD_AP_UNDEC) {
				/*
				 * Probably didn't have a srvtab on
				 * localhost. Disallow login.
				 */
				log("Kerberos v4 TGT for %s unverifiable, "
				    "no srvtab installed? krb_rd_req: %s",
				    pw->pw_name, krb_err_txt[r]);
				goto failure;
			} else if (r != KSUCCESS) {
				log("Kerberos v4 %s ticket unverifiable: %s",
				    KRB4_SERVICE_NAME, krb_err_txt[r]);
				goto failure;
			}
		} else if (r == KDC_PR_UNKNOWN) {
			/*
			 * Disallow login if no rcmd service exists, and
			 * log the error.
			 */
			log("Kerberos v4 TGT for %s unverifiable: %s; %s.%s "
			    "not registered, or srvtab is wrong?", pw->pw_name,
			    krb_err_txt[r], KRB4_SERVICE_NAME, phost);
			goto failure;
		} else {
			/*
			 * TGT is bad, forget it. Possibly spoofed!
			 */
			debug("WARNING: Kerberos v4 TGT possibly spoofed "
			    "for %s: %s", pw->pw_name, krb_err_txt[r]);
			goto failure;
		}
		/* Authentication succeeded. */
		return (1);
	} else
		/* Logging in as root or no local Kerberos realm. */
		debug("Unable to authenticate to Kerberos.");
	
 failure:
	krb4_cleanup_proc(authctxt);
	
	if (!options.kerberos_or_local_passwd)
		return (0);
	
	/* Fall back to ordinary passwd authentication. */
	return (-1);
}

void
krb4_cleanup_proc(void *context)
{
	Authctxt *authctxt = (Authctxt *)context;
	debug("krb4_cleanup_proc called");
	if (authctxt->krb4_ticket_file) {
		(void) dest_tkt();
		xfree(authctxt->krb4_ticket_file);
		authctxt->krb4_ticket_file = NULL;
	}
}

int
auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
{
	AUTH_DAT adat = {0};
	KTEXT_ST reply;
	Key_schedule schedule;
	struct sockaddr_in local, foreign;
	char instance[INST_SZ];
	socklen_t slen;
	u_int cksum;
	int r, s;
	
	s = packet_get_connection_in();
	
	slen = sizeof(local);
	memset(&local, 0, sizeof(local));
	if (getsockname(s, (struct sockaddr *) & local, &slen) < 0)
		debug("getsockname failed: %.100s", strerror(errno));
	slen = sizeof(foreign);
	memset(&foreign, 0, sizeof(foreign));
	if (getpeername(s, (struct sockaddr *) & foreign, &slen) < 0) {
		debug("getpeername failed: %.100s", strerror(errno));
		fatal_cleanup();
	}
	instance[0] = '*';
	instance[1] = 0;
	
	/* Get the encrypted request, challenge, and session key. */
	if ((r = krb_rd_req(auth, KRB4_SERVICE_NAME, instance,
	    0, &adat, ""))) {
		debug("Kerberos v4 krb_rd_req: %.100s", krb_err_txt[r]);
		return (0);
	}
	des_key_sched((des_cblock *) adat.session, schedule);
	
	*client = xmalloc(MAX_K_NAME_SZ);
	(void) snprintf(*client, MAX_K_NAME_SZ, "%s%s%s@%s", adat.pname,
	    *adat.pinst ? "." : "", adat.pinst, adat.prealm);
	
	/* Check ~/.klogin authorization now. */
	if (kuserok(&adat, authctxt->user) != KSUCCESS) {
		log("Kerberos v4 .klogin authorization failed for %s to "
		    "account %s", *client, authctxt->user);
		xfree(*client);
		return (0);
	}
	/* Increment the checksum, and return it encrypted with the
	   session key. */
	cksum = adat.checksum + 1;
	cksum = htonl(cksum);
	
	/* If we can't successfully encrypt the checksum, we send back an
	   empty message, admitting our failure. */
	if ((r = krb_mk_priv((u_char *) & cksum, reply.dat, sizeof(cksum) + 1,
	    schedule, &adat.session, &local, &foreign)) < 0) {
		debug("Kerberos v4 mk_priv: (%d) %s", r, krb_err_txt[r]);
		reply.dat[0] = 0;
		reply.length = 0;
	} else
		reply.length = r;
	
	/* Clear session key. */
	memset(&adat.session, 0, sizeof(&adat.session));
	
	packet_start(SSH_SMSG_AUTH_KERBEROS_RESPONSE);
	packet_put_string((char *) reply.dat, reply.length);
	packet_send();
	packet_write_wait();
	return (1);
}
#endif /* KRB4 */

#ifdef AFS
int
auth_krb4_tgt(Authctxt *authctxt, const char *string)
{
	CREDENTIALS creds;
	struct passwd *pw;
	
	if ((pw = authctxt->pw) == NULL)
		goto failure;
	
	temporarily_use_uid(pw);
	
	if (!radix_to_creds(string, &creds)) {
		log("Protocol error decoding Kerberos v4 TGT");
		goto failure;
	}
	if (strncmp(creds.service, "", 1) == 0)	/* backward compatibility */
		strlcpy(creds.service, "krbtgt", sizeof creds.service);
	
	if (strcmp(creds.service, "krbtgt")) {
		log("Kerberos v4 TGT (%s%s%s@%s) rejected for %s",
		    creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
		    creds.realm, pw->pw_name);
		goto failure;
	}
	if (!krb4_init(authctxt))
		goto failure;
	
	if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
		goto failure;
	
	if (save_credentials(creds.service, creds.instance, creds.realm,
	    creds.session, creds.lifetime, creds.kvno, &creds.ticket_st,
	    creds.issue_date) != KSUCCESS) {
		debug("Kerberos v4 TGT refused: couldn't save credentials");
		goto failure;
	}
	/* Successful authentication, passed all checks. */
	chown(tkt_string(), pw->pw_uid, pw->pw_gid);
	
	debug("Kerberos v4 TGT accepted (%s%s%s@%s)",
	    creds.pname, creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
	memset(&creds, 0, sizeof(creds));
	
	restore_uid();
	
	return (1);
	
 failure:
	krb4_cleanup_proc(authctxt);
	memset(&creds, 0, sizeof(creds));
	restore_uid();
	
	return (0);
}

int
auth_afs_token(Authctxt *authctxt, const char *token_string)
{
	CREDENTIALS creds;
	struct passwd *pw;
	uid_t uid;
	
	if ((pw = authctxt->pw) == NULL)
		return (0);
	
	if (!radix_to_creds(token_string, &creds)) {
		log("Protocol error decoding AFS token");
		return (0);
	}
	if (strncmp(creds.service, "", 1) == 0)	/* backward compatibility */
		strlcpy(creds.service, "afs", sizeof creds.service);
	
	if (strncmp(creds.pname, "AFS ID ", 7) == 0)
		uid = atoi(creds.pname + 7);
	else
		uid = pw->pw_uid;
	
	if (kafs_settoken(creds.realm, uid, &creds)) {
		log("AFS token (%s@%s) rejected for %s",
		    creds.pname, creds.realm, pw->pw_name);
		memset(&creds, 0, sizeof(creds));
		return (0);
	}
	debug("AFS token accepted (%s@%s)", creds.pname, creds.realm);
	memset(&creds, 0, sizeof(creds));
	
	return (1);
}
#endif /* AFS */
