/*
 * 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.23 2001/01/22 08:15:00 markus Exp $");

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

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

#ifdef KRB4
char *ticket = NULL;

extern ServerOptions options;

/*
 * try krb4 authentication,
 * return 1 on success, 0 on failure, -1 if krb4 is not available
 */

int
auth_krb4_password(struct passwd * pw, const char *password)
{
	AUTH_DAT adata;
	KTEXT_ST tkt;
	struct hostent *hp;
	u_long faddr;
	char localhost[MAXHOSTNAMELEN];
	char phost[INST_SZ];
	char realm[REALM_SZ];
	int r;

	/*
	 * 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(pw->pw_uid)) {
			log("Couldn't initialize Kerberos ticket file for %s!",
			    pw->pw_name);
			goto kerberos_auth_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) {
			packet_send_debug("Kerberos V4 password "
			    "authentication for %s failed: %s",
			    pw->pw_name, krb_err_txt[r]);
			goto kerberos_auth_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.
		 */
		(void) gethostname(localhost, sizeof(localhost));
		(void) strlcpy(phost, (char *) krb_get_phost(localhost),
		    INST_SZ);
		r = krb_mk_req(&tkt, KRB4_SERVICE_NAME, phost, realm, 33);

		if (r == KSUCCESS) {
			if (!(hp = gethostbyname(localhost))) {
				log("Couldn't get local host address!");
				goto kerberos_auth_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 kerberos_auth_failure;
			} else if (r != KSUCCESS) {
				log("Kerberos V4 %s ticket unverifiable: %s",
				    KRB4_SERVICE_NAME, krb_err_txt[r]);
				goto kerberos_auth_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 kerberos_auth_failure;
		} else {
			/*
			 * TGT is bad, forget it. Possibly spoofed!
			 */
			packet_send_debug("WARNING: Kerberos V4 TGT "
			    "possibly spoofed for %s: %s",
			    pw->pw_name, krb_err_txt[r]);
			goto kerberos_auth_failure;
		}

		/* Authentication succeeded. */
		return 1;

kerberos_auth_failure:
		krb4_cleanup_proc(NULL);

		if (!options.kerberos_or_local_passwd)
			return 0;
	} else {
		/* Logging in as root or no local Kerberos realm. */
		packet_send_debug("Unable to authenticate to Kerberos.");
	}
	/* Fall back to ordinary passwd authentication. */
	return -1;
}

void
krb4_cleanup_proc(void *ignore)
{
	debug("krb4_cleanup_proc called");
	if (ticket) {
		(void) dest_tkt();
		xfree(ticket);
		ticket = NULL;
	}
}

int
krb4_init(uid_t uid)
{
	static int cleanup_registered = 0;
	const char *tkt_root = TKT_ROOT;
	struct stat st;
	int fd;

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

	return 0;
}

int
auth_krb4(const char *server_user, KTEXT auth, char **client)
{
	AUTH_DAT adat = {0};
	KTEXT_ST reply;
	char instance[INST_SZ];
	int r, s;
	socklen_t slen;
	u_int cksum;
	Key_schedule schedule;
	struct sockaddr_in local, foreign;

	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, ""))) {
		packet_send_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, (char *) server_user) != KSUCCESS) {
		packet_send_debug("Kerberos V4 .klogin authorization failed!");
		log("Kerberos V4 .klogin authorization failed for %s to account %s",
		    *client, server_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) {
		packet_send_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_kerberos_tgt(struct passwd *pw, const char *string)
{
	CREDENTIALS creds;

	if (pw == NULL)
		goto auth_kerberos_tgt_failure;
	if (!radix_to_creds(string, &creds)) {
		log("Protocol error decoding Kerberos V4 tgt");
		packet_send_debug("Protocol error decoding Kerberos V4 tgt");
		goto auth_kerberos_tgt_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);
		packet_send_debug("Kerberos V4 tgt (%s%s%s@%s) rejected for %s",
		    creds.pname, creds.pinst[0] ? "." : "", creds.pinst,
		    creds.realm, pw->pw_name);
		goto auth_kerberos_tgt_failure;
	}
	if (!krb4_init(pw->pw_uid))
		goto auth_kerberos_tgt_failure;

	if (in_tkt(creds.pname, creds.pinst) != KSUCCESS)
		goto auth_kerberos_tgt_failure;

	if (save_credentials(creds.service, creds.instance, creds.realm,
	    creds.session, creds.lifetime, creds.kvno,
	    &creds.ticket_st, creds.issue_date) != KSUCCESS) {
		packet_send_debug("Kerberos V4 tgt refused: couldn't save credentials");
		goto auth_kerberos_tgt_failure;
	}
	/* Successful authentication, passed all checks. */
	chown(tkt_string(), pw->pw_uid, pw->pw_gid);

	packet_send_debug("Kerberos V4 tgt accepted (%s.%s@%s, %s%s%s@%s)",
	    creds.service, creds.instance, creds.realm, creds.pname,
	    creds.pinst[0] ? "." : "", creds.pinst, creds.realm);
	memset(&creds, 0, sizeof(creds));
	packet_start(SSH_SMSG_SUCCESS);
	packet_send();
	packet_write_wait();
	return 1;

auth_kerberos_tgt_failure:
	krb4_cleanup_proc(NULL);
	memset(&creds, 0, sizeof(creds));
	packet_start(SSH_SMSG_FAILURE);
	packet_send();
	packet_write_wait();
	return 0;
}

int
auth_afs_token(struct passwd *pw, const char *token_string)
{
	CREDENTIALS creds;
	uid_t uid;

	if (pw == NULL) {
		/* XXX fake protocol error */
		packet_send_debug("Protocol error decoding AFS token");
		packet_start(SSH_SMSG_FAILURE);
		packet_send();
		packet_write_wait();
		return 0;
	}
	if (!radix_to_creds(token_string, &creds)) {
		log("Protocol error decoding AFS token");
		packet_send_debug("Protocol error decoding AFS token");
		packet_start(SSH_SMSG_FAILURE);
		packet_send();
		packet_write_wait();
		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);
		packet_send_debug("AFS token (%s@%s) rejected for %s", creds.pname,
		    creds.realm, pw->pw_name);
		memset(&creds, 0, sizeof(creds));
		packet_start(SSH_SMSG_FAILURE);
		packet_send();
		packet_write_wait();
		return 0;
	}
	packet_send_debug("AFS token accepted (%s@%s, %s@%s)", creds.service,
	    creds.realm, creds.pname, creds.realm);
	memset(&creds, 0, sizeof(creds));
	packet_start(SSH_SMSG_SUCCESS);
	packet_send();
	packet_write_wait();
	return 1;
}
#endif /* AFS */
