[CalendarServer-changes] [271] PyKerberos/trunk

source_changes at macosforge.org source_changes at macosforge.org
Fri Oct 13 11:55:37 PDT 2006


Revision: 271
          http://trac.macosforge.org/projects/calendarserver/changeset/271
Author:   cdaboo at apple.com
Date:     2006-10-13 11:55:36 -0700 (Fri, 13 Oct 2006)

Log Message:
-----------
Exception handling contributed by Guido Guenther.

Modified Paths:
--------------
    PyKerberos/trunk/pysrc/kerberos.py
    PyKerberos/trunk/src/kerberos.c
    PyKerberos/trunk/src/kerberosbasic.c
    PyKerberos/trunk/src/kerberosgss.c
    PyKerberos/trunk/test.py

Modified: PyKerberos/trunk/pysrc/kerberos.py
===================================================================
--- PyKerberos/trunk/pysrc/kerberos.py	2006-10-12 18:45:06 UTC (rev 270)
+++ PyKerberos/trunk/pysrc/kerberos.py	2006-10-13 18:55:36 UTC (rev 271)
@@ -20,6 +20,15 @@
 PyKerberos Function Description.
 """
 
+class KrbError(Exception):
+    pass
+
+class BasicAuthError(KrbError):
+    pass
+
+class GSSError(KrbError):
+    pass
+
 def checkPassword(user, pswd, service, default_realm):
     """
     This function provides a simple way to verify that a user name and password match

Modified: PyKerberos/trunk/src/kerberos.c
===================================================================
--- PyKerberos/trunk/src/kerberos.c	2006-10-12 18:45:06 UTC (rev 270)
+++ PyKerberos/trunk/src/kerberos.c	2006-10-13 18:55:36 UTC (rev 271)
@@ -21,6 +21,10 @@
 #include "kerberosbasic.h"
 #include "kerberosgss.h"
 
+PyObject *KrbException_class;
+PyObject *BasicAuthException_class;
+PyObject *GssException_class;
+
 static PyObject *checkPassword(PyObject *self, PyObject *args)
 {
     const char *user;
@@ -37,7 +41,7 @@
 	if (result)
 		return Py_INCREF(Py_True), Py_True;
 	else
-		return Py_INCREF(Py_False), Py_False;
+		return NULL;
 }
 
 static PyObject *authGSSClientInit(PyObject *self, PyObject *args)
@@ -54,6 +58,8 @@
 	pystate = PyCObject_FromVoidPtr(state, NULL);
 	
 	result = authenticate_gss_client_init(service, state);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
 	
     return Py_BuildValue("(iO)", result, pystate);
 }
@@ -94,6 +100,8 @@
 		return NULL;
 
 	result = authenticate_gss_client_step(state, challenge);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
 	
     return Py_BuildValue("i", result);
 }
@@ -142,6 +150,8 @@
 	pystate = PyCObject_FromVoidPtr(state, NULL);
 	
 	result = authenticate_gss_server_init(service, state);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
 	
     return Py_BuildValue("(iO)", result, pystate);
 }
@@ -182,6 +192,8 @@
 		return NULL;
 	
 	result = authenticate_gss_server_step(state, challenge);
+	if (result == AUTH_GSS_ERROR)
+		return NULL;
 	
     return Py_BuildValue("i", result);
 }
@@ -216,7 +228,7 @@
     return Py_BuildValue("s", state->username);
 }
 
