예제 #1
0
OM_uint32
ntlm_gss_inquire_cred(
			OM_uint32 *minor_status,
			gss_cred_id_t cred_handle,
			gss_name_t *name,
			OM_uint32 *lifetime,
			int *cred_usage,
			gss_OID_set *mechanisms)
{
	OM_uint32 status = 0;
        ntlm_gss_cred_id_t ntlm_cred_handle = NULL;
        gss_name_t ret_name = NULL;

	dsyslog("Entering inquire_cred\n");

        ntlm_cred_handle = (ntlm_gss_cred_id_t) cred_handle;
        if (ntlm_cred_handle && ntlm_cred_handle->name && name)
        {
            status = gss_duplicate_name(
                         minor_status,
                         ntlm_cred_handle->name,
                         &ret_name);
            if (status == 0)
            {
                *name = ret_name;
            }
        }

	dsyslog("Leaving inquire_cred\n");

	return (status);
}
예제 #2
0
bool_t Svcauth_gss_set_svc_name(gss_name_t name)
{
  OM_uint32 maj_stat, min_stat;

  if(svcauth_gss_name != NULL)
    {
      maj_stat = gss_release_name(&min_stat, &svcauth_gss_name);

      if(maj_stat != GSS_S_COMPLETE)
        {
          return (FALSE);
        }
      svcauth_gss_name = NULL;
    }
  if(svcauth_gss_name == GSS_C_NO_NAME)
    return (TRUE);

  maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name);

  if(maj_stat != GSS_S_COMPLETE)
    {
      return (FALSE);
    }

  return (TRUE);
}
예제 #3
0
bool_t
svcauth_gss_set_svc_name(gss_name_t name)
{
	OM_uint32	maj_stat, min_stat;

	log_debug("in svcauth_gss_set_svc_name()");

	if (_svcauth_gss_name != NULL) {
		maj_stat = gss_release_name(&min_stat, &_svcauth_gss_name);

		if (maj_stat != GSS_S_COMPLETE) {
			log_status("gss_release_name", maj_stat, min_stat);
			return (FALSE);
		}
		_svcauth_gss_name = NULL;
	}
	maj_stat = gss_duplicate_name(&min_stat, name, &_svcauth_gss_name);

	if (maj_stat != GSS_S_COMPLETE) {
		log_status("gss_duplicate_name", maj_stat, min_stat);
		return (FALSE);
	}

	return (TRUE);
}
예제 #4
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_duplicate_name (
            OM_uint32 * minor_status,
            gss_const_name_t src_name,
            gss_name_t * dest_name
           )
{
    return gss_duplicate_name(minor_status, src_name, dest_name);
}
예제 #5
0
OM_uint32 _gss_spnego_duplicate_name (
            OM_uint32 * minor_status,
            const gss_name_t src_name,
            gss_name_t * dest_name
           )
{
    return gss_duplicate_name(minor_status, src_name, dest_name);
}
예제 #6
0
파일: sncgss.c 프로젝트: Aribaaa/osxsnc
uint32_t
sapgss_duplicate_name(
    uint32_t *minor_status,
    gss_name_t input_name,
    gss_name_t *dest_name)
{
    return gss_duplicate_name(minor_status, input_name, dest_name);
}
예제 #7
0
AUTH *
authgss_create(CLIENT *clnt, gss_name_t name, struct rpc_gss_sec *sec)
{
	AUTH			*auth, *save_auth;
	struct rpc_gss_data	*gd;
	OM_uint32		min_stat = 0;

	log_debug("in authgss_create()");
	
	memset(&rpc_createerr, 0, sizeof(rpc_createerr));
	
	if ((auth = calloc(sizeof(*auth), 1)) == NULL) {
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = ENOMEM;
		return (NULL);
	}
	if ((gd = calloc(sizeof(*gd), 1)) == NULL) {
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = ENOMEM;
		free(auth);
		return (NULL);
	}
	if (name != GSS_C_NO_NAME) {
		if (gss_duplicate_name(&min_stat, name, &gd->name)
						!= GSS_S_COMPLETE) {
			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
			rpc_createerr.cf_error.re_errno = ENOMEM;
			free(auth);
			free(gd);
			return (NULL);
		}
	}
	else
		gd->name = name;

	gd->clnt = clnt;
	gd->ctx = GSS_C_NO_CONTEXT;
	gd->sec = *sec;

	gd->gc.gc_v = RPCSEC_GSS_VERSION;
	gd->gc.gc_proc = RPCSEC_GSS_INIT;
	gd->gc.gc_svc = gd->sec.svc;
	
	auth->ah_ops = &authgss_ops;
	auth->ah_private = (caddr_t)gd;
	
	save_auth = clnt->cl_auth;
	clnt->cl_auth = auth;

	if (!authgss_refresh(auth, NULL))
		auth = NULL;
	
	clnt->cl_auth = save_auth;
	
	log_debug("authgss_create returning auth 0x%08x", auth);
	return (auth);
}
예제 #8
0
OM_uint32 _gss_ntlm_canonicalize_name (
    OM_uint32 * minor_status,
    const gss_name_t input_name,
    const gss_OID mech_type,
    gss_name_t * output_name
)
{
    return gss_duplicate_name (minor_status, input_name, output_name);
}
예제 #9
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_canonicalize_name (
            OM_uint32 * minor_status,
            gss_const_name_t input_name,
            const gss_OID mech_type,
            gss_name_t * output_name
           )
{
    /* XXX */
    return gss_duplicate_name(minor_status, input_name, output_name);
}
예제 #10
0
OM_uint32 krb5_gss_canonicalize_name(OM_uint32  *minor_status,
                                     const gss_name_t input_name,
                                     const gss_OID mech_type,
                                     gss_name_t *output_name)
{
    if ((mech_type != GSS_C_NULL_OID) &&
        !g_OID_equal(gss_mech_krb5, mech_type) &&
        !g_OID_equal(gss_mech_krb5_old, mech_type)) {
        *minor_status = 0;
        return(GSS_S_BAD_MECH);
    }

    return(gss_duplicate_name(minor_status, input_name, output_name));
}
예제 #11
0
파일: gsi.c 프로젝트: ddk50/gfarm_v2
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <ctype.h>
#include <pwd.h>

