[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