[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