#include <gfarm/gflog.h>
#include <gfarm/error.h>

#include "gssapi.h"

#include "gfevent.h"
#include "gfutil.h"
#include "thrsubr.h"

#include "tcputil.h"

#include "gfsl_config.h"
#include "gfarm_gsi.h"
#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
#include "gfarm_auth.h"
#endif

static pthread_mutex_t gss_mutex = PTHREAD_MUTEX_INITIALIZER;
static const char gssDiag[] = "gss_mutex";

static char **gssCrackStatus(OM_uint32 statValue, int statType);

static int gssInitiateSecurityContextSwitch(struct gfarmGssInitiateSecurityContextState *state);
static int gssInitiateSecurityContextNext(struct gfarmGssInitiateSecurityContextState *state);
static void gfarmGssInitiateSecurityContextSendToken(int events,
						     int fd,
						     void *closure,
						     const struct timeval *t);
static void gfarmGssInitiateSecurityContextReceiveToken(int events,
							int fd,
							void *closure,
							const struct timeval *t);



static char **
gssCrackStatus(OM_uint32 statValue, int statType)
{
    OM_uint32 msgCtx;
    OM_uint32 minStat;
    gss_buffer_desc stStr;
    char **ret, **ret_new;
    int i = 0;
    char *dP;

    GFARM_MALLOC_ARRAY(ret, 1);
    if (ret == NULL) {
	gflog_error(GFARM_MSG_1003406, "gssCrackStatus: no memory");
	return (ret);
    }
    ret[0] = NULL;
    while (1) {
	msgCtx = 0;
	gss_display_status(&minStat,
				 statValue,
				 statType,
				 GSS_C_NO_OID,
				 &msgCtx,
				 &stStr);
	GFARM_REALLOC_ARRAY(ret_new, ret, i + 2);
	if (ret_new == NULL) {
	    gflog_error(GFARM_MSG_1003407, "gssCrackStatus: no memory");
	    goto free_ret;
	}
	ret = ret_new;
	GFARM_MALLOC_ARRAY(ret[i], stStr.length + 1);
	if (ret[i] == NULL) {
	    gflog_error(GFARM_MSG_1003408, "gssCrackStatus: no memory");
	    goto free_ret;
	}
	dP = ret[i];
	dP[stStr.length] = '\0';
	i++;
	memcpy(dP, stStr.value, stStr.length);
	gss_release_buffer(&minStat, &stStr);
	if (msgCtx == 0) {
	    break;
	}
    }
    ret[i] = NULL;

    return (ret);

 free_ret:
    for (--i; i >= 0; --i)
	free(ret[i]);
    free(ret);
    return (ret);
}


