示例#1
0
int
main(int argc, char **argv)
{
    krb5_context ctx, ctx2;
    krb5_plugin_initvt_fn *mods;
    const krb5_enctype etypes1[] = { ENCTYPE_DES3_CBC_SHA1, 0 };
    const krb5_enctype etypes2[] = { ENCTYPE_AES128_CTS_HMAC_SHA1_96,
                                     ENCTYPE_AES256_CTS_HMAC_SHA1_96, 0 };
    krb5_prompt_type ptypes[] = { KRB5_PROMPT_TYPE_PASSWORD };

    /* Copy a default context and verify the result. */
    check(krb5_init_context(&ctx) == 0);
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    /* Set non-default values for all of the propagated fields in ctx. */
    ctx->allow_weak_crypto = TRUE;
    check(krb5_set_default_in_tkt_ktypes(ctx, etypes1) == 0);
    check(krb5_set_default_tgs_enctypes(ctx, etypes2) == 0);
    check(krb5_set_debugging_time(ctx, 1234, 5678) == 0);
    check(krb5_cc_set_default_name(ctx, "defccname") == 0);
    check(krb5_set_default_realm(ctx, "defrealm") == 0);
    ctx->clockskew = 18;
    ctx->kdc_req_sumtype = CKSUMTYPE_NIST_SHA;
    ctx->default_ap_req_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
    ctx->default_safe_sumtype = CKSUMTYPE_HMAC_SHA1_96_AES256;
    ctx->kdc_default_options = KDC_OPT_FORWARDABLE;
    ctx->library_options = 0;
    ctx->profile_secure = TRUE;
    ctx->udp_pref_limit = 2345;
    ctx->use_conf_ktypes = TRUE;
    ctx->ignore_acceptor_hostname = TRUE;
    ctx->dns_canonicalize_hostname = CANONHOST_FALSE;
    free(ctx->plugin_base_dir);
    check((ctx->plugin_base_dir = strdup("/a/b/c/d")) != NULL);

    /* Also set some of the non-propagated fields. */
    ctx->prompt_types = ptypes;
    check(k5_plugin_load_all(ctx, PLUGIN_INTERFACE_PWQUAL, &mods) == 0);
    k5_plugin_free_modules(ctx, mods);
    k5_setmsg(ctx, ENOMEM, "nooooooooo");
    krb5_set_trace_callback(ctx, trace, ctx);

    /* Copy the intentionally messy context and verify the result. */
    check(krb5_copy_context(ctx, &ctx2) == 0);
    check_context(ctx2, ctx);
    krb5_free_context(ctx2);

    krb5_free_context(ctx);
    return 0;
}
示例#2
0
kim_error kim_identity_copy (kim_identity *out_identity,
                             kim_identity  in_identity)
{
    kim_error err = KIM_NO_ERROR;
    kim_identity identity = KIM_IDENTITY_ANY;

    if (!err && !out_identity) { err = check_error (KIM_NULL_PARAMETER_ERR); }

    if (!err && in_identity != KIM_IDENTITY_ANY) {
        err = kim_identity_allocate (&identity);

        if (!err) {
            err = krb5_error (in_identity->context,
                              krb5_copy_context (in_identity->context,
                                                 &identity->context));
        }

        if (!err) {
            err = krb5_error (identity->context,
                              krb5_copy_principal (identity->context,
                                                   in_identity->principal,
                                                   &identity->principal));
        }
    }

    if (!err) {
        *out_identity = identity;
        identity = NULL;
    }

    kim_identity_free (&identity);

    return check_error (err);
}
示例#3
0
kim_error kim_identity_create_from_krb5_principal (kim_identity  *out_identity,
                                                   krb5_context   in_krb5_context,
                                                   krb5_principal in_krb5_principal)
{
    kim_error err = KIM_NO_ERROR;
    kim_identity identity = NULL;

    if (!err && !out_identity     ) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    if (!err && !in_krb5_principal) { err = check_error (KIM_NULL_PARAMETER_ERR); }
    /* KLCreatePrincipalFromKerberos5Principal passes NULL in_krb5_context */

    if (!err) {
        err = kim_identity_allocate (&identity);
    }

    if (!err) {
        if (in_krb5_context) {
            err = krb5_error (in_krb5_context,
                              krb5_copy_context (in_krb5_context,
                                                 &identity->context));
        } else {
            err = krb5_error (NULL,
                              krb5_init_context (&identity->context));
        }
    }

    if (!err) {
        err = krb5_error (identity->context,
                          krb5_copy_principal (identity->context,
                                               in_krb5_principal,
                                               &identity->principal));
    }

    if (!err) {
        *out_identity = identity;
        identity = NULL;
    }

    kim_identity_free (&identity);

    return check_error (err);
}
示例#4
0
/*
 *	Validate user/pass (Heimdal)
 */
