[CalendarServer-changes] [2146] PyKerberos/branches/more-kerberos

source_changes at macosforge.org source_changes at macosforge.org
Fri Feb 15 07:43:43 PST 2008


Revision: 2146
          http://trac.macosforge.org/projects/calendarserver/changeset/2146
Author:   cdaboo at apple.com
Date:     2008-02-15 07:43:41 -0800 (Fri, 15 Feb 2008)

Log Message:
-----------
Wrap/Unwrap patch from ticket #214. Plus some minor code clean-up.

Modified Paths:
--------------
    PyKerberos/branches/more-kerberos/pysrc/kerberos.py
    PyKerberos/branches/more-kerberos/src/kerberos.c
    PyKerberos/branches/more-kerberos/src/kerberosgss.c
    PyKerberos/branches/more-kerberos/src/kerberosgss.h

Modified: PyKerberos/branches/more-kerberos/pysrc/kerberos.py
===================================================================
--- PyKerberos/branches/more-kerberos/pysrc/kerberos.py	2008-02-15 15:11:14 UTC (rev 2145)
+++ PyKerberos/branches/more-kerberos/pysrc/kerberos.py	2008-02-15 15:43:41 UTC (rev 2146)
@@ -126,6 +126,23 @@
     @return:          a string containing the user name.
     """
 
+def authGSSClientUnwrap(context, challenge): 
+    """ 
+    Perform the client side GSSAPI unwrap step 
+    
+    @param challenge: a string containing the base64-encoded server data. 
+    @return: a result code (see above) 
+    """ 
+
+def authGSSClientWrap(context, data, user): 
+    """ 
+    Perform the client side GSSAPI wrap step.  
+    
+    @param data:the result of the authGSSClientResponse after the authGSSClientUnwrap 
+    @param user: the user to authorize 
+    @return: a result code (see above) 
+    """ 
+
 def authGSSServerInit(service):
     """
     Initializes a context for GSSAPI server-side authentication with the given service principal.

Modified: PyKerberos/branches/more-kerberos/src/kerberos.c
===================================================================
--- PyKerberos/branches/more-kerberos/src/kerberos.c	2008-02-15 15:11:14 UTC (rev 2145)
+++ PyKerberos/branches/more-kerberos/src/kerberos.c	2008-02-15 15:43:41 UTC (rev 2146)
@@ -32,12 +32,12 @@
     const char *service;
     const char *default_realm;
     int result = 0;
-	
+
     if (!PyArg_ParseTuple(args, "ssss", &user, &pswd, &service, &default_realm))
         return NULL;
+
+    result = authenticate_user_krb5pwd(user, pswd, service, default_realm);
 	
-	result = authenticate_user_krb5pwd(user, pswd, service, default_realm);
-	
 	if (result)
 		return Py_INCREF(Py_True), Py_True;
 	else
@@ -157,6 +157,48 @@
     return Py_BuildValue("s", state->username);
 }
 
+static PyObject *authGSSClientUnwrap(PyObject *self, PyObject *args)
+{
+	gss_client_state *state;
+	PyObject *pystate;
+	char *challenge;
+	int result = 0;
+
+	if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge) || !PyCObject_Check(pystate))
+		return NULL;
+
+	state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
+	if (state == NULL)
+		return NULL;
+
+	result = authenticate_gss_client_unwrap(state, challenge);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
+
+	return Py_BuildValue("i", result);
+}
+
+static PyObject *authGSSClientWrap(PyObject *self, PyObject *args)
+{
+	gss_client_state *state;
+	PyObject *pystate;
+	char *challenge, *user;
+	int result = 0;
+
+	if (!PyArg_ParseTuple(args, "Oss", &pystate, &challenge, &user) || !PyCObject_Check(pystate))
+		return NULL;
+
+	state = (gss_client_state *)PyCObject_AsVoidPtr(pystate);
+	if (state == NULL)
+		return NULL;
+
+	result = authenticate_gss_client_wrap(state, challenge, user);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
+
+	return Py_BuildValue("i", result);
+}
+
 static PyObject *authGSSServerInit(PyObject *self, PyObject *args)
 {
     const char *service;
@@ -264,7 +306,11 @@
 		"Get the response from the last client-side GSSAPI step."},
     {"authGSSClientUserName",  authGSSClientUserName, METH_VARARGS,
 		"Get the user name from the last client-side GSSAPI step."},
