[CalendarServer-changes] [2454] PyKerberos/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Fri May 23 09:40:39 PDT 2008
Revision: 2454
http://trac.macosforge.org/projects/calendarserver/changeset/2454
Author: wsanchez at apple.com
Date: 2008-05-23 09:40:38 -0700 (Fri, 23 May 2008)
Log Message:
-----------
Add wrap/unwrap support, via agx at sigxcpu.
Modified Paths:
--------------
PyKerberos/trunk/pysrc/kerberos.py
PyKerberos/trunk/src/kerberos.c
PyKerberos/trunk/src/kerberosgss.c
PyKerberos/trunk/src/kerberosgss.h
Modified: PyKerberos/trunk/pysrc/kerberos.py
===================================================================
--- PyKerberos/trunk/pysrc/kerberos.py 2008-05-23 16:39:49 UTC (rev 2453)
+++ PyKerberos/trunk/pysrc/kerberos.py 2008-05-23 16:40:38 UTC (rev 2454)
@@ -139,6 +139,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/trunk/src/kerberos.c
===================================================================
--- PyKerberos/trunk/src/kerberos.c 2008-05-23 16:39:49 UTC (rev 2453)
+++ PyKerberos/trunk/src/kerberos.c 2008-05-23 16:40:38 UTC (rev 2454)
@@ -84,7 +84,7 @@
return NULL;
}
-static PyObject *authGSSClientInit(PyObject *self, PyObject *args)
+static PyObject* authGSSClientInit(PyObject* self, PyObject* args)
{
const char *service;
gss_client_state *state;
@@ -176,6 +176,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;
@@ -287,6 +329,10 @@
"Get the user name from the last client-side GSSAPI step."},
{"authGSSServerInit", authGSSServerInit, METH_VARARGS,
"Initialize server-side GSSAPI operations."},
+ {"authGSSClientWrap", authGSSClientWrap, METH_VARARGS,
+ "Do a GSSAPI wrap."},
+ {"authGSSClientUnwrap", authGSSClientUnwrap, METH_VARARGS,
+ "Do a GSSAPI unwrap."},
{"authGSSServerClean", authGSSServerClean, METH_VARARGS,
"Terminate server-side GSSAPI operations."},
{"authGSSServerStep", authGSSServerStep, METH_VARARGS,
@@ -329,7 +375,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/trunk/src/kerberosgss.c
===================================================================
--- PyKerberos/trunk/src/kerberosgss.c 2008-05-23 16:39:49 UTC (rev 2453)
+++ PyKerberos/trunk/src/kerberosgss.c 2008-05-23 16:40:38 UTC (rev 2454)
@@ -24,6 +24,7 @@
#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);
@@ -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,8 +255,137 @@
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);
+#ifdef PRINTFS
+ printf("User: %s, %c%c%c\n", user,
+ server_conf_flags & GSS_AUTH_P_NONE ? 'N' : '-',
+ server_conf_flags & GSS_AUTH_P_INTEGRITY ? 'I' : '-',
+ server_conf_flags & GSS_AUTH_P_PRIVACY ? '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;
Modified: PyKerberos/trunk/src/kerberosgss.h
===================================================================
--- PyKerberos/trunk/src/kerberosgss.h 2008-05-23 16:39:49 UTC (rev 2453)
+++ PyKerberos/trunk/src/kerberosgss.h 2008-05-23 16:40:38 UTC (rev 2454)
@@ -26,6 +26,10 @@
#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;
@@ -45,10 +49,12 @@
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/20080523/77e62623/attachment-0001.htm
More information about the calendarserver-changes
mailing list