-static PyMethodDef SpamMethods[] = {
+static PyMethodDef KerberosMethods[] = {
     {"checkPassword",  checkPassword, METH_VARARGS,
 		"Check the supplied user/password against Kerberos KDC."},
     {"authGSSClientInit",  authGSSClientInit, METH_VARARGS,
@@ -244,5 +256,30 @@
 
 PyMODINIT_FUNC initkerberos(void)
 {
-    (void) Py_InitModule("kerberos", SpamMethods);
+    PyObject *m,*d;
+
+    m = Py_InitModule("kerberos", KerberosMethods);
+
+    d = PyModule_GetDict(m);
+
+    /* create the base exception class */
+    if (!(KrbException_class = PyErr_NewException("kerberos.KrbError", NULL, NULL)))
+        goto error;
+    PyDict_SetItemString(d, "KrbError", KrbException_class);
+    Py_INCREF(KrbException_class);
+
+    /* ...and the derived exceptions */
+    if (!(BasicAuthException_class = PyErr_NewException("kerberos.BasicAuthError", KrbException_class, NULL)))
+    	goto error;
+    Py_INCREF(BasicAuthException_class);
+    PyDict_SetItemString(d, "BasicAuthError", BasicAuthException_class);
+
+    if (!(GssException_class = PyErr_NewException("kerberos.GSSError", KrbException_class, NULL)))
+		goto error;
+    Py_INCREF(GssException_class);
+    PyDict_SetItemString(d, "GSSError", GssException_class);
+
+error:
+    if (PyErr_Occurred())
+		PyErr_SetString(PyExc_ImportError, "kerberos: init failed");
 }

Modified: PyKerberos/trunk/src/kerberosbasic.c
===================================================================
--- PyKerberos/trunk/src/kerberosbasic.c	2006-10-12 18:45:06 UTC (rev 270)
+++ PyKerberos/trunk/src/kerberosbasic.c	2006-10-13 18:55:36 UTC (rev 271)
@@ -16,6 +16,7 @@
  * DRI: Cyrus Daboo, cdaboo at apple.com
  **/
 
+#include <Python.h>
 #include "kerberosbasic.h"
 
 #include <stdio.h>
@@ -24,6 +25,9 @@
 
 #undef PRINTFS
 
+extern PyObject *BasicAuthException_class;
+static void set_basicauth_error(krb5_context context, krb5_error_code code);
+
 static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server);
 
 int authenticate_user_krb5pwd(const char *user, const char *pswd, const char *service, const char *default_realm)
@@ -39,9 +43,8 @@
 	code = krb5_init_context(&kcontext);
 	if (code)
 	{
-#ifdef PRINTFS
-		printf("Cannot initialize Kerberos5 context (%d)\n", code);
-#endif
+		PyErr_SetObject(BasicAuthException_class, Py_BuildValue("((s:i))",
+						"Cannot initialize Kerberos5 context", code));
 		return 0;
 	}
 	
@@ -49,9 +52,7 @@
 	
 	if (ret)
 	{
-#ifdef PRINTFS
-		printf("Error parsing server name (%s): %s\n", service, krb5_get_err_text(kcontext, ret));
-#endif
+		set_basicauth_error(kcontext, ret);
 		ret = 0;
 		goto end;
 	}
@@ -59,9 +60,7 @@
 	code = krb5_unparse_name(kcontext, server, &name);
 	if (code)
 	{
-#ifdef PRINTFS
-		printf("krb5_unparse_name() failed: %s\n", krb5_get_err_text(kcontext, code));
-#endif
+		set_basicauth_error(kcontext, code);
 		ret = 0;
 		goto end;
 	}
@@ -85,9 +84,7 @@
 	code = krb5_parse_name(kcontext, name, &client);
 	if (code)
 	{
-#ifdef PRINTFS
-		printf("krb5_parse_name() failed: %s\n", krb5_get_err_text(kcontext, code));
-#endif
+		set_basicauth_error(kcontext, code);
 		ret = 0;
 		goto end;
 	}
@@ -113,7 +110,6 @@
 	if (server)
 		krb5_free_principal(kcontext, server);
 	krb5_free_context(kcontext);
-
 	
 	return ret;
 }
@@ -139,9 +135,7 @@
 	ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, NULL);
 	if (ret)
 	{
-#ifdef PRINTFS
-		printf("krb5_get_init_creds_password() failed: %s\n",  krb5_get_err_text(context, ret));
-#endif
+		set_basicauth_error(context, ret);
 		goto end;
 	}
 	
@@ -151,3 +145,7 @@
 	return ret;
 }
 
+static void set_basicauth_error(krb5_context context, krb5_error_code code)
+{
+	PyErr_SetObject(BasicAuthException_class, Py_BuildValue("(s:i)", krb5_get_err_text(context, code), code));
+}

Modified: PyKerberos/trunk/src/kerberosgss.c
===================================================================
--- PyKerberos/trunk/src/kerberosgss.c	2006-10-12 18:45:06 UTC (rev 270)
+++ PyKerberos/trunk/src/kerberosgss.c	2006-10-13 18:55:36 UTC (rev 271)
@@ -16,6 +16,7 @@
  * DRI: Cyrus Daboo, cdaboo at apple.com
  **/
 
+#include <Python.h>
 #include "kerberosgss.h"
 
 #include "base64.h"
@@ -24,17 +25,15 @@
 #include <stdlib.h>
 #include <string.h>
 
-#undef PRINTFS
+static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min);
 
-static const char *get_gss_error(char *p, int psize, OM_uint32 err_maj, OM_uint32 err_min, char *prefix);
+extern PyObject *GssException_class;
+extern PyObject *KrbException_class;
 
 int authenticate_gss_client_init(const char* service, gss_client_state *state)
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
-#ifdef PRINTFS
-	char buf[1024];
-#endif
 	gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
 	int ret = AUTH_GSS_COMPLETE;
 