-    {"authGSSServerInit",  authGSSServerInit, METH_VARARGS,
+	{"authGSSClientWrap",  authGSSClientWrap, METH_VARARGS, 
+		"Do a GSSAPI wrap."}, 
+	{"authGSSClientUnwrap",  authGSSClientUnwrap, METH_VARARGS, 
+		"Do a GSSAPI unwrap."}, 
+	{"authGSSServerInit",  authGSSServerInit, METH_VARARGS,
 		"Initialize server-side GSSAPI operations."},
     {"authGSSServerClean",  authGSSServerClean, METH_VARARGS,
 		"Terminate server-side GSSAPI operations."},
@@ -303,7 +349,7 @@
     PyDict_SetItemString(d, "GSSError", GssException_class);
 
     PyDict_SetItemString(d, "AUTH_GSS_COMPLETE", PyInt_FromLong(AUTH_GSS_COMPLETE)); 
- 	PyDict_SetItemString(d, "AUTH_GSS_CONTINUE", PyInt_FromLong(AUTH_GSS_CONTINUE)); 
+    PyDict_SetItemString(d, "AUTH_GSS_CONTINUE", PyInt_FromLong(AUTH_GSS_CONTINUE)); 
 
 error:
     if (PyErr_Occurred())

Modified: PyKerberos/branches/more-kerberos/src/kerberosgss.c
===================================================================
--- PyKerberos/branches/more-kerberos/src/kerberosgss.c	2008-02-15 15:11:14 UTC (rev 2145)
+++ PyKerberos/branches/more-kerberos/src/kerberosgss.c	2008-02-15 15:43:41 UTC (rev 2146)
@@ -24,24 +24,25 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <arpa/inet.h> 
 
 static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min);
 
 extern PyObject *GssException_class;
 extern PyObject *KrbException_class;
 
-char* server_principal_details(const char* service, const char* hostname)
+char *server_principal_details(const char *service, const char *hostname)
 {
 	char match[1024];
 	int match_len = 0;
-	char* result = NULL;
+	char *result = NULL;
 
 	int code;
     krb5_context kcontext;
     krb5_keytab kt = NULL;
     krb5_kt_cursor cursor = NULL;
     krb5_keytab_entry entry;
-    char* pname = NULL;
+    char *pname = NULL;
 
 	// Generate the principal prefix we want to match
 	snprintf(match, 1024, "%s/%s@", service, hostname);
@@ -106,7 +107,7 @@
 	return result;
 }
 
-int authenticate_gss_client_init(const char* service, gss_client_state *state)
+int authenticate_gss_client_init(const char *service, gss_client_state *state)
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
@@ -159,7 +160,7 @@
 	return ret;
 }
 
-int authenticate_gss_client_step(gss_client_state *state, const char* challenge)
+int authenticate_gss_client_step(gss_client_state *state, const char *challenge)
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
@@ -254,10 +255,139 @@
 	return ret;
 }
 
