Patch: Kerberos auth + PrivSep (against 3.5p1-CVS)

Jan Iven jan.iven at cern.ch
Thu Oct 10 19:25:01 EST 2002


Dear list,

this patch implements the missing (vs. CVS, as of 08.10.02)
functionality to have privsep+Kerberos authentication working
together. There seems to be some effort into that direction already
(?), some bits of the previous patch for 3.4 are no longer
neccessary. Could somebody from the developers confirm this (since I'd
be happy to drop my version if something better is supposed to appear
anyway).

Compiles fine for me, have not tested on all our platforms yet. The
previous version of this patch (against 3.4) runs on
Solaris,Linux,HPUX, Digital and IRIX.

Thanks
Jan


diff -uwr openssh-cvs/monitor.c openssh-new/monitor.c
--- openssh-cvs/monitor.c	2002-10-03 10:31:11.000000000 +0200
+++ openssh-new/monitor.c	2002-10-08 22:57:08.000000000 +0200
@@ -101,6 +101,14 @@
 int mm_answer_auth2_read_banner(int, Buffer *);
 int mm_answer_authserv(int, Buffer *);
 int mm_answer_authpassword(int, Buffer *);
+
+#ifdef KRB4
+int mm_answer_authkrb4(int, Buffer *);
+#endif
+#ifdef KRB5
+int mm_answer_authkrb5(int, Buffer *);
+#endif
+
 int mm_answer_bsdauthquery(int, Buffer *);
 int mm_answer_bsdauthrespond(int, Buffer *);
 int mm_answer_skeyquery(int, Buffer *);
@@ -195,6 +205,12 @@
     {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed},
     {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge},
     {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response},
+#ifdef KRB4
+    {MONITOR_REQ_AUTHKRB4, MON_AUTH, mm_answer_authkrb4},
+#endif
+#ifdef KRB5
+    {MONITOR_REQ_AUTHKRB5, MON_AUTH, mm_answer_authkrb5},
+#endif
 #ifdef BSD_AUTH
     {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery},
     {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond},
@@ -733,6 +755,93 @@
 }
 #endif
 
+#ifdef KRB4
+int
+mm_answer_authkrb4(int socket, Buffer *m)
+{
+	KTEXT_ST auth;
+	KTEXT_ST reply;
+	char  *localuser, *auth_tmp;
+	int authenticated, authlen;
+
+	reply.length = auth.length = 0;
+ 
+	auth_tmp = buffer_get_string(m, &authlen);
+	if (authlen >=  MAX_KTXT_LEN)
+		 fatal("%s: received too large KRB4 auth from privsep", __func__);
+	memcpy(auth.dat, auth_tmp, authlen);
+	auth.length = authlen;
+        memset(auth_tmp,0, authlen);
+	xfree(auth_tmp);
+	/* Only authenticate if the context is valid */
+	authenticated = options.kerberos_authentication &&
+		authctxt->valid &&
+		auth_krb4(authctxt, &auth, &localuser, &reply);
+
+	memset(auth.dat, 0, authlen);
+
+	buffer_clear(m);
+	buffer_put_int(m, authenticated);
+	if(authenticated) {
+		buffer_put_cstring(m, localuser);
+		buffer_put_string(m, reply.dat, reply.length);
+	}
+	  
+	if (reply.length)
+		memset(reply.dat, 0, reply.length);
+
+	debug3("%s: sending result %d", __func__, authenticated);
+	mm_request_send(socket, MONITOR_ANS_AUTHKRB4, m);
+
+	auth_method = "KRB4.klogin";
+
+	/* Causes monitor loop to terminate if authenticated */
+	return (authenticated);
+}
+#endif /* KRB4 */
+
+#ifdef KRB5
+int
+mm_answer_authkrb5(int socket, Buffer *m)
+{
+	krb5_data auth;
+	krb5_data reply;
+	char  *localuser;
+	int authenticated;
+
+	reply.length = 0;
+	reply.data = NULL;
+ 
+	auth.data = buffer_get_string(m, &auth.length);
+
+	/* Only authenticate if the context is valid */
+	authenticated = options.kerberos_authentication &&
+		authctxt->valid &&
+		auth_krb5(authctxt, &auth, &localuser, &reply);
+
+	memset(auth.data, 0, auth.length);
+	xfree(auth.data);
+
+	buffer_clear(m);
+	buffer_put_int(m, authenticated);
+	if(authenticated) {
+		buffer_put_cstring(m, localuser);
+		buffer_put_string(m, reply.data, reply.length);
+	}
+	  
+	memset(reply.data, 0, reply.length);
+	xfree(reply.data);
+
+	debug3("%s: sending result %d", __func__, authenticated);
+	mm_request_send(socket, MONITOR_ANS_AUTHKRB5, m);
+
+	auth_method = "KRB5.klogin";
+
+	/* Causes monitor loop to terminate if authenticated */
+	return (authenticated);
+}
+#endif /* KRB5 */
+
 #ifdef USE_PAM
 int
 mm_answer_pam_start(int socket, Buffer *m)