static rlm_rcode_t krb5_auth(void *instance, REQUEST *request)
{
	rlm_krb5_t *inst = instance;
	rlm_rcode_t rcode;
	
	krb5_error_code ret;
	
	krb5_principal client;
	krb5_ccache ccache;
	krb5_keytab keytab;
	krb5_verify_opt options;
	krb5_context *context = NULL;
	
	/*
	 *	See above in MIT krb5_auth
	 */
	ret = krb5_copy_context(*(inst->context), context);
	if (ret) {
		radlog(L_ERR, "rlm_krb5 (%s): Error cloning krb5 context: %s",
		       inst->xlat_name, error_message(ret));
		
		return RLM_MODULE_FAIL;
	}
	
	/*
	 *	Setup krb5_verify_user options
	 *
	 *	Not entirely sure this is necessary, but as we use context 
	 *	to get the cache handle, we probably do have to do this with
	 *	the cloned context.
	 */
	krb5_cc_default(*context, &ccache);
	
	krb5_verify_opt_init(&options);
	krb5_verify_opt_set_ccache(&options, ccache);
	
	memset(&keytab, 0, sizeof(keytab));
	ret = inst->keytabname ? 
		krb5_kt_resolve(*context, inst->keytabname, &keytab) :
		krb5_kt_default(*context, &keytab);
	if (ret) {
		radlog(L_ERR, "rlm_krb5 (%s): Resolving keytab failed: %s",
		       inst->xlat_name, error_message(ret));
		
		goto cleanup;
	}
	
	krb5_verify_opt_set_keytab(&options, keytab);
	krb5_verify_opt_set_secure(&options, TRUE);

	if (inst->service) {
		krb5_verify_opt_set_service(&options, inst->service);
	}
	
	rcode = krb5_parse_user(inst, request, &client);
	if (rcode != RLM_MODULE_OK) goto cleanup;

	/* 
	 *	Verify the user, using the options we set in instantiate
	 */
	ret = krb5_verify_user_opt(*context, client,
				   request->password->vp_strvalue,
				   &options);
	if (ret) {
		switch (ret) {
		case KRB5_LIBOS_BADPWDMATCH:
		case KRB5KRB_AP_ERR_BAD_INTEGRITY:
			RDEBUG("Provided password was incorrect: %s",
			       error_message(ret));
			rcode = RLM_MODULE_REJECT;
		
			break;
		case KRB5KDC_ERR_KEY_EXP:
		case KRB5KDC_ERR_CLIENT_REVOKED:
		case KRB5KDC_ERR_SERVICE_REVOKED:
			RDEBUG("Account has been locked out: %s",
			       error_message(ret));
			rcode = RLM_MODULE_USERLOCK;
		
			break;
		case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
			RDEBUG("User not found: %s", error_message(ret));
			rcode = RLM_MODULE_NOTFOUND;
					
		default:
			radlog(L_ERR, "rlm_krb5 (%s): Verifying user failed: "
			       "%s", inst->xlat_name, error_message(ret));
			rcode = RLM_MODULE_FAIL;
		
			break;
		}

		goto cleanup;
	}
	
	cleanup:
	
	krb5_free_context(*context);
	krb5_kt_close(*context, keytab);
	
	return rcode;
}
示例#5
0
/* 
 *  Validate userid/passwd (MIT)
 */
static rlm_rcode_t krb5_auth(void *instance, REQUEST *request)
{
	rlm_krb5_t *inst = instance;
	rlm_rcode_t rcode;	
	krb5_error_code ret;

	krb5_principal client;
	krb5_creds init_creds;
	krb5_keytab keytab;
	krb5_context *context = NULL;
	
	/*
	 *	All the snippets on threadsafety say that individual threads
	 *	must each use their own copy of context.
	 *
	 *	As we don't have any per thread instantiation, we either have
	 *	to clone inst->context on every request, or use the connection
	 *	API.
	 *
	 *	@todo Use the connection API (3.0 only).
	 */
	ret = krb5_copy_context(*(inst->context), context);
	if (ret) {
		radlog(L_ERR, "rlm_krb5 (%s): Error cloning krb5 context: %s",
		       inst->xlat_name, error_message(ret));
		
		return RLM_MODULE_FAIL;
	}

	/*
	 *	Check we have all the required VPs, and convert the username
	 *	into a principal.
	 */
	rcode = krb5_parse_user(inst, request, &client);
	if (rcode != RLM_MODULE_OK) goto cleanup;

	/*
	 * 	Retrieve the TGT from the TGS/KDC and check we can decrypt it.
	 */
	memset(&init_creds, 0, sizeof(init_creds));
	ret = krb5_get_init_creds_password(*context, &init_creds, client,
					   request->password->vp_strvalue,
					   NULL, NULL, 0, NULL,
					   inst->gic_options);
	if (ret) {
		error:
		switch (ret) {
		case KRB5_LIBOS_BADPWDMATCH:
		case KRB5KRB_AP_ERR_BAD_INTEGRITY:
			RDEBUG("Provided password was incorrect: %s",
			       error_message(ret));
			rcode = RLM_MODULE_REJECT;
		
			break;
			
		case KRB5KDC_ERR_KEY_EXP:
		case KRB5KDC_ERR_CLIENT_REVOKED:
		case KRB5KDC_ERR_SERVICE_REVOKED:
			RDEBUG("Account has been locked out: %s",
			       error_message(ret));
			rcode = RLM_MODULE_USERLOCK;
		
			break;
			
		case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
			RDEBUG("User not found: %s", error_message(ret));
			rcode = RLM_MODULE_NOTFOUND;
			
		default:
			radlog(L_ERR, "rlm_krb5 (%s): Failed getting/verifying "
			       "credentials: %s", inst->xlat_name,
			       error_message(ret));
			rcode = RLM_MODULE_FAIL;
		
			break;
		}

		goto cleanup;
	}
	
	RDEBUG("Successfully retrieved and decrypted TGT");
	
	memset(&keytab, 0, sizeof(keytab));
	ret = inst->keytabname ? 
		krb5_kt_resolve(*context, inst->keytabname, &keytab) :
		krb5_kt_default(*context, &keytab);
	if (ret) {
		radlog(L_ERR, "rlm_krb5 (%s): Resolving keytab failed: %s",
		       inst->xlat_name, error_message(ret));
		
		goto cleanup;
	}
	
	ret = krb5_verify_init_creds(*context, &init_creds, inst->server,
				     keytab, NULL, inst->vic_options);
	if (ret) goto error;
 
	cleanup:

	krb5_free_cred_contents(*context, &init_creds);
	krb5_free_context(*context);
	krb5_kt_close(*context, keytab);
	
	return rcode;
}