-int authenticate_gss_server_init(const char* service, gss_server_state *state)
+int authenticate_gss_client_unwrap(gss_client_state *state, const char *challenge)
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
+	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+	int ret = AUTH_GSS_CONTINUE;
+
+	// Always clear out the old response
+	if (state->response != NULL)
+	{
+		free(state->response);
+		state->response = NULL;
+	}
+
+	// If there is a challenge (data from the server) we need to give it to GSS
+	if (challenge && *challenge)
+	{
+		int len;
+		input_token.value = base64_decode(challenge, &len);
+		input_token.length = len;
+	}
+
+	// Do GSSAPI step
+	maj_stat = gss_unwrap(&min_stat,
+							state->context,
+							&input_token,
+							&output_token,
+							NULL,
+							NULL);
+
+	if (maj_stat != GSS_S_COMPLETE)
+	{
+		set_gss_error(maj_stat, min_stat);
+		ret = AUTH_GSS_ERROR;
+		goto end;
+	}
+	else
+		ret = AUTH_GSS_COMPLETE;
+
+	// Grab the client response
+	if (output_token.length)
+	{
+		state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);
+		maj_stat = gss_release_buffer(&min_stat, &output_token);
+	}
+end:
+	if (output_token.value)
+		gss_release_buffer(&min_stat, &output_token);
+	if (input_token.value)
+		free(input_token.value);
+	return ret;
+}
+
+int authenticate_gss_client_wrap(gss_client_state *state, const char *challenge, const char *user)
+{
+	OM_uint32 maj_stat;
+	OM_uint32 min_stat;
+	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+	int ret = AUTH_GSS_CONTINUE;
+	char buf[4096], server_conf_flags;
+	unsigned long buf_size;
+
+	// Always clear out the old response
+	if (state->response != NULL)
+	{
+		free(state->response);
+		state->response = NULL;
+	}
+
+	if (challenge && *challenge)
+	{
+		int len;
+		input_token.value = base64_decode(challenge, &len);
+		input_token.length = len;
+	}
+
+	// get bufsize
+	server_conf_flags = ((char*) input_token.value)[0];
+	((char*) input_token.value)[0] = 0;
+	buf_size = ntohl(*((long *) input_token.value));
+	free(input_token.value);
+#if 0
+	printf("User: %s, %c%c%c\n", user,
+		server_conf_flags & GSS_AUTH_P_NONE\xCA \xCA \xCA ? 'N' : '-',
+		server_conf_flags & GSS_AUTH_P_INTEGRITY ? 'I' : '-',
+		server_conf_flags & GSS_AUTH_P_PRIVACY\xCA \xCA? 'P' : '-');
+	printf("Maximum GSS token size is %ld\n", buf_size);
+#endif
+
+	// agree to terms (hack!)
+	buf_size = htonl(buf_size); // not relevant without integrity/privacy
+	memcpy(buf, &buf_size, 4);
+	buf[0] = GSS_AUTH_P_NONE;
+	// server decides if principal can log in as user
+	strncpy(buf + 4, user, sizeof(buf) - 4);
+	input_token.value = buf;
+	input_token.length = 4 + strlen(user) + 1;
+
+	// Do GSSAPI wrap
+	maj_stat = gss_wrap(&min_stat,
+						state->context,
+						0,
+						GSS_C_QOP_DEFAULT,
+						&input_token,
+						NULL,
+						&output_token);
+
+	if (maj_stat != GSS_S_COMPLETE)
+	{
+		set_gss_error(maj_stat, min_stat);
+		ret = AUTH_GSS_ERROR;
+		goto end;
+	}
+	else
+		ret = AUTH_GSS_COMPLETE;
+	// Grab the client response to send back to the server
+	if (output_token.length)
+	{
+		state->response = base64_encode((const unsigned char *)output_token.value, output_token.length);;
+		maj_stat = gss_release_buffer(&min_stat, &output_token);
+	}
+end:
+	if (output_token.value)
+		gss_release_buffer(&min_stat, &output_token);
+	return ret;
+}
+
+int authenticate_gss_server_init(const char *service, gss_server_state *state)
+{
+	OM_uint32 maj_stat;
+	OM_uint32 min_stat;
 	gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
 	int ret = AUTH_GSS_COMPLETE;
 	

Modified: PyKerberos/branches/more-kerberos/src/kerberosgss.h
===================================================================
--- PyKerberos/branches/more-kerberos/src/kerberosgss.h	2008-02-15 15:11:14 UTC (rev 2145)
+++ PyKerberos/branches/more-kerberos/src/kerberosgss.h	2008-02-15 15:43:41 UTC (rev 2146)
@@ -23,14 +23,18 @@
 #define krb5_get_err_text(context,code) error_message(code)
 
 #define AUTH_GSS_ERROR		-1
-#define AUTH_GSS_COMPLETE	1
-#define AUTH_GSS_CONTINUE	0
+#define AUTH_GSS_COMPLETE	 1
+#define AUTH_GSS_CONTINUE	 0
 
+#define GSS_AUTH_P_NONE         1 
+#define GSS_AUTH_P_INTEGRITY    2 
+#define GSS_AUTH_P_PRIVACY      4 
+ 	
 typedef struct {
 	gss_ctx_id_t    context;
 	gss_name_t		server_name;
-	char*			username;
-	char*			response;
+	char *			username;
+	char *			response;
 } gss_client_state;
 
 typedef struct {
@@ -39,16 +43,18 @@
 	gss_name_t		client_name;
     gss_cred_id_t	server_creds;
     gss_cred_id_t	client_creds;
-	char*			username;
-	char*			response;
+	char *			username;
+	char *			response;
 } gss_server_state;
 
-char* server_principal_details(const char* service, const char* hostname);
+char *server_principal_details(const char *service, const char *hostname);
 
-int authenticate_gss_client_init(const char* service, gss_client_state *state);
+int authenticate_gss_client_init(const char *service, gss_client_state *state);
 int authenticate_gss_client_clean(gss_client_state *state);
 int authenticate_gss_client_step(gss_client_state *state, const char *challenge);
+int authenticate_gss_client_unwrap(gss_client_state *state, const char *challenge); 
+int authenticate_gss_client_wrap(gss_client_state *state, const char *challenge, const char *user);
 
-int authenticate_gss_server_init(const char* service, gss_server_state *state);
+int authenticate_gss_server_init(const char *service, gss_server_state *state);
 int authenticate_gss_server_clean(gss_server_state *state);
 int authenticate_gss_server_step(gss_server_state *state, const char *challenge);

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080215/890c213d/attachment-0001.html 


More information about the calendarserver-changes mailing list