@@ -45,15 +44,13 @@
 	
 	// Import server name first
 	name_token.length = strlen(service);
-    name_token.value = (char *)service;
+	name_token.value = (char *)service;
 	
 	maj_stat = gss_import_name(&min_stat, &name_token, gss_krb5_nt_service_name, &state->server_name);
 	
 	if (GSS_ERROR(maj_stat))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_import_name() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -90,9 +87,6 @@
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
-#ifdef PRINTFS
-	char buf[1024];
-#endif
 	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
 	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
 	int ret = AUTH_GSS_CONTINUE;
@@ -129,9 +123,7 @@
 	
 	if ((maj_stat != GSS_S_COMPLETE) && (maj_stat != GSS_S_CONTINUE_NEEDED))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_init_sec_context() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -151,9 +143,7 @@
 	    maj_stat = gss_inquire_context(&min_stat, state->context, &gssuser, NULL, NULL, NULL,  NULL, NULL, NULL);
 		if (GSS_ERROR(maj_stat))
 		{
-#ifdef PRINTFS
-			printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_inquire_context() failed"));
-#endif
+			set_gss_error(maj_stat, min_stat);
 			ret = AUTH_GSS_ERROR;
 			goto end;
 		}
@@ -167,9 +157,7 @@
 			    gss_release_buffer(&min_stat, &name_token);
 			gss_release_name(&min_stat, &gssuser);
 			
-#ifdef PRINTFS
-			printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_display_name() failed"));
-#endif
+			set_gss_error(maj_stat, min_stat);
 			ret = AUTH_GSS_ERROR;
 			goto end;
 		}
@@ -194,9 +182,6 @@
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
-#ifdef PRINTFS
-	char buf[1024];
-#endif
 	gss_buffer_desc name_token = GSS_C_EMPTY_BUFFER;
 	int ret = AUTH_GSS_COMPLETE;
 	
@@ -216,9 +201,7 @@
 	
 	if (GSS_ERROR(maj_stat))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_import_name() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -229,9 +212,7 @@
 
 	if (GSS_ERROR(maj_stat))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_acquire_cred() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -274,9 +255,6 @@
 {
 	OM_uint32 maj_stat;
 	OM_uint32 min_stat;
-#ifdef PRINTFS
-	char buf[1024];
-#endif
 	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
 	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
 	int ret = AUTH_GSS_CONTINUE;
@@ -297,9 +275,7 @@
 	}
 	else
 	{
-#ifdef PRINTFS
-		printf("No challenge parameter in request from client\n");
-#endif
+		PyErr_SetString(KrbException_class, "No challenge parameter in request from client");
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -318,9 +294,7 @@
 	
 	if (GSS_ERROR(maj_stat))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_accept_sec_context() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -335,9 +309,7 @@
 	maj_stat = gss_display_name(&min_stat, state->client_name, &output_token, NULL);
 	if (GSS_ERROR(maj_stat))
 	{
-#ifdef PRINTFS
-		printf("%s\n", get_gss_error(buf, 1024, maj_stat, min_stat, "gss_display_name() failed"));
-#endif
+		set_gss_error(maj_stat, min_stat);
 		ret = AUTH_GSS_ERROR;
 		goto end;
 	}
@@ -355,13 +327,15 @@
 	return ret;
 }
 
-const char *get_gss_error(char *p, int psize, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
+
+static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min)
 {
 	OM_uint32 maj_stat, min_stat; 
 	OM_uint32 msg_ctx = 0;
 	gss_buffer_desc status_string;
+	char buf_maj[512];
+	char buf_min[512];
 	
-	strncpy(p, prefix, psize);
 	do
 	{
 		maj_stat = gss_display_status (&min_stat,
@@ -372,8 +346,7 @@
 									   &status_string);
 		if (GSS_ERROR(maj_stat))
 			break;
-		strncat(p, ": ", psize);
-		strncat(p, (char*) status_string.value, psize);
+		strncpy(buf_maj, (char*) status_string.value, sizeof(buf_maj));
 		gss_release_buffer(&min_stat, &status_string);
 		
 		maj_stat = gss_display_status (&min_stat,
@@ -384,12 +357,11 @@
 									   &status_string);
 		if (!GSS_ERROR(maj_stat))
 		{
-			strncat(p, " (", psize);
-			strncat(p, (char*) status_string.value, psize);
-			strncat(p, ")", psize);
+			strncpy(buf_min, (char*) status_string.value, sizeof(buf_min));
 			gss_release_buffer(&min_stat, &status_string);
 		}
 	} while (!GSS_ERROR(maj_stat) && msg_ctx != 0);
 	
-	return p;
+	PyErr_SetObject(GssException_class, Py_BuildValue("((s:i)(s:i))", buf_maj, err_maj, buf_min, err_min));
 }
