Esempio n. 1
0
OM_uint32 gss_indicate_mechs
           (OM_uint32 * minor_status,
            gss_OID_set * mech_set
           )
{
  OM_uint32 ret;

  ret = gss_create_empty_oid_set(minor_status, mech_set);
  if (ret)
      return ret;

  ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set);
  if (ret) {
      gss_release_oid_set(NULL, mech_set);
      return ret;
  }

  ret = gss_add_oid_set_member(minor_status, GSS_SPNEGO_MECHANISM, mech_set);
  if (ret) {
      gss_release_oid_set(NULL, mech_set);
      return ret;
  }

  *minor_status = 0;
  return GSS_S_COMPLETE;
}
Esempio n. 2
0
static OM_uint32
spnego_supported_mechs(OM_uint32 *minor_status, gss_OID_set *mechs)
{
    OM_uint32 ret, junk;
    gss_OID_set m;
    size_t i;

    ret = gss_indicate_mechs(minor_status, &m);
    if (ret != GSS_S_COMPLETE)
	return ret;

    ret = gss_create_empty_oid_set(minor_status, mechs);
    if (ret != GSS_S_COMPLETE) {
	gss_release_oid_set(&junk, &m);
	return ret;
    }

    for (i = 0; i < m->count; i++) {
	if (gss_oid_equal(&m->elements[i], GSS_SPNEGO_MECHANISM))
	    continue;

	ret = gss_add_oid_set_member(minor_status, &m->elements[i], mechs);
	if (ret) {
	    gss_release_oid_set(&junk, &m);
	    gss_release_oid_set(&junk, mechs);
	    return ret;
	}
    }
    gss_release_oid_set(&junk, &m);
    return ret;
}
Esempio n. 3
0
OM_uint32 _gsskrb5_inquire_names_for_mech (
            OM_uint32 * minor_status,
            const gss_OID mechanism,
            gss_OID_set * name_types
           )
{
    OM_uint32 ret;
    int i;

    *minor_status = 0;

    if (gss_oid_equal(mechanism, GSS_KRB5_MECHANISM) == 0 &&
	gss_oid_equal(mechanism, GSS_C_NULL_OID) == 0) {
	*name_types = GSS_C_NO_OID_SET;
	return GSS_S_BAD_MECH;
    }

    ret = gss_create_empty_oid_set(minor_status, name_types);
    if (ret != GSS_S_COMPLETE)
	return ret;

    for (i = 0; name_list[i] != NULL; i++) {
	ret = gss_add_oid_set_member(minor_status,
				     *(name_list[i]),
				     name_types);
	if (ret != GSS_S_COMPLETE)
	    break;
    }

    if (ret != GSS_S_COMPLETE)
	gss_release_oid_set(NULL, name_types);
	
    return GSS_S_COMPLETE;
}
Esempio n. 4
0
OM_uint32
ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
{
	gss_buffer_desc gssbuf;
	gss_name_t gssname;
	OM_uint32 status;
	gss_OID_set oidset;

	gssbuf.value = (void *) name;
	gssbuf.length = strlen(gssbuf.value);

	gss_create_empty_oid_set(&status, &oidset);
	gss_add_oid_set_member(&status, ctx->oid, &oidset);

	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
	    GSS_C_NT_USER_NAME, &gssname);

	if (!ctx->major)
		ctx->major = gss_acquire_cred(&ctx->minor, 
		    gssname, 0, oidset, GSS_C_INITIATE, 
		    &ctx->client_creds, NULL, NULL);

	gss_release_name(&status, &gssname);
	gss_release_oid_set(&status, &oidset);

	if (ctx->major)
		ssh_gssapi_error(ctx);

	return(ctx->major);
}
Esempio n. 5
0
/* Unprivileged */
void
ssh_gssapi_supported_oids(gss_OID_set *oidset)
{
	int i = 0;
	OM_uint32 min_status;
	int present;
	gss_OID_set supported;

	gss_create_empty_oid_set(&min_status, oidset);

	if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
		return;

	while (supported_mechs[i]->name != NULL) {
		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
		    &supported_mechs[i]->oid, supported, &present)))
			present = 0;
		if (present)
			gss_add_oid_set_member(&min_status,
			    &supported_mechs[i]->oid, oidset);
		i++;
	}

	gss_release_oid_set(&min_status, &supported);
}
Esempio n. 6
0
/* Privileged (called from ssh_gssapi_server_ctx) */
static OM_uint32
ssh_gssapi_acquire_cred(Gssctxt *ctx)
{
	OM_uint32 status;
	char lname[NI_MAXHOST];
	gss_OID_set oidset;

	gss_create_empty_oid_set(&status, &oidset);
	gss_add_oid_set_member(&status, ctx->oid, &oidset);

	if (gethostname(lname, sizeof(lname))) {
		gss_release_oid_set(&status, &oidset);
		return (-1);
	}

	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
		gss_release_oid_set(&status, &oidset);
		return (ctx->major);
	}

	if ((ctx->major = gss_acquire_cred(&ctx->minor,
	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
		ssh_gssapi_error(ctx);

	gss_release_oid_set(&status, &oidset);
	return (ctx->major);
}
Esempio n. 7
0
/* Privileged (called from ssh_gssapi_server_ctx) */
static OM_uint32
ssh_gssapi_acquire_cred(Gssctxt *ctx)
{
	OM_uint32 status;
	char lname[NI_MAXHOST];
	gss_OID_set oidset;

	if (options.gss_strict_acceptor) {
		gss_create_empty_oid_set(&status, &oidset);
		gss_add_oid_set_member(&status, ctx->oid, &oidset);

		if (gethostname(lname, MAXHOSTNAMELEN)) {
			gss_release_oid_set(&status, &oidset);
			return (-1);
		}

		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
			gss_release_oid_set(&status, &oidset);
			return (ctx->major);
		}

		if ((ctx->major = gss_acquire_cred(&ctx->minor,
		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds,
		    NULL, NULL)))
			ssh_gssapi_error(ctx);

		gss_release_oid_set(&status, &oidset);
		return (ctx->major);
	} else {
		ctx->name = GSS_C_NO_NAME;
		ctx->creds = GSS_C_NO_CREDENTIAL;
	}
	return GSS_S_COMPLETE;
}
Esempio n. 8
0
/**
 * Passes back the mech set of available mechs.
 * We only have one for now. 
 *
 * @param minor_status
 * @param mech_set
 *
 * @return
 */
OM_uint32 
GSS_CALLCONV gss_indicate_mechs(
    OM_uint32 *                         minor_status,
    gss_OID_set *                       mech_set)
{
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    gss_OID_set_desc  *                 set;
    static char *                       _function_name_ =
        "gss_indicate_mechs";
    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;

    if (minor_status == NULL || mech_set == NULL)
    {
        major_status = GSS_S_FAILURE;

        if (minor_status != NULL)
        {
            GLOBUS_GSI_GSSAPI_OPENSSL_ERROR_RESULT(
                    minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
                    (_GGSL("Invalid parameter")));
        }

        goto exit;
    }

    *minor_status = (OM_uint32) GLOBUS_SUCCESS;
    
    major_status = gss_create_empty_oid_set(&local_minor_status, 
                                            &set);
    if (GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_MECH);
        goto exit;
    }
    
    major_status = gss_add_oid_set_member(
        &local_minor_status, 
        (const gss_OID) gss_mech_globus_gssapi_openssl,
        &set);
    if (GSS_ERROR(major_status))
    {
        GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
            minor_status, local_minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_OID);
        
        gss_release_oid_set(&local_minor_status, &set);
        goto exit;
    }
    
    *mech_set = set;

 exit:
    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
