Skip to content
This repository has been archived by the owner on Feb 24, 2024. It is now read-only.

Commit

Permalink
New method to allow the server to determine its own service principal…
Browse files Browse the repository at this point in the history
… from service type and hostname.

git-svn-id: https://svn.calendarserver.org/repository/calendarserver/PyKerberos/trunk@1417 e27351fd-9f3e-4f54-a53b-843176b1656c
  • Loading branch information
cyrusdaboo committed Mar 23, 2007
1 parent 7fbfbdd commit fed13f6
Show file tree
Hide file tree
Showing 9 changed files with 2,084 additions and 7 deletions.
10 changes: 10 additions & 0 deletions pysrc/kerberos.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ def checkPassword(user, pswd, service, default_realm):
@return: True if authentication succeeds, False otherwise.
"""

def getServerPrincipalDetails(service, hostname):
"""
This function returns the service principal for the server given a service type
and hostname. Details are looked up via the /etc/keytab file.
@param service: a string containing the Kerberos service type for the server.
@param hostname: a string containing the hostname of the server.
@return: a string containing the service principal.
"""

"""
GSSAPI Function Result Codes:
Expand Down
25 changes: 24 additions & 1 deletion src/kerberos.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* DRI: Cyrus Daboo, [email protected]
**/

#include <Python.h>
#include <Python/Python.h>

#include "kerberosbasic.h"
#include "kerberosgss.h"
Expand Down Expand Up @@ -44,6 +44,27 @@ static PyObject *checkPassword(PyObject *self, PyObject *args)
return NULL;
}

static PyObject *getServerPrincipalDetails(PyObject *self, PyObject *args)
{
const char *service;
const char *hostname;
char* result;

if (!PyArg_ParseTuple(args, "ss", &service, &hostname))
return NULL;

result = server_principal_details(service, hostname);

if (result != NULL)
{
PyObject* pyresult = Py_BuildValue("s", result);
free(result);
return pyresult;
}
else
return NULL;
}

static PyObject *authGSSClientInit(PyObject *self, PyObject *args)
{
const char *service;
Expand Down Expand Up @@ -231,6 +252,8 @@ static PyObject *authGSSServerUserName(PyObject *self, PyObject *args)
static PyMethodDef KerberosMethods[] = {
{"checkPassword", checkPassword, METH_VARARGS,
"Check the supplied user/password against Kerberos KDC."},
{"getServerPrincipalDetails", getServerPrincipalDetails, METH_VARARGS,
"Return the service principal for a given service and hostname."},
{"authGSSClientInit", authGSSClientInit, METH_VARARGS,
"Initialize client-side GSSAPI operations."},
{"authGSSClientClean", authGSSClientClean, METH_VARARGS,
Expand Down
72 changes: 71 additions & 1 deletion src/kerberosgss.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* DRI: Cyrus Daboo, [email protected]
**/

#include <Python.h>
#include <Python/Python.h>
#include "kerberosgss.h"

#include "base64.h"
Expand All @@ -30,6 +30,76 @@ 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 match[1024];
int match_len = 0;
char* result = NULL;

int code;
krb5_context kcontext;
krb5_keytab kt = NULL;
krb5_kt_cursor cursor = NULL;
krb5_keytab_entry entry;
char* pname = NULL;

// Generate the principal prefix we want to match
snprintf(match, 1024, "%s/%s@", service, hostname);
match_len = strlen(match);

code = krb5_init_context(&kcontext);
if (code)
{
PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
"Cannot initialize Kerberos5 context", code));
return NULL;
}

if ((code = krb5_kt_default(kcontext, &kt)))
{
PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
"Cannot get default keytab", code));
goto end;
}

if ((code = krb5_kt_start_seq_get(kcontext, kt, &cursor)))
{
PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
"Cannot get sequence cursor from keytab", code));
goto end;
}

while ((code = krb5_kt_next_entry(kcontext, kt, &entry, &cursor)) == 0)
{
if ((code = krb5_unparse_name(kcontext, entry.principal, &pname)))
{
PyErr_SetObject(KrbException_class, Py_BuildValue("((s:i))",
"Cannot parse principal name from keytab", code));
goto end;
}

if (strncmp(pname, match, match_len) == 0)
{
result = malloc(strlen(pname) + 1);
strcpy(result, pname);
krb5_free_unparsed_name(kcontext, pname);
break;
}

krb5_free_unparsed_name(kcontext, pname);
krb5_free_keytab_entry_contents(kcontext, &entry);
}

end:
if (cursor)
krb5_kt_end_seq_get(kcontext, kt, &cursor);
if (kt)
krb5_kt_close(kcontext, kt);
krb5_free_context(kcontext);

return result;
}

int authenticate_gss_client_init(const char* service, gss_client_state *state)
{
OM_uint32 maj_stat;
Expand Down
2 changes: 2 additions & 0 deletions src/kerberosgss.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ typedef struct {
char* response;
} gss_server_state;

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_clean(gss_client_state *state);
int authenticate_gss_client_step(gss_client_state *state, const char *challenge);
Expand Down
Loading

0 comments on commit fed13f6

Please sign in to comment.