- markus@cvs.openbsd.org 2002/09/26 11:38:43
     [auth1.c auth.h auth-krb4.c monitor.c monitor.h monitor_wrap.c]
     [monitor_wrap.h]
     krb4 + privsep; ok dugsong@, deraadt@
diff --git a/ChangeLog b/ChangeLog
index 3f62f57..2da8c82 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,10 @@
    - markus@cvs.openbsd.org 2002/09/25 15:19:02
      [sshd.c]
      typo; pilot@monkey.org
+   - markus@cvs.openbsd.org 2002/09/26 11:38:43
+     [auth1.c auth.h auth-krb4.c monitor.c monitor.h monitor_wrap.c]
+     [monitor_wrap.h]
+     krb4 + privsep; ok dugsong@, deraadt@
 
 20020925
  - (bal) Fix issue where successfull login does not clear failure counts
@@ -730,4 +734,4 @@
      save auth method before monitor_reset_key_state(); bugzilla bug #284;
      ok provos@
 
-$Id: ChangeLog,v 1.2484 2002/09/27 03:22:31 djm Exp $
+$Id: ChangeLog,v 1.2485 2002/09/27 03:25:58 djm Exp $
diff --git a/auth-krb4.c b/auth-krb4.c
index 1cc528a..b86ce7e 100644
--- a/auth-krb4.c
+++ b/auth-krb4.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth-krb4.c,v 1.27 2002/06/11 05:46:20 mpech Exp $");
+RCSID("$OpenBSD: auth-krb4.c,v 1.28 2002/09/26 11:38:43 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -210,10 +210,9 @@
 }
 
 int