diff -uwr openssh-cvs/monitor.h openssh-new/monitor.h
--- openssh-cvs/monitor.h	2002-10-03 10:31:11.000000000 +0200
+++ openssh-new/monitor.h	2002-10-08 22:51:00.000000000 +0200
@@ -33,6 +33,12 @@
 	MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
 	MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
 	MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
+#ifdef KRB4
+	MONITOR_REQ_AUTHKRB4, MONITOR_ANS_AUTHKRB4,
+#endif
+#ifdef KRB5
+	MONITOR_REQ_AUTHKRB5, MONITOR_ANS_AUTHKRB5,
+#endif
 	MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
 	MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD,
 	MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY,
diff -uwr openssh-cvs/monitor_wrap.c openssh-new/monitor_wrap.c
--- openssh-cvs/monitor_wrap.c	2002-10-03 10:31:11.000000000 +0200
+++ openssh-new/monitor_wrap.c	2002-10-08 22:51:52.000000000 +0200
@@ -268,6 +268,75 @@
 	return (authenticated);
 }
 
+/* do Kerberos4 .klogin authentication */
+#ifdef KRB4
+int
+mm_auth_krb4(Authctxt *authctxt, KTEXT auth, char **client, KTEXT reply)
+{
+ 	Buffer m;
+	int rlen;
+	int authenticated = 0;
+	char* reply_tmp;
+
+	debug3("%s entering", __func__);
+
+	buffer_init(&m);
+	buffer_put_string(&m, auth->dat, auth->length);
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHKRB4, &m);
+
+	debug3("%s: waiting for MONITOR_ANS_AUTHKRB4", __func__);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHKRB4, &m);
+
+	authenticated = buffer_get_int(&m);
+	if(authenticated) {
+		*client = buffer_get_string(&m, NULL);
+		reply_tmp =  buffer_get_string(&m, &rlen);
+		/* have to get the string back into the fixed char field */
+		if(rlen >= MAX_KTXT_LEN)
+		 fatal("%s: received too large KRB4 reply from monitor", __func__);
+		memcpy(reply->dat, reply_tmp, rlen);
+		reply->length = rlen;
+		memset(reply_tmp,0, rlen);
+		xfree(reply_tmp);
+	}
+	buffer_free(&m);
+
+	debug3("%s: user %s %sauthenticated",
+	    __func__, *client, authenticated ? "" : "not ");
+	return (authenticated); 
+}
+#endif /* KRB4 */
+
+/* do Kerberos5 .klogin authentication */
+#ifdef KRB5
+int
+mm_auth_krb5(Authctxt *authctxt, krb5_data *auth, char **client, krb5_data *reply)
+{
+ 	Buffer m;
+	int authenticated = 0;
+
+	debug3("%s entering", __func__);
+
+	buffer_init(&m);
+	buffer_put_string(&m, auth->data, auth->length);
+	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHKRB5, &m);
+
+	debug3("%s: waiting for MONITOR_ANS_AUTHKRB5", __func__);
+	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHKRB5, &m);
+
+	authenticated = buffer_get_int(&m);
+	if(authenticated) {
+		*client = buffer_get_string(&m, NULL);
+		reply->data =  buffer_get_string(&m, &(reply->length));
+	}
+	buffer_free(&m);
+
+	debug3("%s: user %s %sauthenticated",
+	    __func__, *client, authenticated ? "" : "not ");
+	return (authenticated); 
+}
+#endif /* KRB5 */
+
 int
 mm_user_key_allowed(struct passwd *pw, Key *key)
 {
diff -uwr openssh-cvs/monitor_wrap.h openssh-new/monitor_wrap.h
--- openssh-cvs/monitor_wrap.h	2002-10-03 10:31:11.000000000 +0200
+++ openssh-new/monitor_wrap.h	2002-10-08 22:59:39.000000000 +0200
@@ -30,6 +30,14 @@
 #include "key.h"
 #include "buffer.h"
 
+#ifdef KRB4
+#include <krb.h>
+#endif
+
+#ifdef KRB5
+#include <krb5.h>
+#endif
+
 extern int use_privsep;
 #define PRIVSEP(x)	(use_privsep ? mm_##x : x)
 
@@ -59,6 +67,14 @@
 void mm_start_pam(char *);
 #endif
 
+#ifdef KRB4
+int mm_auth_krb4(struct Authctxt *, KTEXT , char **, KTEXT );
+#endif
+
+#ifdef KRB5
+int mm_auth_krb5(struct Authctxt *, krb5_data *, char **, krb5_data *);
+#endif
+
 void mm_terminate(void);
 int mm_pty_allocate(int *, int *, char *, int);
 void mm_session_pty_cleanup2(void *);





More information about the openssh-unix-dev mailing list