void
gfarmGssFreeCrackedStatus(char **strPtr)
{
    char **cpS = strPtr;

    while (*cpS != NULL)
	free(*cpS++);
    free(strPtr);
}


char **
gfarmGssCrackMajorStatus(OM_uint32 majStat)
{
    return gssCrackStatus(majStat, GSS_C_GSS_CODE);
}


char **
gfarmGssCrackMinorStatus(OM_uint32 minStat)
{
    return gssCrackStatus(minStat, GSS_C_MECH_CODE);
}


static void
gfarmGssPrintStatus(char **list, const char *diag)
{
    char **lP = list;

    if (lP != NULL && *lP != NULL) {
	while (*lP != NULL) {
	    gflog_info(GFARM_MSG_1000607, "\t : %s", *lP++);
	}
    } else
	gflog_info(GFARM_MSG_1000608, "GSS %s Status Error: UNKNOWN", diag);
    gfarmGssFreeCrackedStatus(list);
}

void
gfarmGssPrintMajorStatus(OM_uint32 majStat)
{
    gfarmGssPrintStatus(gfarmGssCrackMajorStatus(majStat), "Major");
}


void
gfarmGssPrintMinorStatus(OM_uint32 minStat)
{
    gfarmGssPrintStatus(gfarmGssCrackMinorStatus(minStat), "Minor");
}

