Subject: openssh, privsep support for krb4
To: None <tech-security@netbsd.org>
From: Jun-ichiro itojun Hagino <itojun@iijlab.net>
List: tech-security
Date: 09/11/2002 16:37:15
------- =_aaaaaaaaaa0
Content-Type: text/plain; charset="us-ascii"
Content-ID: <14234.1031729820.1@itojun.org>

	please test and report, so that it can be part of openssh (hence
	brought into our tree).  thanks!

itojun

------- =_aaaaaaaaaa0
Content-Type: message/rfc822
Content-ID: <14234.1031729820.2@itojun.org>
Content-Description: forwarded message

Delivery-Date: Wed Sep 11 09:04:42 2002
	by starfruit.itojun.org (Postfix) with ESMTP id 9F2CC7B9
	for <itojun@localhost>; Wed, 11 Sep 2002 09:04:32 +0900 (JST)
	by localhost with POP3 (fetchmail-5.9.13)
	for itojun@localhost (single-drop); Wed, 11 Sep 2002 09:04:32 +0900 (JST)
	by coconut.itojun.org (Postfix) with ESMTP id 6C2444B22
	for <itojun@itojun.org>; Wed, 11 Sep 2002 08:07:53 +0900 (JST)
	by cvs.openbsd.org (8.12.5/8.12.1) with ESMTP id g8AN7Sf4018453
	(version=TLSv1/SSLv3 cipher=EDH-DSS-DES-CBC3-SHA bits=168 verify=FAIL);
	Tue, 10 Sep 2002 17:07:30 -0600 (MDT)
	by openbsd.cs.colorado.edu (8.12.5/8.12.5) with ESMTP id g8AN6PAX023216
	(version=TLSv1/SSLv3 cipher=EDH-DSS-DES-CBC3-SHA bits=168 verify=FAIL);
	Tue, 10 Sep 2002 17:06:26 -0600 (MDT)
	by mx04.nexgo.de (Postfix) with ESMTP
	id AC49E37BEA; Wed, 11 Sep 2002 01:06:23 +0200 (CEST)
	id 24A8E34093; Wed, 11 Sep 2002 01:02:51 +0200 (CEST)
Date: Wed, 11 Sep 2002 01:02:50 +0200
From: Markus Friedl <markus@openbsd.org>
To: openssh@openbsd.org
Cc: itojun@openbsd.org
Subject: privsep for kerb4, too
Message-ID: <20020910230250.GA31748@folly>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
User-Agent: Mutt/1.3.28i

what about this? this is based on a patch from jan.iven@cern.ch 
and similar to the krb5 patch from okir@suse.de

itojun, do you know some kerberos guys for testing this?

thanks, -m

Index: auth-krb4.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth-krb4.c,v
retrieving revision 1.27
diff -u -r1.27 auth-krb4.c
--- auth-krb4.c	11 Jun 2002 05:46:20 -0000	1.27
+++ auth-krb4.c	10 Sep 2002 22:32:57 -0000
@@ -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 */
Index: auth.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth.h,v
retrieving revision 1.40
diff -u -r1.40 auth.h
--- auth.h	9 Sep 2002 06:48:06 -0000	1.40
+++ auth.h	10 Sep 2002 22:59:54 -0000
@@ -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 *);
 
Index: auth1.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/auth1.c,v
retrieving revision 1.43
diff -u -r1.43 auth1.c
--- auth1.c	9 Sep 2002 06:48:06 -0000	1.43
+++ auth1.c	10 Sep 2002 22:49:20 -0000
@@ -116,17 +116,25 @@
 
 				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();
+
 						xfree(client_user);
 					}
 #endif /* KRB4 */
Index: monitor.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/monitor.c,v
retrieving revision 1.26
diff -u -r1.26 monitor.c
--- monitor.c	9 Sep 2002 14:54:15 -0000	1.26
+++ monitor.c	10 Sep 2002 23:00:25 -0000
@@ -116,6 +116,9 @@
 int mm_answer_sesskey(int, Buffer *);
 int mm_answer_sessid(int, Buffer *);
 
+#ifdef KRB4
+int mm_answer_krb4(int, Buffer *);
+#endif
 #ifdef KRB5
 int mm_answer_krb5(int, Buffer *);
 #endif
@@ -193,6 +196,9 @@
     {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
     {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
 #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
@@ -1250,6 +1256,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
Index: monitor.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/monitor.h,v
retrieving revision 1.7
diff -u -r1.7 monitor.h
--- monitor.h	9 Sep 2002 06:48:06 -0000	1.7
+++ monitor.h	10 Sep 2002 22:33:20 -0000
@@ -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_TERM
 };
Index: monitor_wrap.c
===================================================================
RCS file: /cvs/src/usr.bin/ssh/monitor_wrap.c,v
retrieving revision 1.18
diff -u -r1.18 monitor_wrap.c
--- monitor_wrap.c	9 Sep 2002 14:54:15 -0000	1.18
+++ monitor_wrap.c	10 Sep 2002 22:59:16 -0000
@@ -918,6 +918,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)
Index: monitor_wrap.h
===================================================================
RCS file: /cvs/src/usr.bin/ssh/monitor_wrap.h,v
retrieving revision 1.7
diff -u -r1.7 monitor_wrap.h
--- monitor_wrap.h	9 Sep 2002 06:48:06 -0000	1.7
+++ monitor_wrap.h	10 Sep 2002 22:35:44 -0000
@@ -79,7 +79,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 */


------- =_aaaaaaaaaa0--