Esempio n. 9
0
OM_uint32 GSSAPI_CALLCONV
_gss_ntlm_inquire_cred
           (OM_uint32 * minor_status,
            const gss_cred_id_t cred_handle,
            gss_name_t * name,
            OM_uint32 * lifetime,
            gss_cred_usage_t * cred_usage,
            gss_OID_set * mechanisms
           )
{
    OM_uint32 ret, junk;

    *minor_status = 0;

    if (cred_handle == NULL)
	return GSS_S_NO_CRED;

    if (name) {
	ntlm_name n = calloc(1, sizeof(*n));
	ntlm_cred c = (ntlm_cred)cred_handle;
	if (n) {
	    n->user = strdup(c->username);
	    n->domain = strdup(c->domain);
	}
	if (n == NULL || n->user == NULL || n->domain == NULL) {
	    if (n)
		free(n->user);
	    *minor_status = ENOMEM;
	    return GSS_S_FAILURE;
	}
	*name = (gss_name_t)n;
    }
    if (lifetime)
	*lifetime = GSS_C_INDEFINITE;
    if (cred_usage)
	*cred_usage = 0;
    if (mechanisms)
	*mechanisms = GSS_C_NO_OID_SET;

    if (cred_handle == GSS_C_NO_CREDENTIAL)
	return GSS_S_NO_CRED;

    if (mechanisms) {
        ret = gss_create_empty_oid_set(minor_status, mechanisms);
        if (ret)
	    goto out;
	ret = gss_add_oid_set_member(minor_status,
				     GSS_NTLM_MECHANISM,
				     mechanisms);
        if (ret)
	    goto out;
    }

    return GSS_S_COMPLETE;
out:
    gss_release_oid_set(&junk, mechanisms);
    return ret;
}
Esempio n. 10
0
OM_uint32 GSSAPI_CALLCONV
_gss_ntlm_inquire_names_for_mech (
            OM_uint32 * minor_status,
            const gss_OID mechanism,
            gss_OID_set * name_types
           )
{
    OM_uint32 ret;

    ret = gss_create_empty_oid_set(minor_status, name_types);
    if (ret != GSS_S_COMPLETE)
	return ret;

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
static OM_uint32
acceptor_approved(void *userptr,
		  gss_name_t target_name, 
		  const gss_cred_id_t cred_handle,
		  gss_OID mech)
{
    OM_uint32 junk, ret;
    gss_OID_set oidset;

    if (cred_handle) {
	int present = 0;

	ret = gss_inquire_cred(&junk,
			       cred_handle,
			       NULL,
			       NULL,
			       NULL,
			       &oidset);
	if (ret != GSS_S_COMPLETE)
	    return ret;

	ret = gss_test_oid_set_member(&junk, mech, oidset, &present);
	gss_release_oid_set(&junk, &oidset);
	
	if (ret != GSS_S_COMPLETE || present == 0)
	    return GSS_S_FAILURE;

    } else {
	gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;

	if (target_name == GSS_C_NO_NAME)
	    return GSS_S_COMPLETE;
	
	gss_create_empty_oid_set(&junk, &oidset);
	gss_add_oid_set_member(&junk, mech, &oidset);

	ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset,
			       GSS_C_ACCEPT, &cred, NULL, NULL);
	gss_release_oid_set(&junk, &oidset);
	if (ret != GSS_S_COMPLETE)
	    return ret;
	gss_release_cred(&junk, &cred);
    }

    return GSS_S_COMPLETE;
}
Esempio n. 12
0
gss_OID_set mag_filter_unwanted_mechs(gss_OID_set src)
{
    gss_const_OID unwanted_mechs[] = {
        &gss_mech_spnego,
        gss_mech_krb5_old,
        gss_mech_krb5_wrong,
        gss_mech_iakerb,
        GSS_C_NO_OID
    };
    gss_OID_set dst;
    uint32_t maj, min;
    int present = 0;

    if (src == GSS_C_NO_OID_SET) return GSS_C_NO_OID_SET;

    for (int i = 0; unwanted_mechs[i] != GSS_C_NO_OID; i++) {
        maj = gss_test_oid_set_member(&min,
                                      discard_const(unwanted_mechs[i]),
                                      src, &present);
        if (present) break;
    }
    if (present) {
        maj = gss_create_empty_oid_set(&min, &dst);
        if (maj != GSS_S_COMPLETE) {
            return GSS_C_NO_OID_SET;
        }
        for (int i = 0; i < src->count; i++) {
            present = 0;
            for (int j = 0; unwanted_mechs[j] != GSS_C_NO_OID; j++) {
                if (gss_oid_equal(&src->elements[i], unwanted_mechs[j])) {
                    present = 1;
                    break;
                }
            }
            if (present) continue;
            maj = gss_add_oid_set_member(&min, &src->elements[i], &dst);
            if (maj != GSS_S_COMPLETE) {
                gss_release_oid_set(&min, &dst);
                return GSS_C_NO_OID_SET;
            }
        }
        return dst;
    }
    return src;
}
Esempio n. 13
0
GSSAPI_LIB_FUNCTION OM_uint32 GSSAPI_LIB_CALL
gss_inquire_names_for_mech(OM_uint32 *minor_status,
    const gss_OID mechanism,
    gss_OID_set *name_types)
{
	OM_uint32 major_status;
	gssapi_mech_interface m = __gss_get_mechanism(mechanism);

	*minor_status = 0;
	*name_types = GSS_C_NO_OID_SET;
	if (!m)
		return (GSS_S_BAD_MECH);

	/*
	 * If the implementation can do it, ask it for a list of
	 * names, otherwise fake it.
	 */
	if (m->gm_inquire_names_for_mech) {
		return (m->gm_inquire_names_for_mech(minor_status,
			    mechanism, name_types));
	} else {
		major_status = gss_create_empty_oid_set(minor_status,
		    name_types);
		if (major_status)
			return (major_status);
		major_status = gss_add_oid_set_member(minor_status,
		    GSS_C_NT_HOSTBASED_SERVICE, name_types);
		if (major_status) {
			OM_uint32 junk;
			gss_release_oid_set(&junk, name_types);
			return (major_status);
		}
		major_status = gss_add_oid_set_member(minor_status,
		    GSS_C_NT_USER_NAME, name_types);
		if (major_status) {
			OM_uint32 junk;
			gss_release_oid_set(&junk, name_types);
			return (major_status);
		}
	}

	return (GSS_S_COMPLETE);
}
Esempio n. 14
0
OM_uint32
gssEapIndicateMechs(OM_uint32 *minor,
                    gss_OID_set *mechs)
{
    OM_uint32 major;

    major = gss_create_empty_oid_set(minor, mechs);
    if (GSS_ERROR(major)) {
        return major;
    }

    major = gss_add_oid_set_member(minor, GSS_SAMLEC_MECHANISM, mechs);
    if (GSS_ERROR(major)) {
        return major;
    }

    *minor = 0;
    return major;
}
Esempio n. 15
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_names_for_mech (
            OM_uint32 * minor_status,
            const gss_OID mechanism,
            gss_OID_set * name_types
           )
{
    gss_OID_set mechs, names, n;
    OM_uint32 ret, junk;
    size_t i, j;

    *name_types = NULL;

    ret = spnego_supported_mechs(minor_status, &mechs);
    if (ret != GSS_S_COMPLETE)
	return ret;

    ret = gss_create_empty_oid_set(minor_status, &names);
    if (ret != GSS_S_COMPLETE)
	goto out;

    for (i = 0; i < mechs->count; i++) {
	ret = gss_inquire_names_for_mech(minor_status,
					 &mechs->elements[i],
					 &n);
	if (ret)
	    continue;

	for (j = 0; j < n->count; j++)
	    gss_add_oid_set_member(minor_status,
				   &n->elements[j],
				   &names);
	gss_release_oid_set(&junk, &n);
    }

    ret = GSS_S_COMPLETE;
    *name_types = names;
out:

    gss_release_oid_set(&junk, &mechs);

    return ret;
}
Esempio n. 16
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_indicate_mechs
           (OM_uint32 * minor_status,
            gss_OID_set * mech_set
           )
{
  OM_uint32 ret, junk;

  ret = gss_create_empty_oid_set(minor_status, mech_set);
  if (ret)
      return ret;

  ret = gss_add_oid_set_member(minor_status, GSS_KRB5_MECHANISM, mech_set);
  if (ret) {
      gss_release_oid_set(&junk, mech_set);
      return ret;
  }

  *minor_status = 0;
  return GSS_S_COMPLETE;
}
Esempio n. 17
0
OM_uint32 _gsskrb5_inquire_mechs_for_name (
    OM_uint32 * minor_status,
    const gss_name_t input_name,
    gss_OID_set * mech_types
)
{
    OM_uint32 ret;

    ret = gss_create_empty_oid_set(minor_status, mech_types);
    if (ret)
        return ret;

    ret = gss_add_oid_set_member(minor_status,
                                 GSS_KRB5_MECHANISM,
                                 mech_types);
    if (ret)
        gss_release_oid_set(NULL, mech_types);

    return ret;
}
Esempio n. 18
0
OM_uint32 GSSAPI_CALLCONV _gss_spnego_inquire_mechs_for_name (
            OM_uint32 * minor_status,
            gss_const_name_t input_name,
            gss_OID_set * mech_types
           )
{
    OM_uint32 ret, junk;

    ret = gss_create_empty_oid_set(minor_status, mech_types);
    if (ret)
	return ret;

    ret = gss_add_oid_set_member(minor_status,
				 GSS_SPNEGO_MECHANISM,
				 mech_types);
    if (ret)
	gss_release_oid_set(&junk, mech_types);

    return ret;
}
OM_uint32 GSSAPI_CALLCONV
gss_inquire_names_for_mech(OM_uint32 *minor,
                           gss_OID mechanism,
                           gss_OID_set *ret_name_types)
{
    OM_uint32 major, tmpMinor;
    gss_OID nameTypes[] = {
        GSS_C_NT_USER_NAME,
        GSS_C_NT_HOSTBASED_SERVICE,
#ifdef MECH_EAP
        GSS_C_NT_EXPORT_NAME,
#ifdef HAVE_GSS_C_NT_COMPOSITE_EXPORT
        GSS_C_NT_COMPOSITE_EXPORT,
#endif
        GSS_EAP_NT_EAP_NAME,
        GSS_C_NT_ANONYMOUS,
#endif
    };
    size_t i;

    if (!gssEapIsMechanismOid(mechanism)) {
        *minor = GSSEAP_WRONG_MECH;
        return GSS_S_BAD_MECH;
    }

    major = gss_create_empty_oid_set(minor, ret_name_types);
    if (GSS_ERROR(major))
        goto cleanup;

    for (i = 0; i < sizeof(nameTypes)/sizeof(nameTypes[0]); i++) {
        major = gss_add_oid_set_member(minor, nameTypes[i], ret_name_types);
        if (GSS_ERROR(major))
            goto cleanup;
    }

cleanup:
    if (GSS_ERROR(major))
        gss_release_oid_set(&tmpMinor, ret_name_types);

    return major;
}
Esempio n. 20
0
OM_uint32 _netlogon_inquire_names_for_mech (
            OM_uint32 * minor_status,
            const gss_OID mechanism,
            gss_OID_set * name_types
           )
{
    OM_uint32 ret, tmp;

    ret = gss_create_empty_oid_set(minor_status, name_types);
    if (ret != GSS_S_COMPLETE)
        return ret;

    ret = gss_add_oid_set_member(minor_status, GSS_NETLOGON_NT_NETBIOS_DNS_NAME, name_types);
    if (ret != GSS_S_COMPLETE) {
        gss_release_oid_set(&tmp, name_types);
        return ret;
    }

    *minor_status = 0;
    return GSS_S_COMPLETE;
}
Esempio n. 21
0
static OM_uint32
acceptor_approved(gss_name_t target_name, gss_OID mech)
{
    gss_cred_id_t cred = GSS_C_NO_CREDENTIAL;
    gss_OID_set oidset;
    OM_uint32 junk, ret;

    if (target_name == GSS_C_NO_NAME)
	return GSS_S_COMPLETE;

    gss_create_empty_oid_set(&junk, &oidset);
    gss_add_oid_set_member(&junk, mech, &oidset);

    ret = gss_acquire_cred(&junk, target_name, GSS_C_INDEFINITE, oidset,
			   GSS_C_ACCEPT, &cred, NULL, NULL);
    gss_release_oid_set(&junk, &oidset);
    if (ret != GSS_S_COMPLETE)
	return ret;
    gss_release_cred(&junk, &cred);

    return GSS_S_COMPLETE;
}
Esempio n. 22
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)
{
	OM_uint32 major_status;
	gss_OID_set mechs = desired_mechs;
	gss_OID_set_desc set;
	struct _gss_name *name = (struct _gss_name *) desired_name;
	gssapi_mech_interface m;
	struct _gss_cred *cred;
	struct _gss_mechanism_cred *mc;
	OM_uint32 min_time, cred_time;
	int i;

	_gss_load_mech();

	/*
	 * First make sure that at least one of the requested
	 * mechanisms is one that we support.
	 */
	if (mechs) {
		for (i = 0; i < mechs->count; i++) {
			int t;
			gss_test_oid_set_member(minor_status,
			    &mechs->elements[i], _gss_mech_oids, &t);
			if (t)
				break;
		}
		if (i == mechs->count) {
			*output_cred_handle = 0;
			*minor_status = 0;
			return (GSS_S_BAD_MECH);
		}
	}

	if (actual_mechs) {
		major_status = gss_create_empty_oid_set(minor_status,
		    actual_mechs);
		if (major_status)
			return (major_status);
	}

	cred = malloc(sizeof(struct _gss_cred));
	if (!cred) {
		if (actual_mechs)
			gss_release_oid_set(minor_status, actual_mechs);
		*minor_status = ENOMEM;
		return (GSS_S_FAILURE);
	}
	cred->gc_usage = cred_usage;
	SLIST_INIT(&cred->gc_mc);

	if (mechs == GSS_C_NO_OID_SET)
		mechs = _gss_mech_oids;

	set.count = 1;
	min_time = GSS_C_INDEFINITE;
	for (i = 0; i < mechs->count; i++) {
		struct _gss_mechanism_name *mn = NULL;

		m = __gss_get_mechanism(&mechs->elements[i]);
		if (!m)
			continue;

		if (desired_name != GSS_C_NO_NAME) {
			mn = _gss_find_mn(name, &mechs->elements[i]);
			if (!mn)
				continue;
		}

		mc = malloc(sizeof(struct _gss_mechanism_cred));
		if (!mc) {
			continue;
		}
		SLIST_INIT(&cred->gc_mc);
		mc->gmc_mech = m;
		mc->gmc_mech_oid = &m->gm_mech_oid;

		/*
		 * XXX Probably need to do something with actual_mechs.
		 */
		set.elements = &mechs->elements[i];
		major_status = m->gm_acquire_cred(minor_status,
		    (desired_name != GSS_C_NO_NAME
			? mn->gmn_name : GSS_C_NO_NAME),
		    time_req, &set, cred_usage,
		    &mc->gmc_cred, NULL, &cred_time);
		if (major_status) {
			free(mc);
			continue;
		}
		if (cred_time < min_time)
			min_time = cred_time;

		if (actual_mechs) {
			major_status = gss_add_oid_set_member(minor_status,
			    mc->gmc_mech_oid, actual_mechs);
			if (major_status) {
				m->gm_release_cred(minor_status,
				    &mc->gmc_cred);
				free(mc);
				continue;
			}
		}

		SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link);
	}

	/*
	 * If we didn't manage to create a single credential, return
	 * an error.
	 */
	if (!SLIST_FIRST(&cred->gc_mc)) {
		free(cred);
		if (actual_mechs)
			gss_release_oid_set(minor_status, actual_mechs);
		*output_cred_handle = 0;
		*minor_status = 0;
		return (GSS_S_NO_CRED);
	}

	if (time_rec)
		*time_rec = min_time;
	*output_cred_handle = (gss_cred_id_t) cred;
	*minor_status = 0;
	return (GSS_S_COMPLETE);
}
Esempio n. 23
0
int
main(int argc, char **argv)
{
    gss_OID_set oidset = GSS_C_NULL_OID_SET;
    gss_OID mechoid = GSS_C_NO_OID;
    OM_uint32 maj_stat, min_stat;
    gss_cred_id_t cred;
    gss_name_t target = GSS_C_NO_NAME;
    int i, optidx = 0;
    gss_cred_usage_t cred_usage = GSS_C_BOTH;
    gss_OID type = GSS_C_NT_HOSTBASED_SERVICE;
    gss_key_value_set_desc store, *storep = GSS_C_NO_CRED_STORE;
    gss_key_value_element_desc elements[2];

    store.count = 0;
    store.elements = elements;

    setprogname(argv[0]);
    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag){
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    if (argc != 0)
	usage(1);

    if (acquire_type) {
	if (strcasecmp(acquire_type, "both") == 0)
	    cred_usage = GSS_C_BOTH;
	else if (strcasecmp(acquire_type, "accept") == 0)
	    cred_usage = GSS_C_ACCEPT;
	else if (strcasecmp(acquire_type, "initiate") == 0)
	    cred_usage = GSS_C_INITIATE;
	else
	    errx(1, "unknown type %s", acquire_type);
    }

    if (name_type) {
	if (strcasecmp("hostbased-service", name_type) == 0)
	    type = GSS_C_NT_HOSTBASED_SERVICE;
	else if (strcasecmp("user-name", name_type) == 0)
	    type = GSS_C_NT_USER_NAME;
	else
	    errx(1, "unknown name type %s", name_type);
    }

    if (ccache) {
	store.elements[store.count].key = "ccache";
	store.elements[store.count].value = ccache;
	store.count++;
    }
    if (client_keytab) {
	store.elements[store.count].key = "client_keytab";
	store.elements[store.count].value = client_keytab;
	store.count++;
    }

    if (store.count)
	storep = &store;

    if (kerberos_flag) {
	mechoid = GSS_KRB5_MECHANISM;

	maj_stat = gss_create_empty_oid_set(&min_stat, &oidset);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_create_empty_oid_set: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));

	maj_stat = gss_add_oid_set_member(&min_stat, GSS_KRB5_MECHANISM, &oidset);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_add_oid_set_member: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    }

    if (target_name) {
	gss_buffer_desc name;

	name.value = target_name;
	name.length = strlen(target_name);
	maj_stat = gss_import_name(&min_stat, &name,
				   GSS_C_NT_HOSTBASED_SERVICE, &target);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_import_name: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    }

    for (i = 0; i < num_loops; i++) {

	cred = acquire_cred_service(acquire_name, type, oidset, cred_usage, storep);

	if (enctype) {
	    int32_t enctypelist = enctype;

	    maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, cred,
						       1, &enctypelist);
	    if (maj_stat)
		errx(1, "gss_krb5_set_allowable_enctypes: %s",
		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
	}

	if (target) {
	    gss_ctx_id_t context = GSS_C_NO_CONTEXT;
	    gss_buffer_desc out;

	    out.length = 0;
	    out.value = NULL;

	    maj_stat = gss_init_sec_context(&min_stat,
					    cred, &context,
					    target, mechoid,
					    GSS_C_MUTUAL_FLAG, 0, NULL,
					    GSS_C_NO_BUFFER, NULL,
					    &out, NULL, NULL);
	    if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED)
		errx(1, "init_sec_context failed: %s",
		     gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));

	    gss_release_buffer(&min_stat, &out);
	    gss_delete_sec_context(&min_stat, &context, NULL);
	}
	gss_release_cred(&min_stat, &cred);
    }


    return 0;
}
/**
 * @brief Set Security Context Option
 * @ingroup globus_gsi_gssapi_extensions
 * @details
 * GSSAPI routine to initiate the sending of a security context
 * See: <draft-ietf-cat-gssv2-cbind-04.txt>
 *
 * @param minor_status
 * @param context_handle
 * @param option
 * @param value
 *
 * @return
 */