int
gfarmGssImportName(gss_name_t *namePtr, void *nameValue, size_t nameLength,
    gss_OID nameType, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat = 0;
    OM_uint32 minStat = 0;
    int ret = -1;
    gss_buffer_desc buf;

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    if (nameType == GSS_C_NT_USER_NAME) {
	char *user;
	gfarmAuthEntry *aePtr;

	GFARM_MALLOC_ARRAY(user, nameLength + 1);
	if (user == NULL) {
	    gflog_auth_error(GFARM_MSG_1000611,
		"gfarmGssImportName(): no memory");
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	memcpy(user, nameValue, nameLength);
	user[nameLength] = '\0';
	aePtr = gfarmAuthGetLocalUserEntry(user);
	if (aePtr == NULL) {
	    gflog_auth_error(GFARM_MSG_1000612, "%s: ERROR: cannot convert "
			     "this user name to X.509 Distinguish name", user);
	    free(user);
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	free(user);
	assert(aePtr->authType == GFARM_AUTH_USER);
	nameValue = aePtr->distName;
	nameLength = strlen(aePtr->distName);
	nameType = GSS_C_NO_OID; /* mechanism specific */
    }
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    buf.length = nameLength;
    buf.value = nameValue;
    majStat = gss_import_name(&minStat, &buf, nameType, namePtr);
    if (majStat == GSS_S_COMPLETE) {
	ret = 1; /* OK */
    }

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    Done:
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}


int
gfarmGssImportNameOfHostBasedService(gss_name_t *namePtr, char *service,
    char *hostname, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;
    int ret = -1;
    size_t nameLength = strlen(service) + 1 + strlen(hostname);
    char *nameString;

    GFARM_MALLOC_ARRAY(nameString, nameLength + 1);
    if (nameString == NULL) {
	gflog_auth_error(GFARM_MSG_1000613,
	    "gfarmGssImportNameOfHostBasedService(): "
			 "no memory");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else {
	sprintf(nameString, "%s@%s", service, hostname);
	if (gfarmGssImportName(namePtr, nameString, nameLength,
			       GSS_C_NT_HOSTBASED_SERVICE,
			       &majStat, &minStat) > 0) {
	    ret = 1;
	}
	free(nameString);
    }
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}


int
gfarmGssImportNameOfHost(gss_name_t *namePtr, char *hostname,
    OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    return gfarmGssImportNameOfHostBasedService(namePtr, "host", hostname,
						majStatPtr, minStatPtr);
}


int
gfarmGssDeleteName(gss_name_t *namePtr, OM_uint32 *majStatPtr,
    OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;

    majStat = gss_release_name(&minStat, namePtr);

    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return majStat == GSS_S_COMPLETE ? 1 : -1;
}


#if 0 /* gss_duplicate_name() is not implemented at least in globus-2 yet. */
int
gfarmGssDuplicateName(gss_name_t *outputNamePtr, const gss_name_t inputName,
    OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;

    majStat = gss_duplicate_name(&minStat, inputName, outputNamePtr);

    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return majStat == GSS_S_COMPLETE ? 1 : -1;
}
예제 #12
0
파일: GSSName.cpp 프로젝트: janetuk/gssweb
GSSName::GSSName ( const GSSName& n )
{
  this->hashKey = n.hashKey;
  if (GSS_C_NO_NAME == n.name)
  {
    major_status = 0;
    minor_status = 0;
    name = GSS_C_NO_NAME;
  }
  else
  {
    this->major_status = gss_duplicate_name(&minor_status, n.name, &name);
    if ( GSS_ERROR(major_status) )
    {
      throw GSSException("Cannot copy a GSS name.", major_status, minor_status);
    }
  }
  this->skipRelease = false;
}
예제 #13
0
bool
svcauth_gss_set_svc_name(gss_name_t name)
{
	OM_uint32 maj_stat, min_stat;

	if (svcauth_gss_name != NULL) {
		maj_stat = gss_release_name(&min_stat, &svcauth_gss_name);
		if (maj_stat != GSS_S_COMPLETE)
			return (false);
		svcauth_gss_name = NULL;
	}

	/* XXX Ganesha */
	if (svcauth_gss_name == GSS_C_NO_NAME)
		return (true);

	maj_stat = gss_duplicate_name(&min_stat, name, &svcauth_gss_name);
	if (maj_stat != GSS_S_COMPLETE)
		return (false);

	return (true);
}
예제 #14
0
파일: GSSName.cpp 프로젝트: janetuk/gssweb
GSSName& GSSName::operator= ( const GSSName& rhs )
{
  if (rhs.toGss() != this->toGss())
  {
    this->function = rhs.function;
    if (GSS_C_NO_NAME == rhs.name)
    {
      major_status = 0;
      minor_status = 0;
      name = GSS_C_NO_NAME;
    }
    else
    {
      this->major_status = gss_duplicate_name(&minor_status, rhs.name, &name);
      if ( GSS_ERROR(major_status) )
      {
	throw GSSException("Cannot copy a GSS name.", major_status, minor_status);
      }
    }
    this->hashKey = "";
    this->skipRelease = rhs.skipRelease;
  }
  return *this;
}
예제 #15
0
OM_uint32 gss_acquire_cred
           (OM_uint32 * minor_status,
            const gss_name_t desired_name,
            OM_uint32 time_req,
            const gss_OID_set desired_mechs,
            gss_cred_usage_t cred_usage,
            gss_cred_id_t * output_cred_handle,
            gss_OID_set * actual_mechs,
            OM_uint32 * time_rec
           )
{
    gss_cred_id_t handle;
    OM_uint32 ret;

    if (cred_usage != GSS_C_ACCEPT && cred_usage != GSS_C_INITIATE && cred_usage != GSS_C_BOTH) {
	*minor_status = GSS_KRB5_S_G_BAD_USAGE;
	return GSS_S_FAILURE;
    }

    GSSAPI_KRB5_INIT ();

    *output_cred_handle = NULL;
    if (time_rec)
	*time_rec = 0;
    if (actual_mechs)
	*actual_mechs = GSS_C_NO_OID_SET;

    if (desired_mechs) {
	int present = 0;

	ret = gss_test_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
				      desired_mechs, &present); 
	if (ret)
	    return ret;
	if (!present) {
	    *minor_status = 0;
	    return GSS_S_BAD_MECH;
	}
    }

    handle = (gss_cred_id_t)malloc(sizeof(*handle));
    if (handle == GSS_C_NO_CREDENTIAL) {
	*minor_status = ENOMEM;
        return (GSS_S_FAILURE);
    }

    memset(handle, 0, sizeof (*handle));
    HEIMDAL_MUTEX_init(&handle->cred_id_mutex);

    if (desired_name != GSS_C_NO_NAME) {
	ret = gss_duplicate_name(minor_status, desired_name,
	    &handle->principal);
	if (ret != GSS_S_COMPLETE) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    free(handle);
	    return (ret);
	}
    }
    if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
	ret = acquire_initiator_cred(minor_status, desired_name, time_req,
	    desired_mechs, cred_usage, handle, actual_mechs, time_rec);
    	if (ret != GSS_S_COMPLETE) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    krb5_free_principal(gssapi_krb5_context, handle->principal);
	    free(handle);
	    return (ret);
	}
    }
    if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
	ret = acquire_acceptor_cred(minor_status, desired_name, time_req,
	    desired_mechs, cred_usage, handle, actual_mechs, time_rec);
	if (ret != GSS_S_COMPLETE) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    krb5_free_principal(gssapi_krb5_context, handle->principal);
	    free(handle);
	    return (ret);
	}
    }
    ret = gss_create_empty_oid_set(minor_status, &handle->mechanisms);
    if (ret == GSS_S_COMPLETE)
    	ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM,
				 &handle->mechanisms);
    if (ret == GSS_S_COMPLETE)
    	ret = gss_inquire_cred(minor_status, handle, NULL, time_rec, NULL,
			   actual_mechs);
    if (ret != GSS_S_COMPLETE) {
	if (handle->mechanisms != NULL)
	    gss_release_oid_set(NULL, &handle->mechanisms);
	HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	krb5_free_principal(gssapi_krb5_context, handle->principal);
	free(handle);
	return (ret);
    } 
    *minor_status = 0;
    if (time_rec) {
	ret = gssapi_lifetime_left(minor_status,
				   handle->lifetime,
				   time_rec);

	if (ret)
	    return ret;
    }
    handle->usage = cred_usage;
    *output_cred_handle = handle;
    return (GSS_S_COMPLETE);
}
예제 #16
0
OM_uint32
srp_gss_accept_sec_context(
                OM_uint32 *minor_status,
                gss_ctx_id_t *context_handle,
                gss_cred_id_t verifier_cred_handle,
                gss_buffer_t input_token,
                gss_channel_bindings_t input_chan_bindings,
                gss_name_t *src_name,
                gss_OID *mech_type,
                gss_buffer_t output_token,
                OM_uint32 *ret_flags,
                OM_uint32 *time_rec,
                gss_cred_id_t *delegated_cred_handle)
{
    int oid_len = 0;
    int state = 0;
    srp_gss_cred_id_t srp_cred = NULL;
    unsigned char *ptr = NULL;
    int ptr_len = 0;
    OM_uint32 maj = 0;
    OM_uint32 min = 0;
    OM_uint32 tmp_maj = 0;
    OM_uint32 tmp_min = 0;
    gss_buffer_desc input_token_srp = {0};
    srp_gss_ctx_id_t srp_context_handle = NULL;
    krb5_error_code krb5_err = 0;
    gss_cred_id_t srp_cred_handle = NULL;

    if (minor_status == NULL ||
        output_token == GSS_C_NO_BUFFER ||
        context_handle == NULL)
    {
        return GSS_S_CALL_INACCESSIBLE_WRITE;
    }

    if (input_token == GSS_C_NO_BUFFER)
    {
        return GSS_S_CALL_INACCESSIBLE_READ;
    }

    if (minor_status)
    {
        *minor_status = 0;
    }

    if (output_token != GSS_C_NO_BUFFER)
    {
        output_token->length = 0;
        output_token->value = NULL;
    }

    if (!context_handle)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    if (*context_handle)
    {
        srp_context_handle = (srp_gss_ctx_id_t) *context_handle;
    }
    else
    {
        /* First call, allocate context handle */
        srp_context_handle =
            (srp_gss_ctx_id_t) calloc(1, sizeof(srp_gss_ctx_id_rec));
        if (!srp_context_handle)
        {
            min = ENOMEM;
            maj = GSS_S_FAILURE;
            goto error;
        }
        memset(srp_context_handle, 0, sizeof(srp_gss_ctx_id_rec));

        /* Needed for Kerberos AES256-SHA1 keyblock generation */
        krb5_err = krb5_init_context(&srp_context_handle->krb5_ctx);
        if (krb5_err)
        {
            maj = GSS_S_FAILURE;
            min = krb5_err;
            goto error;
        }
        maj = srp_gss_acquire_cred(
                  &min,
                  GSS_C_NO_NAME,
                  0,
                  NULL,
                  GSS_C_ACCEPT,
                  &srp_cred_handle,
                  NULL,
                  NULL);
        if (maj)
        {
            goto error;
        }
        srp_cred = (srp_gss_cred_id_t) srp_cred_handle;
        srp_context_handle->magic_num = SRP_MAGIC_ID;

        maj = srp_gss_duplicate_oid(&min,
                                    srp_cred->srp_mech_oid,
                                    &srp_context_handle->mech);
        if (maj)
        {
            goto error;
        }

        srp_context_handle->state = SRP_AUTH_INIT;
        srp_context_handle->cred = (srp_gss_cred_id_t) verifier_cred_handle;
        *context_handle = (gss_ctx_id_t) srp_context_handle;
    }

    ptr = (unsigned char*) input_token->value;
    ptr_len = (int) input_token->length;
    maj = srp_gss_validate_oid_header(
              &min,
              input_token,
              &oid_len);
    if (maj)
    {
        goto error;
    }

    ptr += oid_len;
    ptr_len -= oid_len;
    input_token_srp.value = ptr;
    input_token_srp.length = ptr_len;

    /* This is the "t" field of ber_scanf() */
    state = SRP_AUTH_STATE_VALUE(ptr[0]);

    /* Verify state machine is consistent with expected state */
    state = SRP_AUTH_STATE_VALUE(ptr[0]);

    if (state != srp_context_handle->state)
    {
        maj = GSS_S_FAILURE;
        goto error;
    }

    switch(state)
    {
      case SRP_AUTH_INIT:
        srp_debug_printf("srp_gss_accept_sec_context: state=SRP_AUTH_INIT\n");
        maj = _srp_gss_auth_init(minor_status,
                                 srp_context_handle,
                                 state,
                                 &input_token_srp,
                                 output_token);
        if (maj)
        {
            if (maj == GSS_S_CONTINUE_NEEDED)
            {
                srp_context_handle->state = SRP_AUTH_CLIENT_VALIDATE;
            }
            goto error;
        }
        break;

      case SRP_AUTH_CLIENT_VALIDATE:
        srp_debug_printf("srp_gss_accept_sec_context: "
                         "state=SRP_AUTH_CLIENT_VALIDATE\n");
        maj = _srp_gss_validate_client(minor_status,
                                       srp_context_handle,
                                       state,
                                       &input_token_srp,
                                       output_token);
        if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE)
        {
            /* Hard error occurred */
            goto error;
        }

        srp_context_handle->state = SRP_AUTH_COMPLETE;
        if (mech_type)
        {
            /* The security mechanism with which the context was established.
             * If the security mechanism type is not required, specify NULL
             * for this parameter. The gss_OID value returned for this
             * parameter points to a read-only structure and must not be
             * released by the application.
             */
            *mech_type = srp_context_handle->mech;
        }

        if (src_name)
        {
            /* Optional: Return UPN name to caller */
            tmp_maj = gss_duplicate_name(
                      &tmp_min,
                      srp_context_handle->gss_upn_name,
                      src_name);
            if (tmp_maj)
            {
                maj = tmp_maj;
                *minor_status = tmp_min;
                goto error;
            }
        }
        break;

      /* This should never happen, but include for completeness-sake */
      case SRP_AUTH_COMPLETE:
        srp_debug_printf("srp_gss_accept_sec_context: "
                         "state=SRP_AUTH_COMPLETE\n");
        maj = GSS_S_COMPLETE;
        break;

      default:
        srp_debug_printf("srp_gss_accept_sec_context: state=UNKNOWN!!!\n");
        maj = GSS_S_FAILURE;
        goto error;
        break;
    }

    if (srp_context_handle->state == SRP_AUTH_COMPLETE)
    {
        PVMDIR_SERVER_CONTEXT hServer = srp_context_handle->hServer;

#ifdef SRP_FIPS_ENABLED
        krb5_err = srp_make_enc_keyblock_FIPS(srp_context_handle);
#else
        krb5_err = srp_make_enc_keyblock(srp_context_handle);
#endif
        if (krb5_err)
        {
            maj = GSS_S_FAILURE;
            min = krb5_err;
            goto error;
        }

        if (srp_context_handle->bUseCSRP)
        {
            srp_verifier_delete(srp_context_handle->srp_ver);
        }
        else
        {
            /* Clean up SRP server-side memory, then close the server context */
            cli_rpc_srp_verifier_delete(
                hServer->hBinding,
                (void **) &srp_context_handle->srp_ver);
    
            VmDirCloseServer(hServer);
            srp_context_handle->hServer = NULL;
        }
    }

