[CalendarServer-dev] RFC: pykerberos exception handling (Ticket #51)
Guido Guenther
agx at sigxcpu.org
Wed Sep 27 06:57:06 PDT 2006
Hi,
attached is a patch that implements basic exception handling in
pykerberos GSS path. This way we can get more information about the what
actually failed (current pykerberos only knows success or AUTH_FAILED).
I'm posting this here for comments:
Things I'm unsure about are:
* how should the exception format look like? Currently I've chosen:
(errmsg_maj, errcode_maj)(errmsg_min, errcode_min)
so code like:
try:
rc = kerberos.authGSSClientStep(vc, "");
except kerberos.KrbError, a:
print a
gives:
(('Miscellaneous failure', 851968), ('No credentials cache found', -1765328189))
or in the case the exception is unhandled:
KrbError: (('Miscellaneous failure', 851968), ('Permission denied', 13))
Should we better choose different exception classes for every type of
problem (modeled after the error conditions listed in gssapi.h) -
looks like overkill to me - we can add functions to analyze the error
code in more detail at any later stage since we pass both major and
minor code up to the application.
* What exception classes do we want. What about:
KrbError as base class
KrbBasicAuthError(KrbError): exceptions in the basic auch module
KrbGssAuthError(krbError): excpetions in the GSS module
I'd be happy about any comments on this.
Cheers,
-- Guido
-------------- next part --------------
diff --git a/src/kerberos.c b/src/kerberos.c
index 419827c..1b1e098 100644
--- a/src/kerberos.c
+++ b/src/kerberos.c
@@ -21,6 +21,8 @@ #include <Python.h>
#include "kerberosbasic.h"
#include "kerberosgss.h"
+PyObject *KrbException_class;
+
static PyObject *checkPassword(PyObject *self, PyObject *args)
{
const char *user;
@@ -54,6 +56,9 @@ static PyObject *authGSSClientInit(PyObj
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);
}
@@ -82,8 +87,8 @@ static PyObject *authGSSClientClean(PyOb
static PyObject *authGSSClientStep(PyObject *self, PyObject *args)
{
gss_client_state *state;
- PyObject *pystate;
- char *challenge;
+ PyObject *pystate;
+ char *challenge;
int result = 0;
if (!PyArg_ParseTuple(args, "Os", &pystate, &challenge) || !PyCObject_Check(pystate))
@@ -94,6 +99,9 @@ static PyObject *authGSSClientStep(PyObj
return NULL;
result = authenticate_gss_client_step(state, challenge);
+ if(result == AUTH_GSS_ERROR) {
+ return NULL;
+ }
return Py_BuildValue("i", result);
}
@@ -142,6 +150,9 @@ static PyObject *authGSSServerInit(PyObj
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 +193,9 @@ static PyObject *authGSSServerStep(PyObj
return NULL;
result = authenticate_gss_server_step(state, challenge);
+ if(result == AUTH_GSS_ERROR) {
+ return NULL;
+ }
return Py_BuildValue("i", result);
}
@@ -216,7 +230,7 @@ static PyObject *authGSSServerUserName(P
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 +258,14 @@ static PyMethodDef SpamMethods[] = {
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 */
+ KrbException_class = PyErr_NewException("kerbros.KrbError", NULL, NULL);
+ PyDict_SetItemString( d, "KrbError", KrbException_class );
+ Py_INCREF(KrbException_class);
}
+
diff --git a/src/kerberosgss.c b/src/kerberosgss.c
index 7200786..4d2882c 100644
--- a/src/kerberosgss.c
+++ b/src/kerberosgss.c
@@ -16,6 +16,7 @@
* DRI: Cyrus Daboo, cdaboo at apple.com
**/
+#include <Python.h>
#include "kerberosgss.h"
#include "base64.h"
@@ -24,17 +25,14 @@ #include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#undef PRINTFS
+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 *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 +43,13 @@ #endif
// 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 +86,6 @@ int authenticate_gss_client_step(gss_cli
{
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 +122,7 @@ #endif
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 +142,7 @@ #endif
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 +156,7 @@ #endif
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 +181,6 @@ int authenticate_gss_server_init(const c
{
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 +200,7 @@ #endif
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 +211,7 @@ #endif
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 +254,6 @@ int authenticate_gss_server_step(gss_ser
{
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 +274,7 @@ #endif
}
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 +293,7 @@ #endif
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 +308,7 @@ #endif
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 +326,15 @@ end:
return ret;
}
-const char *get_gss_error(char *p, int psize, OM_uint32 err_maj, OM_uint32 err_min, char *prefix)
+
+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 +345,7 @@ const char *get_gss_error(char *p, int p
&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 +356,11 @@ const char *get_gss_error(char *p, int p
&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(KrbException_class, Py_BuildValue("((s:i)(s:i))", buf_maj, err_maj, buf_min, err_min));
}
+
More information about the calendarserver-dev
mailing list