+

Modified: PyKerberos/trunk/test.py
===================================================================
--- PyKerberos/trunk/test.py	2006-10-12 18:45:06 UTC (rev 270)
+++ PyKerberos/trunk/test.py	2006-10-13 18:55:36 UTC (rev 271)
@@ -56,7 +56,7 @@
         print "\n*** Skipping basic test: no user or password specified"
 
     print "\n*** Running GSSAPI test"
-    #testGSSAPI(service)
+    testGSSAPI(service)
 
     print "\n*** Running HTTP test"
     testHTTP(host, port, ssl, service)
@@ -64,11 +64,12 @@
     print "\n*** Done\n"
 
 def testCheckpassword(user, pswd, service, realm):
-    result = kerberos.checkPassword(user, pswd, service, realm)
-    if result:
+    try:
+        kerberos.checkPassword(user, pswd, service, realm)
+    except kerberos.BasicAuthError, e:
+        print "Kerberos authentication for %s failed: %s" % (user, e[0])
+    else:
         print "Kerberos authentication for %s succeeded" % user
-    else:
-        print "Kerberos authentication for %s failed" % user
 
 def testGSSAPI(service):
     def statusText(r):
@@ -129,7 +130,8 @@
         return response
 
     # Initial request without auth header
-    response = sendRequest(host, port, ssl, "OPTIONS", "/", {})
+    uri = "/"
+    response = sendRequest(host, port, ssl, "OPTIONS", uri, {})
     
     if response is None:
         print "Initial HTTP request to server failed"
@@ -151,28 +153,30 @@
         print "Incorrect www-authenticate header in initial HTTP response: %s" % hdr        
         return
 
-    rc, vc = kerberos.authGSSClientInit(service);
-    if rc != 1:
-        print "Could not initialize GSSAPI"
+    try:
+        rc, vc = kerberos.authGSSClientInit(service);
+    except kerberos.GSSError, e:
+        print "Could not initialize GSSAPI: %s/%s" % (e[0][0], e[1][0])
         return
 
-    rc = kerberos.authGSSClientStep(vc, "");
-    if rc != 0:
-        print "Could not do GSSAPI setp with continue"
+    try:
+        kerberos.authGSSClientStep(vc, "");
+    except kerberos.GSSError, e:
+        print "Could not do GSSAPI setp with continue: %s/%s" % (e[0][0], e[1][0])
         return
 
     hdrs = {}
     hdrs["Authorization"] = "negotiate %s" % kerberos.authGSSClientResponse(vc)    
 
     # Second request with auth header
-    response = sendRequest(host, port, ssl, "OPTIONS", "/", hdrs)
+    response = sendRequest(host, port, ssl, "OPTIONS", uri, hdrs)
     
     if response is None:
         print "Second HTTP request to server failed"
         return
     
     if response.status/100 != 2:
-        print "Second HTTP request did not result in a 2xx response"
+        print "Second HTTP request did not result in a 2xx response: %d" % (response.status,)
         return
     
     hdrs = response.msg.getheaders("www-authenticate")
@@ -180,22 +184,24 @@
         print "No www-authenticate header in second HTTP response."
         return
     if len(hdrs) != 1:
-        print "Too many www-authenticate headers in second HTTP response."
+        print "Too many www-authenticate headers in second HTTP response: %d." % (len(hdrs),)
         return
     hdr = hdrs[0].strip()
     splits = hdr.split(' ', 1)
     if (len(splits) != 2) or (splits[0].lower() != "negotiate"):
-        print "Incorrect www-authenticate header in second HTTP response: %s" % hdr        
+        print "Incorrect www-authenticate header in second HTTP response: %s" % hdr
         return
     
-    rc = kerberos.authGSSClientStep(vc, splits[1]);
-    if rc != 1:
-        print "Could not verify server www-authenticate header in second HTTP response"
+    try:
+        kerberos.authGSSClientStep(vc, splits[1])
+    except kerberos.GSSError, e:
+        print "Could not verify server www-authenticate header in second HTTP response: %s/%s" % (e[0][0], e[1][0])
         return
     
-    rc = kerberos.authGSSClientClean(vc);
-    if rc != 1:
-        print "Could not clean-up GSSAPI"
+    try:
+        rc = kerberos.authGSSClientClean(vc);
+    except kerberos.GSSError, e:
+        print "Could not clean-up GSSAPI: %s/%s" % (e[0][0], e[1][0])
         return
 
     return

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20061013/8300737e/attachment.html


More information about the calendarserver-changes mailing list