-auth_krb4(Authctxt *authctxt, KTEXT auth, char **client)
+auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply)
 {
 	AUTH_DAT adat = {0};
-	KTEXT_ST reply;
 	Key_schedule schedule;
 	struct sockaddr_in local, foreign;
 	char instance[INST_SZ];
@@ -263,21 +262,16 @@
 
 	/* 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,
+	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;
+		reply->dat[0] = 0;
+		reply->length = 0;
 	} else
-		reply.length = r;
+		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 */
diff --git a/auth.h b/auth.h
index 82d9987..c75d753 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: auth.h,v 1.40 2002/09/09 06:48:06 itojun Exp $	*/
+/*	$OpenBSD: auth.h,v 1.41 2002/09/26 11:38:43 markus Exp $	*/
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -113,7 +113,7 @@
 
 #ifdef KRB4
 #include <krb.h>
-int     auth_krb4(Authctxt *, KTEXT, char **);
+int     auth_krb4(Authctxt *, KTEXT, char **, KTEXT);
 int	auth_krb4_password(Authctxt *, const char *);
 void    krb4_cleanup_proc(void *);
 
diff --git a/auth1.c b/auth1.c
index 676c8a6..9527ba0 100644
--- a/auth1.c
+++ b/auth1.c
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth1.c,v 1.43 2002/09/09 06:48:06 itojun Exp $");
+RCSID("$OpenBSD: auth1.c,v 1.44 2002/09/26 11:38:43 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -118,17 +118,24 @@
 
 				if (kdata[0] == 4) { /* KRB_PROT_VERSION */
 #ifdef KRB4
-					KTEXT_ST tkt;
-
+					KTEXT_ST tkt, reply;
 					tkt.length = dlen;
 					if (tkt.length < MAX_KTXT_LEN)
 						memcpy(tkt.dat, kdata, tkt.length);
 
-					if (auth_krb4(authctxt, &tkt, &client_user)) {
+					if (PRIVSEP(auth_krb4(authctxt, &tkt,
+					    &client_user, &reply))) {
 						authenticated = 1;
 						snprintf(info, sizeof(info),
 						    " tktuser %.100s",
 						    client_user);
+
+						packet_start(
+						    SSH_SMSG_AUTH_KERBEROS_RESPONSE);
+						packet_put_string((char *)
+						    reply.dat, reply.length);
+						packet_send();
+						packet_write_wait();
 					}
 #endif /* KRB4 */
 				} else {
diff --git a/monitor.c b/monitor.c
index e07e97e..4ad3f3d 100644
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor.c,v 1.28 2002/09/24 08:46:04 markus Exp $");
+RCSID("$OpenBSD: monitor.c,v 1.29 2002/09/26 11:38:43 markus Exp $");
 
 #include <openssl/dh.h>
 
@@ -120,6 +120,9 @@
 int mm_answer_pam_start(int, Buffer *);
 #endif
 
+#ifdef KRB4
+int mm_answer_krb4(int, Buffer *);
+#endif
 #ifdef KRB5
 int mm_answer_krb5(int, Buffer *);
 #endif
@@ -203,6 +206,9 @@
 #ifdef USE_PAM
     {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
 #endif
+#ifdef KRB4
+    {MONITOR_REQ_KRB4, MON_ONCE|MON_AUTH, mm_answer_krb4},
+#endif
 #ifdef KRB5
     {MONITOR_REQ_KRB5, MON_ONCE|MON_AUTH, mm_answer_krb5},
 #endif
@@ -1285,6 +1291,51 @@
 	return (success);
 }
 
+#ifdef KRB4
+int
+mm_answer_krb4(int socket, Buffer *m)
+{
+	KTEXT_ST auth, reply;
+	char  *client, *p;
+	int success;
+	u_int alen;
+
+	reply.length = auth.length = 0;
+ 
+	p = buffer_get_string(m, &alen);
+	if (alen >=  MAX_KTXT_LEN)
+		 fatal("%s: auth too large", __func__);
+	memcpy(auth.dat, p, alen);
+	auth.length = alen;
+	memset(p, 0, alen);
+	xfree(p);
+
+	success = options.kerberos_authentication &&
+	    authctxt->valid &&
+	    auth_krb4(authctxt, &auth, &client, &reply);
+
+	memset(auth.dat, 0, alen);
+	buffer_clear(m);
+	buffer_put_int(m, success);
+
+	if (success) {
+		buffer_put_cstring(m, client);
+		buffer_put_string(m, reply.dat, reply.length);
+		if (client)
+			xfree(client);
+		if (reply.length)
+			memset(reply.dat, 0, reply.length);
+	}
+
+	debug3("%s: sending result %d", __func__, success);
+	mm_request_send(socket, MONITOR_ANS_KRB4, m);
+
+	auth_method = "kerberos";
+
+	/* Causes monitor loop to terminate if authenticated */
+	return (success);
+}
+#endif
 
 #ifdef KRB5
 int
diff --git a/monitor.h b/monitor.h
index 5531319..668ac98 100644
--- a/monitor.h
+++ b/monitor.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: monitor.h,v 1.7 2002/09/09 06:48:06 itojun Exp $	*/
+/*	$OpenBSD: monitor.h,v 1.8 2002/09/26 11:38:43 markus Exp $	*/
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -49,6 +49,7 @@
 	MONITOR_REQ_RSAKEYALLOWED, MONITOR_ANS_RSAKEYALLOWED,
 	MONITOR_REQ_RSACHALLENGE, MONITOR_ANS_RSACHALLENGE,
 	MONITOR_REQ_RSARESPONSE, MONITOR_ANS_RSARESPONSE,
+	MONITOR_REQ_KRB4, MONITOR_ANS_KRB4,
  	MONITOR_REQ_KRB5, MONITOR_ANS_KRB5,
 	MONITOR_REQ_PAM_START,
 	MONITOR_REQ_TERM
diff --git a/monitor_wrap.c b/monitor_wrap.c
index 5d11a65..4c53bfd 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -25,7 +25,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: monitor_wrap.c,v 1.18 2002/09/09 14:54:15 markus Exp $");
+RCSID("$OpenBSD: monitor_wrap.c,v 1.19 2002/09/26 11:38:43 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/dh.h>
@@ -937,6 +937,42 @@
 	return (success);
 }
 
+#ifdef KRB4
+int
+mm_auth_krb4(Authctxt *authctxt, void *_auth, char **client, void *_reply)
+{
+	KTEXT auth, reply;
+ 	Buffer m;
+	u_int rlen;
+	int success = 0;
+	char *p;
+
+	debug3("%s entering", __func__);
+	auth = _auth;
+	reply = _reply;
+
+	buffer_init(&m);
+	buffer_put_string(&m, auth->dat, auth->length);
+
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KRB4, &m);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KRB4, &m);
+
+	success = buffer_get_int(&m);
+	if (success) {
+		*client = buffer_get_string(&m, NULL);
+		p = buffer_get_string(&m, &rlen);
+		if (rlen >= MAX_KTXT_LEN)
+			fatal("%s: reply from monitor too large", __func__);
+		reply->length = rlen;
+		memcpy(reply->dat, p, rlen);
+		memset(p, 0, rlen);
+		xfree(p);
+	}
+	buffer_free(&m);
+	return (success); 
+}
+#endif
+
 #ifdef KRB5
 int
 mm_auth_krb5(void *ctx, void *argp, char **userp, void *resp)
diff --git a/monitor_wrap.h b/monitor_wrap.h
index 5e583e1..d960a3d 100644
--- a/monitor_wrap.h
+++ b/monitor_wrap.h
@@ -1,4 +1,4 @@
-/*	$OpenBSD: monitor_wrap.h,v 1.7 2002/09/09 06:48:06 itojun Exp $	*/
+/*	$OpenBSD: monitor_wrap.h,v 1.8 2002/09/26 11:38:43 markus Exp $	*/
 
 /*
  * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -83,7 +83,10 @@
 int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **);
 int mm_skey_respond(void *, u_int, char **);
 
-/* auth_krb5 */
+/* auth_krb */
+#ifdef KRB4
+int mm_auth_krb4(struct Authctxt *, void *, char **, void *);
+#endif
 #ifdef KRB5
 /* auth and reply are really krb5_data objects, but we don't want to
  * include all of the krb5 headers here */