error:
    if (maj != GSS_S_CONTINUE_NEEDED && maj != GSS_S_COMPLETE)
    {
        _srp_gss_accept_sec_ctx_error_resp(
            minor_status,
            output_token);
    }

    if (srp_cred_handle)
    {
        srp_gss_release_cred(&tmp_min, &srp_cred_handle);
    }
    return maj;
}
예제 #17
0
OM_uint32
srp_gss_acquire_cred(
    OM_uint32 *minor_status,
    gss_name_t desired_name,
    OM_uint32 time_req,
    gss_OID_set desired_mechs,
    gss_cred_usage_t cred_usage,
    gss_cred_id_t *output_cred_handle,
    gss_OID_set *actual_mechs,
    OM_uint32 *time_rec)
{
    OM_uint32 major = 0;
    OM_uint32 minor = 0;
    srp_gss_cred_id_t srp_cred = NULL;
    gss_name_t username_buf = NULL;

    /* Official "UNIX OID" */
    int gssapi_srp_mech_oid_len = GSSAPI_UNIX_MECH_OID_LEN_ST;
    unsigned char *srp_mech_oid = GSSAPI_UNIX_MECH_OID_ST;

    /* Allocate the cred structure */
    srp_cred = (srp_gss_cred_id_t) gssalloc_malloc(sizeof(*srp_cred));
    if (!srp_cred)
    {
        minor = ENOMEM;
        major = GSS_S_FAILURE;
        goto error;
    }
    memset(srp_cred, 0, sizeof(*srp_cred));

    /* Allocate/set the mech OID; must be SRP for this method to be called */
    srp_cred->srp_mech_oid =
        (gss_OID) gssalloc_malloc(sizeof(*srp_cred->srp_mech_oid));
    if (!srp_cred->srp_mech_oid)
    {
        minor = ENOMEM;
        major = GSS_S_FAILURE;
        goto error;
    }
    memset(srp_cred->srp_mech_oid, 0, sizeof(*srp_cred->srp_mech_oid));
    srp_cred->srp_mech_oid->elements =
        (void *) gssalloc_malloc(gssapi_srp_mech_oid_len);
    if (!srp_cred->srp_mech_oid->elements)
    {
        minor = ENOMEM;
        major = GSS_S_FAILURE;
        goto error;
    }

    srp_cred->srp_mech_oid->length = gssapi_srp_mech_oid_len;
    memcpy(srp_cred->srp_mech_oid->elements,
           srp_mech_oid,
           gssapi_srp_mech_oid_len);

    if (desired_name)
    {
        major = gss_duplicate_name(&minor, desired_name, &username_buf);
        if (major)
        {
            goto error;
        }

        srp_cred->name = username_buf, username_buf = NULL;
    }
    *output_cred_handle = (gss_cred_id_t) srp_cred;

error:
    if (major || minor)
    {
        *minor_status = minor;
        if (srp_cred)
        {
            if (srp_cred->srp_mech_oid)
            {
                if (srp_cred->srp_mech_oid->elements)
                {
                    gssalloc_free(srp_cred->srp_mech_oid->elements);
                }
                gssalloc_free(srp_cred->srp_mech_oid);
            }
            gssalloc_free(srp_cred);
        }
    }

    return major;
}