[CalendarServer-changes] [12830] PyKerberos/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Thu Mar 6 10:41:23 PST 2014
Revision: 12830
http://trac.calendarserver.org//changeset/12830
Author: wsanchez at apple.com
Date: 2014-03-06 10:41:23 -0800 (Thu, 06 Mar 2014)
Log Message:
-----------
Add support for delegation of credentials
Fixes: #842
Author: j.warburton at irax.com
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 2014-03-06 04:18:19 UTC (rev 12829)
+++ PyKerberos/trunk/pysrc/kerberos.py 2014-03-06 18:41:23 UTC (rev 12830)
@@ -234,3 +234,20 @@
@return: a string containing the target name.
"""
+def authGSSServerStoreDelegate(context):
+ """
+ Save the ticket sent to the server in the file /tmp/krb5_pyserv_XXXXXX
+ his method must only be called after authGSSServerStep returns a complete or continue response code.
+
+ @param context: the context object returned from authGSSServerInit.
+ @return: a result code (see above).
+ """
+
+def authGSSServerCacheName(context):
+ """
+ Get the name of the credential cache created with authGSSServerStoreDelegate.
+ This method must only be called after authGSSServerStoreDelegate.
+
+ @param context: the context object returned from authGSSServerInit.
+ @return: a string containing the cache name.
+ """
Modified: PyKerberos/trunk/src/kerberos.c
===================================================================
--- PyKerberos/trunk/src/kerberos.c 2014-03-06 04:18:19 UTC (rev 12829)
+++ PyKerberos/trunk/src/kerberos.c 2014-03-06 18:41:23 UTC (rev 12830)
@@ -344,6 +344,31 @@
return Py_BuildValue("i", result);
}
+static PyObject *authGSSServerStoreDelegate(PyObject *self, PyObject *args)
+{
+ gss_server_state *state;
+ PyObject *pystate;
+ int result = 0;
+
+ if (!PyArg_ParseTuple(args, "O", &pystate))
+ return NULL;
+
+ if (!PyCObject_Check(pystate)) {
+ PyErr_SetString(PyExc_TypeError, "Expected a context object");
+ return NULL;
+ }
+
+ state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
+ if (state == NULL)
+ return NULL;
+
+ result = authenticate_gss_server_store_delegate(state);
+ if (result == AUTH_GSS_ERROR)
+ return NULL;
+
+ return Py_BuildValue("i", result);
+}
+
static PyObject *authGSSServerResponse(PyObject *self, PyObject *args)
{
gss_server_state *state;
@@ -384,6 +409,26 @@
return Py_BuildValue("s", state->username);
}
+static PyObject *authGSSServerCacheName(PyObject *self, PyObject *args)
+{
+ gss_server_state *state;
+ PyObject *pystate;
+
+ if (!PyArg_ParseTuple(args, "O", &pystate))
+ return NULL;
+
+ if (!PyCObject_Check(pystate)) {
+ PyErr_SetString(PyExc_TypeError, "Expected a context object");
+ return NULL;
+ }
+
+ state = (gss_server_state *)PyCObject_AsVoidPtr(pystate);
+ if (state == NULL)
+ return NULL;
+
+ return Py_BuildValue("s", state->ccname);
+}
+
static PyObject *authGSSServerTargetName(PyObject *self, PyObject *args)
{
gss_server_state *state;
@@ -433,10 +478,14 @@
"Terminate server-side GSSAPI operations."},
{"authGSSServerStep", authGSSServerStep, METH_VARARGS,
"Do a server-side GSSAPI step."},
+ {"authGSSServerStoreDelegate", authGSSServerStoreDelegate, METH_VARARGS,
+ "Store the delegated Credentials."},
{"authGSSServerResponse", authGSSServerResponse, METH_VARARGS,
"Get the response from the last server-side GSSAPI step."},
{"authGSSServerUserName", authGSSServerUserName, METH_VARARGS,
"Get the user name from the last server-side GSSAPI step."},
+ {"authGSSServerCacheName", authGSSServerCacheName, METH_VARARGS,
+ "Get the location of the cache where delegated credentials are stored."},
{"authGSSServerTargetName", authGSSServerTargetName, METH_VARARGS,
"Get the target name from the last server-side GSSAPI step."},
{NULL, NULL, 0, NULL} /* Sentinel */
Modified: PyKerberos/trunk/src/kerberosgss.c
===================================================================
--- PyKerberos/trunk/src/kerberosgss.c 2014-03-06 04:18:19 UTC (rev 12829)
+++ PyKerberos/trunk/src/kerberosgss.c 2014-03-06 18:41:23 UTC (rev 12830)
@@ -26,6 +26,8 @@
static void set_gss_error(OM_uint32 err_maj, OM_uint32 err_min);
+int create_krb5_ccache(gss_server_state *state, krb5_context kcontext, krb5_principal princ, krb5_ccache *ccache);
+
extern PyObject *GssException_class;
extern PyObject *KrbException_class;
@@ -444,6 +446,7 @@
state->username = NULL;
state->targetname = NULL;
state->response = NULL;
+ state->ccname = NULL;
// Server name may be empty which means we aren't going to create our own creds
size_t service_len = strlen(service);
@@ -509,6 +512,12 @@
free(state->response);
state->response = NULL;
}
+
+ if (state->ccname != NULL)
+ {
+ free(state->ccname);
+ state->ccname = NULL;
+ }
return ret;
}
@@ -652,3 +661,106 @@
PyErr_SetObject(GssException_class, Py_BuildValue("((s:i)(s:i))", buf_maj, err_maj, buf_min, err_min));
}
+
+int
+authenticate_gss_server_store_delegate(gss_server_state *state)
+{
+ gss_cred_id_t delegated_cred = state->client_creds;
+ char *princ_name = state->username;
+ OM_uint32 maj_stat, min_stat;
+ krb5_principal princ = NULL;
+ krb5_ccache ccache = NULL;
+ krb5_error_code problem;
+ krb5_context context;
+ int ret = 500;
+
+ problem = krb5_init_context(&context);
+ if (problem) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s)", "Cannot initialize krb5 context"));
+ return AUTH_GSS_ERROR;
+ }
+
+ problem = krb5_parse_name(context, princ_name, &princ);
+ if (problem) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s:s)", "Cannot parse delegated username", krb5_get_err_text(context, problem)));
+ ret = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ problem = create_krb5_ccache(state, context, princ, &ccache);
+ if (problem) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s:s)", "Error in creating krb5 cache", krb5_get_err_text(context, problem)));
+ ret = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ maj_stat = gss_krb5_copy_ccache(&min_stat, delegated_cred, ccache);
+ if (GSS_ERROR(maj_stat)) {
+ set_gss_error(maj_stat, min_stat);
+ ret = AUTH_GSS_ERROR;
+ goto end;
+ }
+
+ krb5_cc_close(context, ccache);
+ ccache = NULL;
+ ret = 0;
+
+end:
+ if (princ)
+ krb5_free_principal(context, princ);
+ if (ccache)
+ krb5_cc_destroy(context, ccache);
+ krb5_free_context(context);
+ return ret;
+}
+
+int
+create_krb5_ccache(gss_server_state *state,
+ krb5_context kcontext,
+ krb5_principal princ,
+ krb5_ccache *ccache)
+{
+ int fd;
+ char ccname[32];
+ krb5_error_code problem;
+ int ret;
+ krb5_ccache tmp_ccache = NULL;
+
+ snprintf(ccname, sizeof(ccname), "/tmp/krb5cc_pyserv_XXXXXX");
+ fd = mkstemp(ccname);
+ if (fd < 0) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s:s)", "Error in mkstemp", strerror(errno)));
+ ret = 1;
+ goto end;
+ }
+ close(fd);
+
+ problem = krb5_cc_resolve(kcontext, ccname, &tmp_ccache);
+ if (problem) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s:s)", "Error resolving the credential cache", krb5_get_err_text(kcontext, problem)));
+ ret = 1;
+ unlink(ccname);
+ goto end;
+ }
+
+ problem = krb5_cc_initialize(kcontext, tmp_ccache, princ);
+ if (problem) {
+ PyErr_SetObject(KrbException_class, Py_BuildValue("(s:s)", "Error initialising the credential cache", krb5_get_err_text(kcontext, problem)));
+ ret = 1;
+ goto end;
+ }
+
+ *ccache = tmp_ccache;
+ tmp_ccache = NULL;
+
+ ret = 0;
+
+end:
+ if (tmp_ccache)
+ krb5_cc_destroy(kcontext, tmp_ccache);
+
+ state->ccname = (char *)malloc(32*sizeof(char));
+ strcpy(state->ccname, ccname);
+
+ return ret;
+}
Modified: PyKerberos/trunk/src/kerberosgss.h
===================================================================
--- PyKerberos/trunk/src/kerberosgss.h 2014-03-06 04:18:19 UTC (rev 12829)
+++ PyKerberos/trunk/src/kerberosgss.h 2014-03-06 18:41:23 UTC (rev 12830)
@@ -47,6 +47,7 @@
char* username;
char* targetname;
char* response;
+ char* ccname;
} gss_server_state;
char* server_principal_details(const char* service, const char* hostname);
@@ -60,3 +61,4 @@
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);
+int authenticate_gss_server_store_delegate(gss_server_state *state);
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20140306/d88677ab/attachment-0001.html>
More information about the calendarserver-changes
mailing list