OM_uint32
GSS_CALLCONV gss_set_sec_context_option(
    OM_uint32 *                         minor_status,
    gss_ctx_id_t *                      context_handle,
    const gss_OID                       option,
    const gss_buffer_t                  value)
{
    gss_ctx_id_desc *                   context = NULL;
    OM_uint32                           major_status = GSS_S_COMPLETE;
    OM_uint32                           local_minor_status;
    globus_result_t                     local_result = GLOBUS_SUCCESS;
    int                                 index;

    GLOBUS_I_GSI_GSSAPI_DEBUG_ENTER;
    
    if(minor_status == NULL)
    {
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *minor_status = (OM_uint32) GLOBUS_SUCCESS;
    
    if(context_handle == NULL)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid context_handle passed to function - cannot be NULL")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    context = *context_handle;

    if(option == GSS_C_NO_OID)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
            (_GGSL("Invalid option passed to function with value: GSS_C_NO_OID")));
        major_status = GSS_S_FAILURE;
        goto exit;
    }
    
    if (*context_handle == GSS_C_NO_CONTEXT)
    {
        /* for now just malloc and zero the context */
        context = (gss_ctx_id_desc *) malloc(sizeof(gss_ctx_id_desc));
        if (context == NULL)
        {
            GLOBUS_GSI_GSSAPI_MALLOC_ERROR(minor_status);
            major_status = GSS_S_FAILURE;
            goto exit;
        }

        *context_handle = context;
        memset(context, 0, sizeof(gss_ctx_id_desc));
        context->ctx_flags = 0;

        major_status = gss_create_empty_oid_set(
            &local_minor_status,
            (gss_OID_set *) &context->extension_oids);

        /* initialize the callback_data in the context.  This needs
         * to be done so the verify_callback func can be set later.
         */
        local_result = globus_gsi_callback_data_init(
            &context->callback_data);
        if(local_result != GLOBUS_SUCCESS)
        {
            GLOBUS_GSI_GSSAPI_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT,
                (_GGSL("The callback data in the context "
                 "could not be initialized.")));
            major_status = GSS_S_FAILURE;
            goto exit;
        }
    }
    else if(context->ctx_flags & GSS_I_CTX_INITIALIZED)
    {
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_WITH_GSS_CONTEXT,
            (_GGSL("The context has already been initialized!  %s should be "
             "called on a context before initialization"), __func__));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    if(g_OID_equal(option, GSS_DISALLOW_ENCRYPTION))
    {
        context->ctx_flags |= GSS_I_DISALLOW_ENCRYPTION;
    }
    else if(g_OID_equal(option, GSS_PROTECTION_FAIL_ON_CONTEXT_EXPIRATION))
    {
        context->ctx_flags |= GSS_I_PROTECTION_FAIL_ON_CONTEXT_EXPIRATION;
    }
    else if(g_OID_equal(option, GSS_APPLICATION_WILL_HANDLE_EXTENSIONS))
    {
        if(value == GSS_C_NO_BUFFER)
        {
            GLOBUS_GSI_GSSAPI_ERROR_RESULT(
                minor_status,
                GLOBUS_GSI_GSSAPI_ERROR_BAD_ARGUMENT,
                (_GGSL("Invalid buffer passed to function")));
            major_status = GSS_S_FAILURE;
            goto exit;
        }

        for(index = 0; 
            index < ((gss_OID_set_desc *) value->value)->count; 
            index++)
        {
            major_status = gss_add_oid_set_member(
                &local_minor_status,
                (gss_OID) 
                &((gss_OID_set_desc *) value->value)->elements[index],
                (gss_OID_set *) &context->extension_oids);

            if(GSS_ERROR(major_status))
            {
                GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                    minor_status, local_minor_status,
                    GLOBUS_GSI_GSSAPI_ERROR_WITH_OID);
                goto exit;
            }
        }

        local_result = globus_gsi_callback_set_extension_cb(
            context->callback_data,
            globus_i_gsi_gss_verify_extensions_callback);
        if(local_result != GLOBUS_SUCCESS)
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_result,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
            major_status = GSS_S_FAILURE;
            goto exit;
        }

        /* if the extension_oids are set, 
         * then we set them in the callback data */
        local_result = globus_gsi_callback_set_extension_oids(
            context->callback_data,
            (void *) context->extension_oids);
        if(local_result != GLOBUS_SUCCESS)
        {
            GLOBUS_GSI_GSSAPI_ERROR_CHAIN_RESULT(
                minor_status, local_result,
                GLOBUS_GSI_GSSAPI_ERROR_WITH_CALLBACK_DATA);
            major_status = GSS_S_FAILURE;
            goto exit;
        }

        context->ctx_flags |= GSS_I_APPLICATION_WILL_HANDLE_EXTENSIONS;
    }
    else
    {
        /* unknown option */
        GLOBUS_GSI_GSSAPI_ERROR_RESULT(
            minor_status,
            GLOBUS_GSI_GSSAPI_ERROR_UNKNOWN_OPTION,
            (NULL));
        major_status = GSS_S_FAILURE;
        goto exit;
    }

    *context_handle = context;

 exit:

    GLOBUS_I_GSI_GSSAPI_DEBUG_EXIT;
    return major_status;
}
Esempio n. 25
0
int
main(int argc, char **argv)
{
    int i, s, done, print_body, gssapi_done, gssapi_started, optidx = 0;
    const char *host, *page;
    struct http_req req;
    char *headers[99]; /* XXX */
    int num_headers;
    krb5_storage *sp;

    gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL;
    gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
    gss_name_t server = GSS_C_NO_NAME;
    gss_OID mech_oid, cred_mech_oid;
    OM_uint32 flags;
    OM_uint32 maj_stat, min_stat;

    setprogname(argv[0]);

    if(getarg(http_args, num_http_args, argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag) {
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    mech_oid = select_mech(mech);

    if (cred_mech_str)
	cred_mech_oid = select_mech(cred_mech_str);
    else
	cred_mech_oid = mech_oid;

    if (argc != 1 && argc != 2)
	errx(1, "usage: %s host [page]", getprogname());
    host = argv[0];
    if (argc == 2)
	page = argv[1];
    else
	page = "/";

    flags = 0;
    if (delegate_flag)
	flags |= GSS_C_DELEG_FLAG;
    if (policy_flag)
	flags |= GSS_C_DELEG_POLICY_FLAG;
    if (mutual_flag)
	flags |= GSS_C_MUTUAL_FLAG;

    done = 0;
    num_headers = 0;
    gssapi_done = 0;
    gssapi_started = 0;

    if (client_str) {
	gss_buffer_desc name_buffer;
	gss_name_t name;
	gss_OID_set mechset = GSS_C_NO_OID_SET;

	name_buffer.value = client_str;
	name_buffer.length = strlen(client_str);

	maj_stat = gss_import_name(&min_stat, &name_buffer, GSS_C_NT_USER_NAME, &name);
	if (maj_stat)
	    errx(1, "failed to import name");

	if (cred_mech_oid) {
	    gss_create_empty_oid_set(&min_stat, &mechset);
	    gss_add_oid_set_member(&min_stat, cred_mech_oid, &mechset);
	}
	
	maj_stat = gss_acquire_cred(&min_stat, name, GSS_C_INDEFINITE,
				    mechset, GSS_C_INITIATE,
				    &client_cred, NULL, NULL);
	gss_release_name(&min_stat, &name);
	gss_release_oid_set(&min_stat, &mechset);
	if (maj_stat)
	    errx(1, "failed to find cred of name %s", client_str);
    }

    {
	gss_buffer_desc name_token;
	char *name;
	asprintf(&name, "%s@%s", gss_service, host);
	name_token.length = strlen(name);
	name_token.value = name;
	
	maj_stat = gss_import_name(&min_stat,
				   &name_token,
				   GSS_C_NT_HOSTBASED_SERVICE,
				   &server);
	if (GSS_ERROR(maj_stat))
	    gss_err (1, min_stat, "gss_inport_name: %s", name);
	free(name);
    }

    s = do_connect(host, port_str);
    if (s < 0)
	errx(1, "connection failed");

    sp = krb5_storage_from_fd(s);
    if (sp == NULL)
	errx(1, "krb5_storage_from_fd");

    do {
	print_body = 0;

	http_query(sp, host, page, headers, num_headers, &req);
	for (i = 0 ; i < num_headers; i++)
	    free(headers[i]);
	num_headers = 0;

	if (strstr(req.response, " 200 ") != NULL) {
	    print_body = 1;
	    done = 1;
	} else if (strstr(req.response, " 401 ") != NULL) {
	    if (http_find_header(&req, "WWW-Authenticate:") == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);
	}

	if (!gssapi_done) {
	    const char *h = http_find_header(&req, "WWW-Authenticate:");
	    if (h == NULL)
		errx(1, "Got %s but missed `WWW-Authenticate'", req.response);

	    if (strncasecmp(h, "Negotiate", 9) == 0) {
		gss_buffer_desc input_token, output_token;

		if (verbose_flag)
		    printf("Negotiate found\n");

		i = 9;
		while(h[i] && isspace((unsigned char)h[i]))
		    i++;
		if (h[i] != '\0') {
		    size_t len = strlen(&h[i]);
		    int slen;
		    if (len == 0)
			errx(1, "invalid Negotiate token");
		    input_token.value = emalloc(len);
		    slen = base64_decode(&h[i], input_token.value);
		    if (slen < 0)
			errx(1, "invalid base64 Negotiate token %s", &h[i]);
		    input_token.length = slen;
		} else {
		    if (gssapi_started)
			errx(1, "Negotiate already started");
		    gssapi_started = 1;

		    input_token.length = 0;
		    input_token.value = NULL;
		}

		if (strstr(req.response, " 200 ") != NULL)
		    sleep(1);

		maj_stat =
		    gss_init_sec_context(&min_stat,
					 client_cred,
					 &context_hdl,
					 server,
					 mech_oid,
					 flags,
					 0,
					 GSS_C_NO_CHANNEL_BINDINGS,
					 &input_token,
					 NULL,
					 &output_token,
					 NULL,
					 NULL);
		if (maj_stat == GSS_S_CONTINUE_NEEDED) {

		} else if (maj_stat == GSS_S_COMPLETE) {
		    gss_name_t targ_name, src_name;
		    gss_buffer_desc name_buffer;
		    gss_OID mech_type;

		    gssapi_done = 1;

		    maj_stat = gss_inquire_context(&min_stat,
						   context_hdl,
						   &src_name,
						   &targ_name,
						   NULL,
						   &mech_type,
						   NULL,
						   NULL,
						   NULL);
		    if (GSS_ERROR(maj_stat))
			gss_err (1, min_stat, "gss_inquire_context");

		    printf("Negotiate done: %s\n", mech);

		    maj_stat = gss_display_name(&min_stat,
						src_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Source: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_buffer(&min_stat, &name_buffer);

		    maj_stat = gss_display_name(&min_stat,
						targ_name,
						&name_buffer,
						NULL);
		    if (GSS_ERROR(maj_stat))
			gss_print_errors(min_stat);
		    else
			printf("Target: %.*s\n",
			       (int)name_buffer.length,
			       (char *)name_buffer.value);

		    gss_release_name(&min_stat, &targ_name);
		    gss_release_buffer(&min_stat, &name_buffer);
		} else {
		    gss_err (1, min_stat, "gss_init_sec_context");
		}


		if (output_token.length) {
		    char *neg_token;

		    base64_encode(output_token.value,
				  (int)output_token.length,
				  &neg_token);

		    asprintf(&headers[0], "Authorization: Negotiate %s",
			     neg_token);

		    num_headers = 1;
		    free(neg_token);
		    gss_release_buffer(&min_stat, &output_token);
		}
		if (input_token.length)
		    free(input_token.value);

	    } else
		done = 1;
	} else
	    done = 1;

	if (print_body || verbose_flag)
	    printf("%.*s\n", (int)req.body_size, (char *)req.body);

	http_req_free(&req);
    } while (!done);

    if (gssapi_done == 0)
	errx(1, "gssapi not done but http dance done");

    krb5_storage_free(sp);
    close(s);

    return 0;
}
Esempio n. 26
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
(OM_uint32 * minor_status,
 gss_const_name_t desired_name,
 gss_const_OID credential_type,
 const void *credential_data,
 OM_uint32 time_req,
 gss_const_OID desired_mech,
 gss_cred_usage_t cred_usage,
 gss_cred_id_t * output_cred_handle
    )
{
    krb5_context context;
    gsskrb5_cred handle;
    OM_uint32 ret;

    cred_usage &= GSS_C_OPTION_MASK;

    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(&context);

    *output_cred_handle = NULL;

    handle = calloc(1, sizeof(*handle));
    if (handle == NULL) {
	*minor_status = ENOMEM;
        return (GSS_S_FAILURE);
    }

    HEIMDAL_MUTEX_init(&handle->cred_id_mutex);

    if (desired_name != GSS_C_NO_NAME) {
	ret = _gsskrb5_canon_name(minor_status, context, 1, NULL,
				  desired_name, &handle->principal);
	if (ret) {
	    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, context,
				     credential_type, credential_data,
				     desired_name, time_req,
				     desired_mech, cred_usage, handle);
    	if (ret != GSS_S_COMPLETE) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    krb5_free_principal(context, handle->principal);
	    free(handle);
	    return (ret);
	}
    }
    if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
	ret = acquire_acceptor_cred(minor_status, context,
				    credential_type, credential_data,
				    desired_name, time_req,
				    desired_mech, cred_usage, handle);
	if (ret != GSS_S_COMPLETE) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    krb5_free_principal(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) {
	if (handle->mechanisms != NULL)
	    gss_release_oid_set(NULL, &handle->mechanisms);
	HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	krb5_free_principal(context, handle->principal);
	free(handle);
	return (ret);
    }
    handle->usage = cred_usage;
    *minor_status = 0;
    *output_cred_handle = (gss_cred_id_t)handle;
    return (GSS_S_COMPLETE);
}
Esempio n. 27
0
OM_uint32 GSSAPI_CALLCONV _gsskrb5_acquire_cred_ext
(OM_uint32 * minor_status,
 gss_const_name_t desired_name,
 gss_const_OID credential_type,
 const void *credential_data,
 OM_uint32 time_req,
 gss_const_OID desired_mech,
 gss_cred_usage_t cred_usage,
 gss_cred_id_t * output_cred_handle
    )
{
    krb5_context context;
    gsskrb5_cred handle;
    OM_uint32 ret;

    cred_usage &= GSS_C_OPTION_MASK;

    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(&context);

    *output_cred_handle = GSS_C_NO_CREDENTIAL;

    handle = calloc(1, sizeof(*handle));
    if (handle == NULL) {
	*minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }

    HEIMDAL_MUTEX_init(&handle->cred_id_mutex);

    if (desired_name != GSS_C_NO_NAME) {
	ret = _gsskrb5_canon_name(minor_status, context,
				  desired_name, &handle->principal);
	if (ret) {
	    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	    free(handle);
	    return ret;
	}
    }

    if (credential_type != GSS_C_NO_OID &&
        gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
        /* Acquire a cred with a password */
        gss_const_buffer_t pwbuf = credential_data;
        char *pw;

        if (pwbuf == NULL) {
            HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
            free(handle);
            *minor_status = KRB5_NOCREDS_SUPPLIED; /* see below */
            return GSS_S_CALL_INACCESSIBLE_READ;
        }

        /* NUL-terminate the password, if it wasn't already */
        pw = strndup(pwbuf->value, pwbuf->length);
        if (pw == NULL) {
            HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
            free(handle);
            *minor_status = krb5_enomem(context);
            return GSS_S_CALL_INACCESSIBLE_READ;
        }
        ret = acquire_cred_with_password(minor_status, context, pw, time_req,
                                         desired_mech, cred_usage, handle);
        free(pw);
        if (ret != GSS_S_COMPLETE) {
            HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
            krb5_free_principal(context, handle->principal);
            free(handle);
            return (ret);
        }
    } else if (credential_type != GSS_C_NO_OID) {
        /*
         * _gss_acquire_cred_ext() called with something other than a password.
         *
         * Not supported.
         *
         * _gss_acquire_cred_ext() is not a supported public interface, so
         * we don't have to try too hard as to minor status codes here.
         */
        HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
        free(handle);
        *minor_status = ENOTSUP;
        return GSS_S_FAILURE;
    } else {
        /*
         * Acquire a credential from the background credential store (ccache,
         * keytab).
         */
        if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) {
            ret = acquire_initiator_cred(minor_status, context, time_req,
                                         desired_mech, cred_usage, handle);
            if (ret != GSS_S_COMPLETE) {
                HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
                krb5_free_principal(context, handle->principal);
                free(handle);
                return (ret);
            }
        }
        if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) {
            ret = acquire_acceptor_cred(minor_status, context, time_req,
                                        desired_mech, cred_usage, handle);
            if (ret != GSS_S_COMPLETE) {
                HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
                krb5_free_principal(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) {
	if (handle->mechanisms != NULL)
	    gss_release_oid_set(NULL, &handle->mechanisms);
	HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
	krb5_free_principal(context, handle->principal);
	free(handle);
	return (ret);
    }
    handle->usage = cred_usage;
    *minor_status = 0;
    *output_cred_handle = (gss_cred_id_t)handle;
    return (GSS_S_COMPLETE);
}
Esempio n. 28
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)
{
	OM_uint32 major_status;
	struct acquire_cred_res res;
	struct acquire_cred_args args;
	enum clnt_stat stat;
	gss_cred_id_t cred;
	int i;
	CLIENT *cl;

	*minor_status = 0;
	cl = kgss_gssd_client();
	if (cl == NULL)
		return (GSS_S_FAILURE);

	args.uid = curthread->td_ucred->cr_uid;
	if (desired_name)
		args.desired_name = desired_name->handle;
	else
		args.desired_name = 0;
	args.time_req = time_req;
	args.desired_mechs = desired_mechs;
	args.cred_usage = cred_usage;

	bzero(&res, sizeof(res));
	stat = gssd_acquire_cred_1(&args, &res, cl);
	CLNT_RELEASE(cl);
	if (stat != RPC_SUCCESS) {
		*minor_status = stat;
		return (GSS_S_FAILURE);
	}

	if (res.major_status != GSS_S_COMPLETE) {
		*minor_status = res.minor_status;
		return (res.major_status);
	}

	cred = malloc(sizeof(struct _gss_cred_id_t), M_GSSAPI, M_WAITOK);
	cred->handle = res.output_cred;
	*output_cred_handle = cred;
	if (actual_mechs) {
		major_status = gss_create_empty_oid_set(minor_status,
		    actual_mechs);
		if (major_status)
			return (major_status);
		for (i = 0; i < res.actual_mechs->count; i++) {
			major_status = gss_add_oid_set_member(minor_status,
			    &res.actual_mechs->elements[i], actual_mechs);
			if (major_status)
				return (major_status);
		}
	}
	if (time_rec)
		*time_rec = res.time_rec;

	xdr_free((xdrproc_t) xdr_acquire_cred_res, &res);

	return (GSS_S_COMPLETE);
}
Esempio n. 29
0
OM_uint32
_gsskrb5_krb5_import_cred(OM_uint32 *minor_status,
			  krb5_ccache id,
			  krb5_principal keytab_principal,
			  krb5_keytab keytab,
			  gss_cred_id_t *cred)
{
    krb5_context context;
    krb5_error_code kret;
    gsskrb5_cred handle;
    OM_uint32 ret;

    *cred = NULL;

    GSSAPI_KRB5_INIT (&context);

    handle = calloc(1, sizeof(*handle));
    if (handle == NULL) {
	_gsskrb5_clear_status ();
	*minor_status = ENOMEM;
        return (GSS_S_FAILURE);
    }
    HEIMDAL_MUTEX_init(&handle->cred_id_mutex);

    handle->usage = 0;

    if (id) {
	char *str;

	handle->usage |= GSS_C_INITIATE;

	kret = krb5_cc_get_principal(context, id,
				     &handle->principal);
	if (kret) {
	    free(handle);
	    *minor_status = kret;
	    return GSS_S_FAILURE;
	}

	if (keytab_principal) {
	    krb5_boolean match;

	    match = krb5_principal_compare(context,
					   handle->principal,
					   keytab_principal);
	    if (match == FALSE) {
		krb5_free_principal(context, handle->principal);
		free(handle);
		_gsskrb5_clear_status ();
		*minor_status = EINVAL;
		return GSS_S_FAILURE;
	    }
	}

	ret = __gsskrb5_ccache_lifetime(minor_status,
					context,
					id,
					handle->principal,
					&handle->lifetime);
	if (ret != GSS_S_COMPLETE) {
	    krb5_free_principal(context, handle->principal);
	    free(handle);
	    return ret;
	}


	kret = krb5_cc_get_full_name(context, id, &str);
	if (kret)
	    goto out;

	kret = krb5_cc_resolve(context, str, &handle->ccache);
	free(str);
	if (kret)
	    goto out;
    }


    if (keytab) {
	char *str;

	handle->usage |= GSS_C_ACCEPT;

	if (keytab_principal && handle->principal == NULL) {
	    kret = krb5_copy_principal(context,
				       keytab_principal,
				       &handle->principal);
	    if (kret)
		goto out;
	}

	kret = krb5_kt_get_full_name(context, keytab, &str);
	if (kret)
	    goto out;

	kret = krb5_kt_resolve(context, str, &handle->keytab);
	free(str);
	if (kret)
	    goto out;
    }


    if (id || keytab) {
	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) {
	    kret = *minor_status;
	    goto out;
	}
    }

    *minor_status = 0;
    *cred = (gss_cred_id_t)handle;
    return GSS_S_COMPLETE;

out:
    gss_release_oid_set(minor_status, &handle->mechanisms);
    if (handle->ccache)
	krb5_cc_close(context, handle->ccache);
    if (handle->keytab)
	krb5_kt_close(context, handle->keytab);
    if (handle->principal)
	krb5_free_principal(context, handle->principal);
    HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex);
    free(handle);
    *minor_status = kret;
    return GSS_S_FAILURE;
}
Esempio n. 30
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);
}