Esempio n. 1
0
int mr_krb5_auth(char *prog)
{
  mr_params params, reply;
  char host[BUFSIZ], *p;
  char *args[2];
  int argl[2];
  krb5_ccache ccache = NULL;
  krb5_data auth;
  krb5_error_code problem = 0;

  CHECK_CONNECTED;

  memset(&auth, 0, sizeof(auth));

  if ((problem = mr_host(host, sizeof(host) - 1)))
    return problem;

  if (!context)
    {
      problem = krb5_init_context(&context);
      if (problem)
	goto out;
    }

  problem = krb5_auth_con_init(context, &auth_con);
  if (problem)
    goto out;

  problem = krb5_cc_default(context, &ccache);
  if (problem)
    goto out;

  problem = krb5_mk_req(context, &auth_con, 0, MOIRA_SNAME, host, NULL, 
		       ccache, &auth);
  if (problem)
    goto out;

  params.u.mr_procno = MR_KRB5_AUTH;
  params.mr_argc = 2;
  params.mr_argv = args;
  params.mr_argl = argl;
  params.mr_argv[0] = (char *)auth.data;
  params.mr_argl[0] = auth.length;
  params.mr_argv[1] = prog;
  params.mr_argl[1] = strlen(prog) + 1;

  if ((problem = mr_do_call(&params, &reply)) == MR_SUCCESS)
    problem = reply.u.mr_status;

  mr_destroy_reply(reply);

 out:
  if (ccache)
    krb5_cc_close(context, ccache);
  krb5_free_data_contents(context, &auth);
  if (auth_con)
    krb5_auth_con_free(context, auth_con);
  auth_con = NULL;

  return problem;
}
Esempio n. 2
0
int
main (int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache  ccache;
    krb5_principal principal;
    int optidx = 0;
    krb5_deltat ticket_life = 0;
    int parseflags = 0;

    setprogname (argv[0]);

    setlocale (LC_ALL, "");
    bindtextdomain ("heimdal_kuser", HEIMDAL_LOCALEDIR);
    textdomain("heimdal_kuser");

    ret = krb5_init_context (&context);
    if (ret == KRB5_CONFIG_BADFORMAT)
	errx (1, "krb5_init_context failed to parse configuration file");
    else if (ret)
	errx(1, "krb5_init_context failed: %d", ret);

    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 (canonicalize_flag || enterprise_flag)
	parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;

    if (pk_enterprise_flag) {
	ret = krb5_pk_enterprise_cert(context, pk_user_id,
				      argv[0], &principal,
				      &ent_user_id);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");

	pk_user_id = NULL;

    } else if (anonymous_flag) {

	ret = krb5_make_principal(context, &principal, argv[0],
				  KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME,
				  NULL);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_make_principal");
	krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);

    } else {
	if (argv[0]) {
	    ret = krb5_parse_name_flags (context, argv[0], parseflags,
					 &principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_parse_name");
	} else {
	    ret = krb5_get_default_principal (context, &principal);
	    if (ret)
		krb5_err (context, 1, ret, "krb5_get_default_principal");
	}
    }

    if(fcache_version)
	krb5_set_fcache_version(context, fcache_version);

    if(renewable_flag == -1)
	/* this seems somewhat pointless, but whatever */
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"renewable", FALSE, &renewable_flag);
    if(do_afslog == -1)
	krb5_appdefault_boolean(context, "kinit",
				krb5_principal_get_realm(context, principal),
				"afslog", TRUE, &do_afslog);

    if(cred_cache)
	ret = krb5_cc_resolve(context, cred_cache, &ccache);
    else {
	if(argc > 1) {
	    char s[1024];
	    ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
	    if(ret)
		krb5_err(context, 1, ret, "creating cred cache");
	    snprintf(s, sizeof(s), "%s:%s",
		     krb5_cc_get_type(context, ccache),
		     krb5_cc_get_name(context, ccache));
	    setenv("KRB5CCNAME", s, 1);
	} else {
	    ret = krb5_cc_cache_match(context, principal, &ccache);
	    if (ret) {
		const char *type;
		ret = krb5_cc_default (context, &ccache);
		if (ret)
		    krb5_err (context, 1, ret, N_("resolving credentials cache", ""));

		/*
		 * Check if the type support switching, and we do,
		 * then do that instead over overwriting the current
		 * default credential
		 */
		type = krb5_cc_get_type(context, ccache);
		if (krb5_cc_support_switch(context, type)) {
		    krb5_cc_close(context, ccache);
		    ret = krb5_cc_new_unique(context, type, NULL, &ccache);
		}
	    }
	}
    }
    if (ret)
	krb5_err (context, 1, ret, N_("resolving credentials cache", ""));

#ifndef NO_AFS
    if(argc > 1 && k_hasafs ())
	k_setpag();
#endif

    if (lifetime) {
	int tmp = parse_time (lifetime, "s");
	if (tmp < 0)
	    errx (1, N_("unparsable time: %s", ""), lifetime);

	ticket_life = tmp;
    }

    if(addrs_flag == 0 && extra_addresses.num_strings > 0)
	krb5_errx(context, 1,
		  N_("specifying both extra addresses and "
		     "no addresses makes no sense", ""));
    {
	int i;
	krb5_addresses addresses;
	memset(&addresses, 0, sizeof(addresses));
	for(i = 0; i < extra_addresses.num_strings; i++) {
	    ret = krb5_parse_address(context, extra_addresses.strings[i],
				     &addresses);
	    if (ret == 0) {
		krb5_add_extra_addresses(context, &addresses);
		krb5_free_addresses(context, &addresses);
	    }
	}
	free_getarg_strings(&extra_addresses);
    }

    if(renew_flag || validate_flag) {
	ret = renew_validate(context, renew_flag, validate_flag,
			     ccache, server_str, ticket_life);
	exit(ret != 0);
    }

    get_new_tickets(context, principal, ccache, ticket_life, 1);

#ifndef NO_AFS
    if(do_afslog && k_hasafs())
	krb5_afslog(context, ccache, NULL, NULL);
#endif
    if(argc > 1) {
	struct renew_ctx ctx;
	time_t timeout;

	timeout = ticket_lifetime(context, ccache, principal, server_str) / 2;

	ctx.context = context;
	ctx.ccache = ccache;
	ctx.principal = principal;
	ctx.ticket_life = ticket_life;

	ret = simple_execvp_timed(argv[1], argv+1,
				  renew_func, &ctx, timeout);
#define EX_NOEXEC	126
#define EX_NOTFOUND	127
	if(ret == EX_NOEXEC)
	    krb5_warnx(context, N_("permission denied: %s", ""), argv[1]);
	else if(ret == EX_NOTFOUND)
	    krb5_warnx(context, N_("command not found: %s", ""), argv[1]);

	krb5_cc_destroy(context, ccache);
#ifndef NO_AFS
	if(k_hasafs())
	    k_unlog();
#endif
    } else {
	krb5_cc_close (context, ccache);
	ret = 0;
    }
    krb5_free_principal(context, principal);
    krb5_free_context (context);
    return ret;
}
krb5_error_code
_kadm5_c_get_cache_principal(krb5_context context,
			     krb5_ccache *id,
			     krb5_principal *client)
{
    krb5_error_code ret;
    const char *name, *inst;
    krb5_principal p1, p2;

    ret = krb5_cc_default(context, id);
    if(ret) {
	*id = NULL;
	return ret;
    }

    ret = krb5_cc_get_principal(context, *id, &p1);
    if(ret) {
	krb5_cc_close(context, *id);
	*id = NULL;
	return ret;
    }

    ret = krb5_make_principal(context, &p2, NULL,
			      "kadmin", "admin", NULL);
    if (ret) {
	krb5_cc_close(context, *id);
	*id = NULL;
	krb5_free_principal(context, p1);
	return ret;
    }

    {
	krb5_creds in, *out;
	krb5_kdc_flags flags;

	flags.i = 0;
	memset(&in, 0, sizeof(in));

	in.client = p1;
	in.server = p2;

	/* check for initial ticket kadmin/admin */
	ret = krb5_get_credentials_with_flags(context, KRB5_GC_CACHED, flags,
					      *id, &in, &out);
	krb5_free_principal(context, p2);
	if (ret == 0) {
	    if (out->flags.b.initial) {
		*client = p1;
		krb5_free_creds(context, out);
		return 0;
	    }
	    krb5_free_creds(context, out);
	}
    }
    krb5_cc_close(context, *id);
    *id = NULL;

    name = krb5_principal_get_comp_string(context, p1, 0);
    inst = krb5_principal_get_comp_string(context, p1, 1);
    if(inst == NULL || strcmp(inst, "admin") != 0) {
	ret = krb5_make_principal(context, &p2, NULL, name, "admin", NULL);
	krb5_free_principal(context, p1);
	if(ret != 0)
	    return ret;

	*client = p2;
	return 0;
    }

    *client = p1;

    return 0;
}
Esempio n. 4
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache cache;
    krb5_creds *out;
    int optidx = 0;
    krb5_get_creds_opt opt;
    krb5_principal server;
    krb5_principal impersonate = NULL;

    setprogname (argv[0]);

    ret = krb5_init_context (&context);
    if (ret)
	errx(1, "krb5_init_context failed: %d", ret);
  
    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 != 1)
	usage (1);

    if(cache_str) {
	ret = krb5_cc_resolve(context, cache_str, &cache);
	if (ret)
	    krb5_err (context, 1, ret, "%s", cache_str);
    } else {
	ret = krb5_cc_default (context, &cache);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");
    }

    ret = krb5_get_creds_opt_alloc(context, &opt);
    if (ret)
	krb5_err (context, 1, ret, "krb5_get_creds_opt_alloc");

    if (etype_str) {
	krb5_enctype enctype;

	ret = krb5_string_to_enctype(context, etype_str, &enctype);
	if (ret)
	    krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
	krb5_get_creds_opt_set_enctype(context, opt, enctype);
    }

    if (impersonate_str) {
	ret = krb5_parse_name(context, impersonate_str, &impersonate);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_parse_name %s", impersonate_str);
	krb5_get_creds_opt_set_impersonate(context, opt, impersonate);
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE);
    }

    if (out_cache_str)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE);

    if (forwardable_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_FORWARDABLE);
    if (!transit_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_TRANSIT_CHECK);

    if (delegation_cred_str) {
	krb5_ccache id;
	krb5_creds c, mc;
	Ticket ticket;

	krb5_cc_clear_mcred(&mc);
	ret = krb5_cc_get_principal(context, cache, &mc.server);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_get_principal");

	ret = krb5_cc_resolve(context, delegation_cred_str, &id);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");

	ret = krb5_cc_retrieve_cred(context, id, 0, &mc, &c);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");

	ret = decode_Ticket(c.ticket.data, c.ticket.length, &ticket, NULL);
	if (ret) {
	    krb5_clear_error_string(context);
	    krb5_err (context, 1, ret, "decode_Ticket");
	}
	krb5_free_cred_contents(context, &c);

	ret = krb5_get_creds_opt_set_ticket(context, opt, &ticket);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_get_creds_opt_set_ticket");
	free_Ticket(&ticket);

	krb5_cc_close (context, id);
	krb5_free_principal(context, mc.server);

	krb5_get_creds_opt_add_options(context, opt, 
				       KRB5_GC_CONSTRAINED_DELEGATION);
    }

    ret = krb5_parse_name(context, argv[0], &server);
    if (ret)
	krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);

    if (nametype_str) {
	ret = krb5_parse_nametype(context, nametype_str,
				  &server->name.name_type);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_parse_nametype");
    }

    ret = krb5_get_creds(context, opt, cache, server, &out);
    if (ret)
	krb5_err (context, 1, ret, "krb5_get_creds");

    if (out_cache_str) {
	krb5_ccache id;

	ret = krb5_cc_resolve(context, out_cache_str, &id);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");

	ret = krb5_cc_initialize(context, id, out->client);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_cc_initialize");

	ret = krb5_cc_store_cred(context, id, out);
	if(ret)
	    krb5_err (context, 1, ret, "krb5_cc_store_cred");
	krb5_cc_close (context, id);
    }

    krb5_free_creds(context, out);
    krb5_free_principal(context, server);
    krb5_get_creds_opt_free(context, opt);
    krb5_cc_close (context, cache);
    krb5_free_context (context);

    return 0;
}
Esempio n. 5
0
static int
create_krb5_cred(krb5_context ctx, char *realm, char *user, char *password,
                 char *ktname, krb5_ccache *ccache, gss_cred_id_t *gsscred,
                 char **errmsg) {
    int rc = 0, len = 0;
    unsigned int minor_stat = 0, major_stat = 0;
    const char *errmsg_tmp = NULL;
    const char *cctype = NULL;
    char *cname = NULL;
    krb5_ccache defcc = NULL;
    krb5_creds creds;
    krb5_principal princ = NULL;
    krb5_keytab keytab = NULL;
    gss_key_value_element_desc elems[2];
    gss_key_value_set_desc store;
    gss_name_t sname = NULL;
    gss_buffer_desc pr_name;

    pr_name.value = NULL;
    pr_name.length = 0;

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

    if (user == NULL || realm == NULL) return 1;
    len = strlen(realm);

    if (len == 0 || strlen(user) == 0) return 0;

    DEBUG("create_krb5_cred (ctx:%p, realm:%s, user:%s, password:%s, ktname: %s,"
        " ccache:%p, gsscred:%p)", ctx, realm, user, "****", ktname, ccache, gsscred);

    rc = krb5_cc_default(ctx, &defcc);
    if (rc != 0) goto end;

    cctype = krb5_cc_get_type(ctx, defcc);

    rc = krb5_cc_new_unique(ctx, cctype, NULL, ccache);
    if (rc != 0) goto end;

    rc = krb5_build_principal(ctx, &princ, len, realm, user, NULL);
    if (rc != 0) goto end;

    rc = krb5_cc_initialize(ctx, *ccache, princ);
    if (rc != 0) goto end;

    if (password != NULL && strlen(password) > 0) {
        rc = krb5_get_init_creds_password(ctx, &creds, princ, password,
                                          0, NULL, 0, NULL, NULL);
        if (rc != 0) goto end;

        rc = krb5_cc_store_cred(ctx, *ccache, &creds);
        if (rc != 0) goto end;

        rc = krb5_cc_get_full_name(ctx, *ccache, &cname);
        if (rc != 0) goto end;
        
        store.elements[store.count].key = "ccache";
        store.elements[store.count].value = cname;
        store.count++;
    }

    if (ktname != NULL && strlen(ktname) > 0) {
        rc = krb5_kt_resolve(ctx, ktname, &keytab);
        if (rc != 0) goto end;

        rc = krb5_get_init_creds_keytab(ctx, &creds, princ, keytab, 0, NULL, NULL);
        if (rc != 0) goto end;
        
        rc = krb5_cc_store_cred(ctx, *ccache, &creds);
        if (rc != 0) goto end;

        rc = krb5_cc_get_full_name(ctx, *ccache, &cname);
        if (rc != 0) goto end;

        store.elements[store.count].key = "client_keytab";
        store.elements[store.count].value = ktname;
        store.count++;

        store.elements[store.count].key = "ccache";
        store.elements[store.count].value = cname;
        store.count++;

        rc = krb5_unparse_name(ctx, princ, (char**)&pr_name.value);
        if (rc != 0) goto end;
        pr_name.length = strlen(pr_name.value);

        major_stat = gss_import_name(&minor_stat, &pr_name,
                                     GSS_KRB5_NT_PRINCIPAL_NAME, &sname);
        if (major_stat != 0) goto end;
    }

    // Does not work with GSS-SPENGO.
    //major_stat = gss_krb5_import_cred(&minor_stat, *ccache, princ, NULL, gsscred);
    major_stat = gss_acquire_cred_from(&minor_stat, sname, 0, GSS_C_NO_OID_SET,
                                       GSS_C_INITIATE, &store, gsscred,
                                       NULL, NULL);

end:
    if (keytab != NULL) krb5_kt_close(ctx, keytab);
    if (princ != NULL) krb5_free_principal(ctx, princ);
    if (defcc != NULL) krb5_cc_close(ctx, defcc);
    if (cname != NULL) free(cname);
    if (pr_name.value != NULL) krb5_free_unparsed_name(ctx, pr_name.value);
    if (sname != NULL) {
        major_stat = gss_release_name(&minor_stat, &sname);
    }

    if (rc != 0) {
        /* Create error message with the error code. */
        errmsg_tmp = krb5_get_error_message(ctx, rc);
        if (errmsg != NULL && errmsg_tmp != NULL) {
            len = strlen(errmsg_tmp) + 26;
            *errmsg = (char *)malloc(len);
            if (*errmsg == NULL) {
                krb5_free_error_message(ctx, errmsg_tmp);
                return -1;
            }
            snprintf(*errmsg, len,"%s. (KRB5_ERROR 0x%08x)", errmsg_tmp, rc);
        }
        krb5_free_error_message(ctx, errmsg_tmp);
    }
    if (major_stat != 0) return major_stat;
    return rc;
}
Esempio n. 6
0
krb5_error_code
_kadm5_c_get_cred_cache(krb5_context context,
			const char *client_name,
			const char *server_name,
			const char *password,
			krb5_prompter_fct prompter,
			const char *keytab,
			krb5_ccache ccache,
			krb5_ccache *ret_cache)
{
    krb5_error_code ret;
    krb5_ccache id = NULL;
    krb5_principal default_client = NULL, client = NULL;
    
    /* treat empty password as NULL */
    if(password && *password == '\0')
	password = NULL;
    if(server_name == NULL)
	server_name = KADM5_ADMIN_SERVICE;
    
    if(client_name != NULL) {
	ret = krb5_parse_name(context, client_name, &client);
	if(ret) 
	    return ret;
    }

    if(password != NULL || prompter != NULL) {
	/* get principal from default cache, ok if this doesn't work */
	ret = krb5_cc_default(context, &id);
	if(ret == 0) {
	    ret = krb5_cc_get_principal(context, id, &default_client);
	    if(ret) {
		krb5_cc_close(context, id);
		id = NULL;
	    } else {
		const char *name, *inst;
		krb5_principal tmp;
		name = krb5_principal_get_comp_string(context, 
						      default_client, 0);
		inst = krb5_principal_get_comp_string(context, 
						      default_client, 1);
		if(inst == NULL || strcmp(inst, "admin") != 0) {
		    ret = krb5_make_principal(context, &tmp, NULL, 
					      name, "admin", NULL);
		    if(ret != 0) {
			krb5_free_principal(context, default_client);
			if (client)
			    krb5_free_principal(context, client);
			krb5_cc_close(context, id);
			return ret;
		    }
		    krb5_free_principal(context, default_client);
		    default_client = tmp;
		    krb5_cc_close(context, id);
		    id = NULL;
		}
	    }
	}

	if (client != NULL) {
	    /* A client was specified by the caller. */
	    if (default_client != NULL) {
		krb5_free_principal(context, default_client);
		default_client = NULL;
	    }
	}
	else if (default_client != NULL)
	    /* No client was specified by the caller, but we have a
	     * client from the default credentials cache.
	     */
	    client = default_client;
	else {
	    /* No client was specified by the caller and we cannot determine
	     * the client from a credentials cache.
	     */
	    const char *user;

	    user = get_default_username ();

	    if(user == NULL)
		return KADM5_FAILURE;
	    ret = krb5_make_principal(context, &client, 
				      NULL, user, "admin", NULL);
	    if(ret)
		return ret;
	    if (id != NULL) {
		krb5_cc_close(context, id);
		id = NULL;
	    }
	}
    } else if(ccache != NULL) {
	id = ccache;
	ret = krb5_cc_get_principal(context, id, &client);
	if(ret)
	    return ret;
    }

    
    if(id && (default_client == NULL || 
	      krb5_principal_compare(context, client, default_client))) {
	ret = get_kadm_ticket(context, id, client, server_name);
	if(ret == 0) {
	    *ret_cache = id;
	    krb5_free_principal(context, default_client);
	    if (default_client != client)
		krb5_free_principal(context, client);
	    return 0;
	}
	if(ccache != NULL)
	    /* couldn't get ticket from cache */
	    return -1;
    }
    /* get creds via AS request */
    if(id && (id != ccache))
	krb5_cc_close(context, id);
    if (client != default_client)
	krb5_free_principal(context, default_client);

    ret = get_new_cache(context, client, password, prompter, keytab, 
			server_name, ret_cache);
    krb5_free_principal(context, client);
    return ret;
}
Esempio n. 7
0
static int
proto (int sock, const char *service)
{
    struct sockaddr_storage remote, local;
    socklen_t addrlen;
    krb5_address remote_addr, local_addr;
    krb5_ccache ccache;
    krb5_auth_context auth_context;
    krb5_error_code status;
    krb5_data packet;
    krb5_data data;
    krb5_data client_name;
    krb5_creds in_creds, *out_creds;

    addrlen = sizeof(local);
    if (getsockname (sock, (struct sockaddr *)&local, &addrlen) < 0
	|| addrlen > sizeof(local))
	err (1, "getsockname)");

    addrlen = sizeof(remote);
    if (getpeername (sock, (struct sockaddr *)&remote, &addrlen) < 0
	|| addrlen > sizeof(remote))
	err (1, "getpeername");

    status = krb5_auth_con_init (context, &auth_context);
    if (status)
	krb5_err(context, 1, status, "krb5_auth_con_init");

    status = krb5_sockaddr2address (context, (struct sockaddr *)&local, &local_addr);
    if (status)
	krb5_err(context, 1, status, "krb5_sockaddr2address(local)");
    status = krb5_sockaddr2address (context, (struct sockaddr *)&remote, &remote_addr);
    if (status)
	krb5_err(context, 1, status, "krb5_sockaddr2address(remote)");

    status = krb5_auth_con_setaddrs (context,
				     auth_context,
				     &local_addr,
				     &remote_addr);
    if (status)
	krb5_err(context, 1, status, "krb5_auth_con_setaddr");

    status = krb5_read_message(context, &sock, &client_name);
    if(status)
	krb5_err(context, 1, status, "krb5_read_message");

    memset(&in_creds, 0, sizeof(in_creds));
    status = krb5_cc_default(context, &ccache);
    if(status)
	krb5_err(context, 1, status, "krb5_cc_default");
    status = krb5_cc_get_principal(context, ccache, &in_creds.client);
    if(status)
	krb5_err(context, 1, status, "krb5_cc_get_principal");

    status = krb5_read_message(context, &sock, &in_creds.second_ticket);
    if(status)
	krb5_err(context, 1, status, "krb5_read_message");

    status = krb5_parse_name(context, client_name.data, &in_creds.server);
    if(status)
	krb5_err(context, 1, status, "krb5_parse_name");

    status = krb5_get_credentials(context, KRB5_GC_USER_USER, ccache,
				  &in_creds, &out_creds);
    if(status)
	krb5_err(context, 1, status, "krb5_get_credentials");

    status = krb5_cc_default(context, &ccache);
    if(status)
	krb5_err(context, 1, status, "krb5_cc_default");

    status = krb5_sendauth(context,
			   &auth_context,
			   &sock,
			   VERSION,
			   in_creds.client,
			   in_creds.server,
			   AP_OPTS_USE_SESSION_KEY,
			   NULL,
			   out_creds,
			   ccache,
			   NULL,
			   NULL,
			   NULL);

    if (status)
	krb5_err(context, 1, status, "krb5_sendauth");

    {
	char *str;
	krb5_unparse_name(context, in_creds.server, &str);
	printf ("User is `%s'\n", str);
	free(str);
	krb5_unparse_name(context, in_creds.client, &str);
	printf ("Server is `%s'\n", str);
	free(str);
    }

    krb5_data_zero (&data);
    krb5_data_zero (&packet);

    status = krb5_read_message(context, &sock, &packet);
    if(status)
	krb5_err(context, 1, status, "krb5_read_message");

    status = krb5_rd_safe (context,
			   auth_context,
			   &packet,
			   &data,
			   NULL);
    if (status)
	krb5_err(context, 1, status, "krb5_rd_safe");

    printf ("safe packet: %.*s\n", (int)data.length,
	    (char *)data.data);

    status = krb5_read_message(context, &sock, &packet);
    if(status)
	krb5_err(context, 1, status, "krb5_read_message");

    status = krb5_rd_priv (context,
			   auth_context,
			   &packet,
			   &data,
			   NULL);
    if (status)
	krb5_err(context, 1, status, "krb5_rd_priv");

    printf ("priv packet: %.*s\n", (int)data.length,
	    (char *)data.data);

    return 0;
}
Esempio n. 8
0
int
main(int argc, char **argv)
{
    krb5_context ctx;
    krb5_ccache in_ccache, out_ccache, armor_ccache;
    krb5_get_init_creds_opt *opt;
    char *user, *password, *armor_ccname = NULL, *in_ccname = NULL, *perr;
    const char *err;
    krb5_principal client;
    krb5_creds creds;
    krb5_flags fast_flags;
    krb5_error_code ret;
    int c;

    while ((c = getopt(argc, argv, "I:A:")) != -1) {
        switch (c) {
        case 'A':
            armor_ccname = optarg;
            break;
        case 'I':
            in_ccname = optarg;
            break;
        }
    }
    if (argc - optind < 2) {
        fprintf(stderr, "Usage: %s [-A armor_ccache] [-I in_ccache] "
                "username password\n", argv[0]);
        return 1;
    }
    user = argv[optind];
    password = argv[optind + 1];

    bail_on_err(NULL, "Error initializing Kerberos", krb5_init_context(&ctx));
    bail_on_err(ctx, "Error allocating space for get_init_creds options",
                krb5_get_init_creds_opt_alloc(ctx, &opt));
    if (in_ccname != NULL) {
        bail_on_err(ctx, "Error resolving input ccache",
                    krb5_cc_resolve(ctx, in_ccname, &in_ccache));
        bail_on_err(ctx, "Error setting input_ccache option",
                    krb5_get_init_creds_opt_set_in_ccache(ctx, opt,
                                                          in_ccache));
    } else {
        in_ccache = NULL;
    }
    if (armor_ccname != NULL) {
        bail_on_err(ctx, "Error resolving armor ccache",
                    krb5_cc_resolve(ctx, armor_ccname, &armor_ccache));
        bail_on_err(ctx, "Error setting fast_ccache option",
                    krb5_get_init_creds_opt_set_fast_ccache(ctx, opt,
                                                            armor_ccache));
        fast_flags = KRB5_FAST_REQUIRED;
        bail_on_err(ctx, "Error setting option to force use of FAST",
                    krb5_get_init_creds_opt_set_fast_flags(ctx, opt,
                                                           fast_flags));
    } else {
        armor_ccache = NULL;
    }
    bail_on_err(ctx, "Error resolving output (default) ccache",
                krb5_cc_default(ctx, &out_ccache));
    bail_on_err(ctx, "Error setting output ccache option",
                krb5_get_init_creds_opt_set_out_ccache(ctx, opt, out_ccache));
    if (asprintf(&perr, "Error parsing principal name \"%s\"", user) < 0)
        abort();
    bail_on_err(ctx, perr, krb5_parse_name(ctx, user, &client));
    ret = krb5_get_init_creds_password(ctx, &creds, client, password,
                                       prompter_cb, NULL, 0, NULL, opt);
    if (ret) {
        err = krb5_get_error_message(ctx, ret);
        printf("%s\n", err);
        krb5_free_error_message(ctx, err);
    } else {
        krb5_free_cred_contents(ctx, &creds);
    }
    krb5_get_init_creds_opt_free(ctx, opt);
    krb5_free_principal(ctx, client);
    krb5_cc_close(ctx, out_ccache);
    if (armor_ccache != NULL)
        krb5_cc_close(ctx, armor_ccache);
    if (in_ccache != NULL)
        krb5_cc_close(ctx, in_ccache);
    krb5_free_context(ctx);
    free(perr);
    return ret ? (ret - KRB5KDC_ERR_NONE) : 0;
}
Esempio n. 9
0
_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, 
					struct loadparm_context *lp_ctx,
					const char *name,
					enum credentials_obtained obtained,
					const char **error_string)
{
	krb5_error_code ret;
	krb5_principal princ;
	struct ccache_container *ccc;
	if (cred->ccache_obtained > obtained) {
		return 0;
	}

	ccc = talloc(cred, struct ccache_container);
	if (!ccc) {
		(*error_string) = error_message(ENOMEM);
		return ENOMEM;
	}

	ret = cli_credentials_get_krb5_context(cred, lp_ctx,
					       &ccc->smb_krb5_context);
	if (ret) {
		(*error_string) = error_message(ret);
		talloc_free(ccc);
		return ret;
	}
	if (!talloc_reference(ccc, ccc->smb_krb5_context)) {
		talloc_free(ccc);
		(*error_string) = error_message(ENOMEM);
		return ENOMEM;
	}

	if (name) {
		ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache);
		if (ret) {
			(*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n",
							  name,
							  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
										     ret, ccc));
			talloc_free(ccc);
			return ret;
		}
	} else {
		ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache);
		if (ret) {
			(*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n",
							  smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context,
										     ret, ccc));
			talloc_free(ccc);
			return ret;
		}
	}

	talloc_set_destructor(ccc, free_dccache);

	ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ);

	if (ret == 0) {
		krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ);
		ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string);

		if (ret) {
			(*error_string) = error_message(ret);
			return ret;
		}

		cred->ccache = ccc;
		cred->ccache_obtained = obtained;
		talloc_steal(cred, ccc);

		cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained);
		return 0;
	}
	return 0;
}
Esempio n. 10
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;
}
Esempio n. 11
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache src_cc = NULL;
    krb5_ccache dst_cc = NULL;
    krb5_cc_cursor cursor;
    krb5_principal me = NULL;
    krb5_creds cred;
    const char *during;
    Ticket t;
    size_t len;
    int make_kvno_absent = 0;
    int opt;

    memset(&cred, 0, sizeof (cred));
    during = "init_context";
    ret = krb5_init_context(&context);
    if (ret) goto err;

    while ((opt = getopt(argc, argv, "c:n")) != -1) {
	switch (opt) {
	case 'c':
	    during = "cc_resolve of source ccache";
	    ret = krb5_cc_resolve(context, optarg, &src_cc);
	    if (ret) goto err;
	    break;
	case 'n':
	    make_kvno_absent++;
	    break;
	case 'h':
	default:
	    fprintf(stderr, "Usage: %s [-n] [-c ccache]\n"
		    "\tThis utility edits a ccache, setting all ticket\n"
		    "\tenc_part kvnos to zero or absent (if -n is set).\n",
		    argv[0]);
	    return 1;
	}
    }

    if (!src_cc) {
	during = "cc_default";
	ret = krb5_cc_default(context, &src_cc);
	if (ret) goto err;
    }

    during = "cc_get_principal";
    ret = krb5_cc_get_principal(context, src_cc, &me);
    if (ret) goto err;

    if (optind != argc) {
	fprintf(stderr, "Usage: %s [-n] [-c ccache]\n"
		"\tThis utility edits a ccache, setting all ticket\n"
		"\tenc_part kvnos to zero or absent (if -n is set).\n",
		argv[0]);
	return 1;
    }

    during = "cc_new_unique of temporary ccache";
    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, src_cc),
			     NULL, &dst_cc);

    during = "cc_initialize of temporary ccache";
    ret = krb5_cc_initialize(context, dst_cc, me);
    if (ret) goto err;

    during = "cc_start_seq_get";
    ret = krb5_cc_start_seq_get(context, src_cc, &cursor);
    if (ret) goto err;

    while ((ret = krb5_cc_next_cred(context, src_cc, &cursor, &cred)) == 0) {
	krb5_data data;

	during = "decode_Ticket";
	memset(&t, 0, sizeof (t));
	ret = decode_Ticket(cred.ticket.data, cred.ticket.length, &t, &len);
	if (ret == ASN1_MISSING_FIELD)
	    continue;
	if (ret) goto err;
	if (t.enc_part.kvno) {
	    *t.enc_part.kvno = 0;
	    if (make_kvno_absent) {
		free(t.enc_part.kvno);
		t.enc_part.kvno = NULL;
	    }
	    /*
	     * The new Ticket has to need less or same space as before, so
	     * we reuse cred->icket.data.
	     */
	    during = "encode_Ticket";
	    ASN1_MALLOC_ENCODE(Ticket, data.data, data.length, &t, &len, ret);
	    if (ret) {
		free_Ticket(&t);
		goto err;
	    }
	    krb5_data_free(&cred.ticket);
	    cred.ticket = data;
	}
	free_Ticket(&t);
	during = "cc_store_cred";
	ret = krb5_cc_store_cred(context, dst_cc, &cred);
	if (ret) goto err;
	krb5_free_cred_contents(context, &cred);
	memset(&cred, 0, sizeof (cred));
    }
    during = "cc_next_cred";
    if (ret != KRB5_CC_END) goto err;

    during = "cc_end_seq_get";
    ret = krb5_cc_end_seq_get(context, src_cc, &cursor);
    if (ret) goto err;

    during = "cc_move";
    ret = krb5_cc_move(context, dst_cc, src_cc);
    if (ret) goto err;
    dst_cc = NULL;

    during = "cc_switch";
    ret = krb5_cc_switch(context, src_cc);
    if (ret) goto err;

err:
    (void) krb5_free_principal(context, me);
    if (src_cc)
	(void) krb5_cc_close(context, src_cc);
    if (dst_cc)
	(void) krb5_cc_destroy(context, dst_cc);
    if (ret) {
	fprintf(stderr, "Failed while doing %s (%d)\n", during, ret);
	ret = 1;
    }
    return (ret);
}
Esempio n. 12
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_sendauth(krb5_context context,
              krb5_auth_context *auth_context,
              krb5_pointer p_fd,
              const char *appl_version,
              krb5_principal client,
              krb5_principal server,
              krb5_flags ap_req_options,
              krb5_data *in_data,
              krb5_creds *in_creds,
              krb5_ccache ccache,
              krb5_error **ret_error,
              krb5_ap_rep_enc_part **rep_result,
              krb5_creds **out_creds)
{
    krb5_error_code ret;
    uint32_t len, net_len;
    const char *version = KRB5_SENDAUTH_VERSION;
    u_char repl;
    krb5_data ap_req, error_data;
    krb5_creds this_cred;
    krb5_principal this_client = NULL;
    krb5_creds *creds;
    ssize_t sret;
    krb5_boolean my_ccache = FALSE;

    len = strlen(version) + 1;
    net_len = htonl(len);
    if (krb5_net_write (context, p_fd, &net_len, 4) != 4
            || krb5_net_write (context, p_fd, version, len) != len) {
        ret = errno;
        krb5_set_error_message (context, ret, "write: %s", strerror(ret));
        return ret;
    }

    len = strlen(appl_version) + 1;
    net_len = htonl(len);
    if (krb5_net_write (context, p_fd, &net_len, 4) != 4
            || krb5_net_write (context, p_fd, appl_version, len) != len) {
        ret = errno;
        krb5_set_error_message (context, ret, "write: %s", strerror(ret));
        return ret;
    }

    sret = krb5_net_read (context, p_fd, &repl, sizeof(repl));
    if (sret < 0) {
        ret = errno;
        krb5_set_error_message (context, ret, "read: %s", strerror(ret));
        return ret;
    } else if (sret != sizeof(repl)) {
        krb5_clear_error_message (context);
        return KRB5_SENDAUTH_BADRESPONSE;
    }

    if (repl != 0) {
        krb5_clear_error_message (context);
        return KRB5_SENDAUTH_REJECTED;
    }

    if (in_creds == NULL) {
        if (ccache == NULL) {
            ret = krb5_cc_default (context, &ccache);
            if (ret)
                return ret;
            my_ccache = TRUE;
        }

        if (client == NULL) {
            ret = krb5_cc_get_principal (context, ccache, &this_client);
            if (ret) {
                if(my_ccache)
                    krb5_cc_close(context, ccache);
                return ret;
            }
            client = this_client;
        }
        memset(&this_cred, 0, sizeof(this_cred));
        this_cred.client = client;
        this_cred.server = server;
        this_cred.times.endtime = 0;
        this_cred.ticket.length = 0;
        in_creds = &this_cred;
    }
    if (in_creds->ticket.length == 0) {
        ret = krb5_get_credentials (context, 0, ccache, in_creds, &creds);
        if (ret) {
            if(my_ccache)
                krb5_cc_close(context, ccache);
            return ret;
        }
    } else {
        creds = in_creds;
    }
    if(my_ccache)
        krb5_cc_close(context, ccache);
    ret = krb5_mk_req_extended (context,
                                auth_context,
                                ap_req_options,
                                in_data,
                                creds,
                                &ap_req);

    if (out_creds)
        *out_creds = creds;
    else
        krb5_free_creds(context, creds);
    if(this_client)
        krb5_free_principal(context, this_client);

    if (ret)
        return ret;

    ret = krb5_write_message (context,
                              p_fd,
                              &ap_req);
    if (ret)
        return ret;

    krb5_data_free (&ap_req);

    ret = krb5_read_message (context, p_fd, &error_data);
    if (ret)
        return ret;

    if (error_data.length != 0) {
        KRB_ERROR error;

        ret = krb5_rd_error (context, &error_data, &error);
        krb5_data_free (&error_data);
        if (ret == 0) {
            ret = krb5_error_from_rd_error(context, &error, NULL);
            if (ret_error != NULL) {
                *ret_error = malloc (sizeof(krb5_error));
                if (*ret_error == NULL) {
                    krb5_free_error_contents (context, &error);
                } else {
                    **ret_error = error;
                }
            } else {
                krb5_free_error_contents (context, &error);
            }
            return ret;
        } else {
            krb5_clear_error_message(context);
            return ret;
        }
    } else
        krb5_data_free (&error_data);

    if (ap_req_options & AP_OPTS_MUTUAL_REQUIRED) {
        krb5_data ap_rep;
        krb5_ap_rep_enc_part *ignore = NULL;

        krb5_data_zero (&ap_rep);
        ret = krb5_read_message (context,
                                 p_fd,
                                 &ap_rep);
        if (ret)
            return ret;

        ret = krb5_rd_rep (context, *auth_context, &ap_rep,
                           rep_result ? rep_result : &ignore);
        krb5_data_free (&ap_rep);
        if (ret)
            return ret;
        if (rep_result == NULL)
            krb5_free_ap_rep_enc_part (context, ignore);
    }
    return 0;
}
Esempio n. 13
0
void
kerberos5_forward (TN_Authenticator * ap)
{
  krb5_error_code r;
  krb5_ccache ccache;
  krb5_principal client = 0;
  krb5_principal server = 0;
  krb5_data forw_creds;

  forw_creds.data = 0;

  if ((r = krb5_cc_default (telnet_context, &ccache)))
    {
      DEBUG (("Kerberos V5: could not get default ccache - %s\r\n",
	      error_message (r)));
      return;
    }

  for (;;)			/* Fake loop */
    {
      if ((r = krb5_cc_get_principal (telnet_context, ccache, &client)))
	{
	  DEBUG (("Kerberos V5: could not get default principal - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r =
	   krb5_sname_to_principal (telnet_context, RemoteHostName, "host",
				    KRB5_NT_SRV_HST, &server)))
	{
	  DEBUG (("Kerberos V5: could not make server principal - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r = krb5_auth_con_genaddrs (telnet_context, auth_context, net,
				       KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR)))
	{
	  DEBUG (("Kerberos V5: could not gen local full address - %s\r\n",
		  error_message (r)));
	  break;
	}
      if ((r = krb5_fwd_tgt_creds (telnet_context, auth_context, 0, client,
				   server, ccache,
				   forward_flags & OPTS_FORWARDABLE_CREDS,
				   &forw_creds)))
	{
	  DEBUG (("Kerberos V5: error getting forwarded creds - %s\r\n",
		  error_message (r)));
	  break;
	}

      /* Send forwarded credentials */
      if (!Data (ap, KRB_FORWARD, forw_creds.data, forw_creds.length))
	{
	  DEBUG (("Not enough room for authentication data\r\n"));
	}
      else
	{
	  DEBUG (("Forwarded local Kerberos V5 credentials to server\r\n"));
	}
      break;
    }

  if (client)
    krb5_free_principal (telnet_context, client);
  if (server)
    krb5_free_principal (telnet_context, server);
  free (forw_creds.data);
  krb5_cc_close (telnet_context, ccache);
}
Esempio n. 14
0
int
kerberos5_send (TN_Authenticator * ap)
{
  krb5_error_code r;
  krb5_ccache ccache;
  krb5_creds creds;
  krb5_creds *new_creds = 0;
  int ap_opts;
  char type_check[2];
  krb5_data check_data;

  if (!UserNameRequested)
    {
      DEBUG (("telnet: Kerberos V5: no user name supplied\r\n"));
      return 0;
    }

  if ((r = krb5_cc_default (telnet_context, &ccache)))
    {
      DEBUG (("telnet: Kerberos V5: could not get default ccache\r\n"));
      return 0;
    }

  memset (&creds, 0, sizeof (creds));
  if ((r = krb5_sname_to_principal (telnet_context, RemoteHostName,
				    "host", KRB5_NT_SRV_HST, &creds.server)))
    {
      DEBUG (("telnet: Kerberos V5: error while constructing service name: %s\r\n", error_message (r)));
      return 0;
    }

  if (telnet_krb5_realm)
    {
      krb5_data rdata;

      rdata.length = strlen (telnet_krb5_realm);
      rdata.data = malloc (rdata.length + 1);
      assert (rdata.data);
      strcpy (rdata.data, telnet_krb5_realm);
      krb5_princ_set_realm (telnet_context, creds.server, &rdata);
    }

  if ((r = krb5_cc_get_principal (telnet_context, ccache, &creds.client)))
    {
      DEBUG (("telnet: Kerberos V5: failure on principal (%s)\r\n",
	      error_message (r)));
      krb5_free_cred_contents (telnet_context, &creds);
      return 0;
    }

  creds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
  if ((r = krb5_get_credentials (telnet_context, 0,
				 ccache, &creds, &new_creds)))
    {
      DEBUG (("telnet: Kerberos V5: failure on credentials(%s)\r\n",
	      error_message (r)));
      krb5_free_cred_contents (telnet_context, &creds);
      return 0;
    }

  if ((ap->way & AUTH_HOW_MASK) == AUTH_HOW_MUTUAL)
    ap_opts = AP_OPTS_MUTUAL_REQUIRED;
  else
    ap_opts = 0;

# ifdef ENCRYPTION
  ap_opts |= AP_OPTS_USE_SUBKEY;
# endif

  if (auth_context)
    {
      krb5_auth_con_free (telnet_context, auth_context);
      auth_context = 0;
    }

  if ((r = krb5_auth_con_init (telnet_context, &auth_context)))
    {
      DEBUG (("Kerberos V5: failed to init auth_context (%s)\r\n",
	      error_message (r)));
      return 0;
    }

  krb5_auth_con_setflags (telnet_context, auth_context,
			  KRB5_AUTH_CONTEXT_RET_TIME);

  type_check[0] = ap->type;
  type_check[1] = ap->way;
  check_data.magic = KV5M_DATA;
  check_data.length = 2;
  check_data.data = (char *) &type_check;

  r = krb5_mk_req_extended (telnet_context, &auth_context, ap_opts,
			    &check_data, new_creds, &auth);

  encryption_init (new_creds);

  krb5_free_cred_contents (telnet_context, &creds);
  krb5_free_creds (telnet_context, new_creds);
  if (r)
    {
      DEBUG (("telnet: Kerberos V5: mk_req failed (%s)\r\n",
	      error_message (r)));
      return 0;
    }

  if (!auth_sendname (UserNameRequested, strlen (UserNameRequested)))
    {
      DEBUG (("telnet: Not enough room for user name\r\n"));
      return 0;
    }

  if (!Data (ap, KRB_AUTH, auth.data, auth.length))
    {
      DEBUG (("telnet: Not enough room for authentication data\r\n"));
      return 0;
    }

  DEBUG (("telnet: Sent Kerberos V5 credentials to server\r\n"));

  return 1;
}
Esempio n. 15
0
static char *
init_cc_from_keytab(const char *keytab_name, const char *user)
{
	krb5_context context = NULL;
	krb5_error_code ret;
	krb5_creds my_creds;
	krb5_keytab keytab = NULL;
	krb5_principal me = NULL;
	krb5_ccache cc = NULL;
	char *ccname = NULL;

	memset((char *) &my_creds, 0, sizeof(my_creds));

	ret = krb5_init_context(&context);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_init_context: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_kt_resolve(context, keytab_name, &keytab);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_kt_resolve: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_parse_name(context, user, &me);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_parse_name: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_get_init_creds_keytab(context, &my_creds, me,
			keytab, 0, NULL, NULL);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_get_init_creds_keytab: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_cc_default(context, &cc);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_cc_default: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_cc_initialize(context, cc, me);
	if (ret) {
		syslog(LOG_DEBUG, "krb5_cc_initialize: %d", (int)ret);
		goto icfk_cleanup;
	}

	ret = krb5_cc_store_cred(context, cc, &my_creds);
	if (ret)
		syslog(LOG_DEBUG, "krb5_cc_store_cred: %d", (int)ret);

	ccname = strdup(krb5_cc_default_name(context));
	if (ccname == NULL)
		syslog(LOG_ERR, "Unable to allocate memory");
icfk_cleanup:
	my_creds.client = 0;
	krb5_free_cred_contents(context, &my_creds);

	if (me)
		krb5_free_principal(context, me);
	if (cc)
		krb5_cc_close(context, cc);
	if (keytab)
		krb5_kt_close(context, keytab);
	if (context)
		krb5_free_context(context);
	return ccname;
}
Esempio n. 16
0
static krb5_error_code
digest_request(krb5_context context,
	       krb5_realm realm,
	       krb5_ccache ccache,
	       krb5_key_usage usage,
	       const DigestReqInner *ireq,
	       DigestRepInner *irep)
{
    DigestREQ req;
    DigestREP rep;
    krb5_error_code ret;
    krb5_data data, data2;
    size_t size = 0;
    krb5_crypto crypto = NULL;
    krb5_auth_context ac = NULL;
    krb5_principal principal = NULL;
    krb5_ccache id = NULL;
    krb5_realm r = NULL;

    krb5_data_zero(&data);
    krb5_data_zero(&data2);
    memset(&req, 0, sizeof(req));
    memset(&rep, 0, sizeof(rep));

    if (ccache == NULL) {
	ret = krb5_cc_default(context, &id);
	if (ret)
	    goto out;
    } else
	id = ccache;

    if (realm == NULL) {
	ret = krb5_get_default_realm(context, &r);
	if (ret)
	    goto out;
    } else
	r = realm;

    /*
     *
     */

    ret = krb5_make_principal(context, &principal,
			      r, KRB5_DIGEST_NAME, r, NULL);
    if (ret)
	goto out;

    ASN1_MALLOC_ENCODE(DigestReqInner, data.data, data.length,
		       ireq, &size, ret);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to encode digest inner request", ""));
	goto out;
    }
    if (size != data.length)
	krb5_abortx(context, "ASN.1 internal encoder error");

    ret = krb5_mk_req_exact(context, &ac,
			    AP_OPTS_USE_SUBKEY|AP_OPTS_MUTUAL_REQUIRED,
			    principal, NULL, id, &req.apReq);
    if (ret)
	goto out;

    {
	krb5_keyblock *key;

	ret = krb5_auth_con_getlocalsubkey(context, ac, &key);
	if (ret)
	    goto out;
	if (key == NULL) {
	    ret = EINVAL;
	    krb5_set_error_message(context, ret,
				   N_("Digest failed to get local subkey", ""));
	    goto out;
	}

	ret = krb5_crypto_init(context, key, 0, &crypto);
	krb5_free_keyblock (context, key);
	if (ret)
	    goto out;
    }

    ret = krb5_encrypt_EncryptedData(context, crypto, usage,
				     data.data, data.length, 0,
				     &req.innerReq);
    if (ret)
	goto out;

    krb5_data_free(&data);

    ASN1_MALLOC_ENCODE(DigestREQ, data.data, data.length,
		       &req, &size, ret);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to encode DigestREQest", ""));
	goto out;
    }
    if (size != data.length)
	krb5_abortx(context, "ASN.1 internal encoder error");

    ret = krb5_sendto_kdc(context, &data, &r, &data2);
    if (ret)
	goto out;

    ret = decode_DigestREP(data2.data, data2.length, &rep, NULL);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to parse digest response", ""));
	goto out;
    }

    {
	krb5_ap_rep_enc_part *repl;

	ret = krb5_rd_rep(context, ac, &rep.apRep, &repl);
	if (ret)
	    goto out;

	krb5_free_ap_rep_enc_part(context, repl);
    }
    {
	krb5_keyblock *key;

	ret = krb5_auth_con_getremotesubkey(context, ac, &key);
	if (ret)
	    goto out;
	if (key == NULL) {
	    ret = EINVAL;
	    krb5_set_error_message(context, ret,
				   N_("Digest reply have no remote subkey", ""));
	    goto out;
	}

	krb5_crypto_destroy(context, crypto);
	ret = krb5_crypto_init(context, key, 0, &crypto);
	krb5_free_keyblock (context, key);
	if (ret)
	    goto out;
    }

    krb5_data_free(&data);
    ret = krb5_decrypt_EncryptedData(context, crypto, usage,
				     &rep.innerRep, &data);
    if (ret)
	goto out;

    ret = decode_DigestRepInner(data.data, data.length, irep, NULL);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to decode digest inner reply", ""));
	goto out;
    }

 out:
    if (ccache == NULL && id)
	krb5_cc_close(context, id);
    if (realm == NULL && r)
	free(r);
    if (crypto)
	krb5_crypto_destroy(context, crypto);
    if (ac)
	krb5_auth_con_free(context, ac);
    if (principal)
	krb5_free_principal(context, principal);

    krb5_data_free(&data);
    krb5_data_free(&data2);

    free_DigestREQ(&req);
    free_DigestREP(&rep);

    return ret;
}
Esempio n. 17
0
int main(int argc, const char *argv[])
{
	static const char *server = NULL;
	static const char *principal = NULL;
	static const char *keytab = NULL;
	static const char *enctypes_string = NULL;
	static const char *binddn = NULL;
	static const char *bindpw = NULL;
	int quiet = 0;
	int askpass = 0;
	int permitted_enctypes = 0;
	int retrieve = 0;
        struct poptOption options[] = {
            { "quiet", 'q', POPT_ARG_NONE, &quiet, 0,
              _("Print as little as possible"), _("Output only on errors")},
            { "server", 's', POPT_ARG_STRING, &server, 0,
              _("Contact this specific KDC Server"),
              _("Server Name") },
            { "principal", 'p', POPT_ARG_STRING, &principal, 0,
              _("The principal to get a keytab for (ex: ftp/[email protected])"),
              _("Kerberos Service Principal Name") },
            { "keytab", 'k', POPT_ARG_STRING, &keytab, 0,
              _("File were to store the keytab information"),
              _("Keytab File Name") },
	    { "enctypes", 'e', POPT_ARG_STRING, &enctypes_string, 0,
              _("Encryption types to request"),
              _("Comma separated encryption types list") },
	    { "permitted-enctypes", 0, POPT_ARG_NONE, &permitted_enctypes, 0,
              _("Show the list of permitted encryption types and exit"),
              _("Permitted Encryption Types") },
	    { "password", 'P', POPT_ARG_NONE, &askpass, 0,
              _("Asks for a non-random password to use for the principal"), NULL },
	    { "binddn", 'D', POPT_ARG_STRING, &binddn, 0,
              _("LDAP DN"), _("DN to bind as if not using kerberos") },
	    { "bindpw", 'w', POPT_ARG_STRING, &bindpw, 0,
              _("LDAP password"), _("password to use if not using kerberos") },
	    { "retrieve", 'r', POPT_ARG_NONE, &retrieve, 0,
              _("Retrieve current keys without changing them"), NULL },
            POPT_AUTOHELP
            POPT_TABLEEND
	};
	poptContext pc;
	char *ktname;
	char *password = NULL;
	krb5_context krbctx;
	krb5_ccache ccache;
	krb5_principal uprinc = NULL;
	krb5_principal sprinc;
	krb5_error_code krberr;
	struct keys_container keys = { 0 };
	krb5_keytab kt;
	int kvno;
	int i, ret;
	char *err_msg;

    ret = init_gettext();
    if (ret) {
        fprintf(stderr, "Failed to load translations\n");
    }

	krberr = krb5_init_context(&krbctx);
	if (krberr) {
		fprintf(stderr, _("Kerberos context initialization failed\n"));
		exit(1);
	}

	pc = poptGetContext("ipa-getkeytab", argc, (const char **)argv, options, 0);
	ret = poptGetNextOpt(pc);
	if (ret == -1 && permitted_enctypes &&
	    !(server || principal || keytab || quiet)) {
		krb5_enctype *ktypes;
		char enc[79]; /* fit std terminal or truncate */

		krberr = krb5_get_permitted_enctypes(krbctx, &ktypes);
		if (krberr) {
			fprintf(stderr, _("No system preferred enctypes ?!\n"));
			exit(1);
		}
		fprintf(stdout, _("Supported encryption types:\n"));
		for (i = 0; ktypes[i]; i++) {
			krberr = krb5_enctype_to_string(ktypes[i], enc, 79);
			if (krberr) {
				fprintf(stderr, _("Warning: "
                                        "failed to convert type (#%d)\n"), i);
				continue;
			}
			fprintf(stdout, "%s\n", enc);
		}
		ipa_krb5_free_ktypes(krbctx, ktypes);
		exit (0);
	}

	if (ret != -1 || !principal || !keytab || permitted_enctypes) {
		if (!quiet) {
			poptPrintUsage(pc, stderr, 0);
		}
		exit(2);
	}

	if (NULL!=binddn && NULL==bindpw) {
		fprintf(stderr,
                        _("Bind password required when using a bind DN.\n"));
		if (!quiet)
			poptPrintUsage(pc, stderr, 0);
		exit(10);
	}

    if (!server) {
        struct ipa_config *ipacfg = NULL;

        ret = read_ipa_config(&ipacfg);
        if (ret == 0) {
            server = ipacfg->server_name;
            ipacfg->server_name = NULL;
        }
        free(ipacfg);
        if (!server) {
            fprintf(stderr, _("Server name not provided and unavailable\n"));
            exit(2);
        }
    }

    if (askpass && retrieve) {
        fprintf(stderr, _("Incompatible options provided (-r and -P)\n"));
        exit(2);
    }

        if (askpass) {
		password = ask_password(krbctx);
		if (!password) {
			exit(2);
		}
	} else if (enctypes_string && strchr(enctypes_string, ':')) {
		if (!quiet) {
			fprintf(stderr, _("Warning: salt types are not honored"
                                " with randomized passwords (see opt. -P)\n"));
		}
	}

	ret = asprintf(&ktname, "WRFILE:%s", keytab);
	if (ret == -1) {
		exit(3);
	}

	krberr = krb5_parse_name(krbctx, principal, &sprinc);
	if (krberr) {
		fprintf(stderr, _("Invalid Service Principal Name\n"));
		exit(4);
	}

	if (NULL == bindpw) {
		krberr = krb5_cc_default(krbctx, &ccache);
		if (krberr) {
			fprintf(stderr,
                                _("Kerberos Credential Cache not found. "
				  "Do you have a Kerberos Ticket?\n"));
			exit(5);
		}

		krberr = krb5_cc_get_principal(krbctx, ccache, &uprinc);
		if (krberr) {
			fprintf(stderr,
                                _("Kerberos User Principal not found. "
				  "Do you have a valid Credential Cache?\n"));
			exit(6);
		}
	}

	krberr = krb5_kt_resolve(krbctx, ktname, &kt);
	if (krberr) {
		fprintf(stderr, _("Failed to open Keytab\n"));
		exit(7);
	}

    kvno = -1;
    ret = ldap_get_keytab(krbctx, (retrieve == 0), password, enctypes_string,
                          server, principal, uprinc, binddn, bindpw,
                          &keys, &kvno, &err_msg);
    if (ret) {
        if (!quiet && err_msg != NULL) {
            fprintf(stderr, "%s", err_msg);
        }
    }

    if (retrieve == 0 && kvno == -1) {
        if (!quiet) {
            fprintf(stderr,
                    _("Retrying with pre-4.0 keytab retrieval method...\n"));
        }

        /* create key material */
        ret = create_keys(krbctx, sprinc, password, enctypes_string, &keys, &err_msg);
        if (!ret) {
            if (err_msg != NULL) {
                fprintf(stderr, "%s", err_msg);
            }

            fprintf(stderr, _("Failed to create key material\n"));
            exit(8);
        }

        kvno = ldap_set_keytab(krbctx, server, principal, uprinc, binddn, bindpw, &keys);
    }

    if (kvno == -1) {
        fprintf(stderr, _("Failed to get keytab\n"));
        exit(9);
    }

	for (i = 0; i < keys.nkeys; i++) {
		krb5_keytab_entry kt_entry;
		memset((char *)&kt_entry, 0, sizeof(kt_entry));
		kt_entry.principal = sprinc;
		kt_entry.key = keys.ksdata[i].key;
		kt_entry.vno = kvno;

		krberr = krb5_kt_add_entry(krbctx, kt, &kt_entry);
		if (krberr) {
			fprintf(stderr,
                                _("Failed to add key to the keytab\n"));
			exit (11);
		}
	}

	free_keys_contents(krbctx, &keys);

	krberr = krb5_kt_close(krbctx, kt);
	if (krberr) {
		fprintf(stderr, _("Failed to close the keytab\n"));
		exit (12);
	}

	if (!quiet) {
		fprintf(stderr,
			_("Keytab successfully retrieved and stored in: %s\n"),
			keytab);
	}
	exit(0);
}
Esempio n. 18
0
ADS_STATUS ads_krb5_set_password(const char *kdc_host, const char *princ, 
				 const char *newpw, int time_offset)
{

	ADS_STATUS aret;
	krb5_error_code ret = 0;
	krb5_context context = NULL;
	krb5_principal principal = NULL;
	char *princ_name = NULL;
	char *realm = NULL;
	krb5_creds creds, *credsp = NULL;
#if KRB5_PRINC_REALM_RETURNS_REALM
	krb5_realm orig_realm;
#else
	krb5_data orig_realm;
#endif
	krb5_ccache ccache = NULL;

	ZERO_STRUCT(creds);
	
	initialize_krb5_error_table();
	ret = krb5_init_context(&context);
	if (ret) {
		DEBUG(1,("Failed to init krb5 context (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	if (time_offset != 0) {
		krb5_set_real_time(context, time(NULL) + time_offset, 0);
	}

	ret = krb5_cc_default(context, &ccache);
	if (ret) {
	        krb5_free_context(context);
		DEBUG(1,("Failed to get default creds (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	realm = strchr_m(princ, '@');
	if (!realm) {
		krb5_cc_close(context, ccache);
	        krb5_free_context(context);
		DEBUG(1,("Failed to get realm\n"));
		return ADS_ERROR_KRB5(-1);
	}
	realm++;

	asprintf(&princ_name, "kadmin/changepw@%s", realm);
	ret = smb_krb5_parse_name(context, princ_name, &creds.server);
	if (ret) {
		krb5_cc_close(context, ccache);
                krb5_free_context(context);
		DEBUG(1,("Failed to parse kadmin/changepw (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}

	/* parse the principal we got as a function argument */
	ret = smb_krb5_parse_name(context, princ, &principal);
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.server);
                krb5_free_context(context);
		DEBUG(1,("Failed to parse %s (%s)\n", princ_name, error_message(ret)));
		free(princ_name);
		return ADS_ERROR_KRB5(ret);
	}

	free(princ_name);

	/* The creds.server principal takes ownership of this memory.
		Remember to set back to original value before freeing. */
	orig_realm = *krb5_princ_realm(context, creds.server);
	krb5_princ_set_realm(context, creds.server, krb5_princ_realm(context, principal));
	
	ret = krb5_cc_get_principal(context, ccache, &creds.client);
	if (ret) {
		krb5_cc_close(context, ccache);
		krb5_princ_set_realm(context, creds.server, &orig_realm);
	        krb5_free_principal(context, creds.server);
	        krb5_free_principal(context, principal);
                krb5_free_context(context);
		DEBUG(1,("Failed to get principal from ccache (%s)\n", 
			 error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	ret = krb5_get_credentials(context, 0, ccache, &creds, &credsp); 
	if (ret) {
		krb5_cc_close(context, ccache);
	        krb5_free_principal(context, creds.client);
		krb5_princ_set_realm(context, creds.server, &orig_realm);
	        krb5_free_principal(context, creds.server);
	        krb5_free_principal(context, principal);
	        krb5_free_context(context);
		DEBUG(1,("krb5_get_credentials failed (%s)\n", error_message(ret)));
		return ADS_ERROR_KRB5(ret);
	}
	
	/* we might have to call krb5_free_creds(...) from now on ... */

	aret = do_krb5_kpasswd_request(context, kdc_host,
				       KRB5_KPASSWD_VERS_SETPW,
				       credsp, princ, newpw);

	krb5_free_creds(context, credsp);
	krb5_free_principal(context, creds.client);
	krb5_princ_set_realm(context, creds.server, &orig_realm);
        krb5_free_principal(context, creds.server);
	krb5_free_principal(context, principal);
	krb5_cc_close(context, ccache);
	krb5_free_context(context);

	return aret;
}
Esempio n. 19
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache cache;
    krb5_creds in, *out;
    krb5_kdc_flags flags;
    int optind = 0;

    flags.i = 0;

    ret = krb5_init_context (&context);
    if (ret)
	errx(1, "krb5_init_context failed: %d", ret);
  
    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind))
	usage(1);
    
    if (help_flag)
	usage (0);

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

    argc -= optind;
    argv += optind;

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

    ret = krb5_cc_default(context, &cache);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_default");

    if(cache_str) {
	ret = krb5_cc_resolve(context, cache_str, &cache);
	if (ret)
	    krb5_err (context, 1, ret, "%s", cache_str);
    } else {
	ret = krb5_cc_default (context, &cache);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");
    }

    memset(&in, 0, sizeof(in));

    if (etype_str) {
	krb5_enctype enctype;

	ret = krb5_string_to_enctype(context, etype_str, &enctype);
	if (ret)
	    krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
	in.session.keytype = enctype;
    }

    ret = krb5_cc_get_principal(context, cache, &in.client);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_get_principal");

    ret = krb5_parse_name(context, argv[0], &in.server);
    if (ret)
	krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);

    if (!transit_check)
	flags.b.disable_transited_check = 1;
    if (canonicalize)
	flags.b.canonicalize = 1;


    in.times.endtime = 0;
    ret = krb5_get_credentials_with_flags(context, 0, flags, cache, &in, &out);
    if (ret)
	krb5_err (context, 1, ret, "krb5_get_credentials");

    krb5_free_cred_contents(context, out);
    return 0;
}
Esempio n. 20
0
int main(int argc, char **argv)
{
	int log_level = 0;
	char *data_str;
	char *ap_req_str = NULL;
	unsigned char *data;
	size_t data_len;

	/* krb5 */
	krb5_error_code ret;
	krb5_context context;
	krb5_auth_context auth_context;
	char *princ_str_tn = "kink/tn.example.com";
	krb5_principal princ_tn;
	char *princ_str_nut = "kink/nut.example.com";
	krb5_principal princ_nut;
	char *princ_str_krbtgt = "krbtgt/EXAMPLE.COM";
	krb5_principal princ_krbtgt;
	krb5_ccache ccache;
	krb5_keytab keytab;
	krb5_creds creds_tgt;
	krb5_data ap_req;

	prog = (const char *) basename(argv[0]);
	if (prog == NULL) {
		fprintf(stderr,
			"basename: %s -- %s\n", strerror(errno), argv[0]);

		return(0);
		/* NOTREACHED */
	}

	{
		int ch = 0;

		while ((ch = getopt(argc, argv, "dq:")) != -1) {
			switch (ch) {
			case 'd':
				log_level++;
				break;
			case 'q':
				ap_req_str = optarg;
				break;
			default:
				usage();
				/* NOTREACHED */

				break;
			}
		}

		argc -= optind;
		argv += optind;
	}

	if (!argc) {
		usage();
		/* NOTREACHED */
	}
	data_str = argv[0];

	{
		printf("dbg: %s starts arg(%s)\n", prog, data_str);
	}

	{
		{ /* stdout */
			printf("std:data:%s\n", data_str);
		}
		data_len = strlen(data_str);
		data_len = data_len/2 + data_len%2;
		data = (unsigned char *)malloc(data_len);
		memset(data, 0, data_len);
		data = hex2data(data_str, data);
	}

	if (ap_req_str != NULL) {
		hex2krb5data(ap_req_str, &ap_req);
		if (log_level) {
			dump_krb5_data(&ap_req);
		}
		{ /* stdout */
			int i = 0;
			unsigned char *p;
			p = (unsigned char *)ap_req.data;
			printf("std:ap_req:");
			for (i = 0; i < ap_req.length; i++) {
				printf("%02x", *p++);
			}
			printf("\n");
		}
	}

	/* prepare krb5 context */
	{
		/** init context */
		ret = krb5_init_context(&context);
		if (ret != 0) {
			printf("ERR:krb5_init_context:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/** setup principals */
		ret = krb5_parse_name(context, princ_str_tn, &princ_tn);
		if (ret != 0) {
			printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
		ret = krb5_parse_name(context, princ_str_nut, &princ_nut);
		if (ret != 0) {
			printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
		ret = krb5_parse_name(context, princ_str_krbtgt, &princ_krbtgt);
		if (ret != 0) {
			printf("ERR:krb5_parse_name:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/** prepare credential cache */
		ret = krb5_cc_default(context, &ccache);
		if (ret != 0) {
			printf("ERR:krb5_cc_default:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/** prepare keytab */
		/*ret = krb5_kt_resolve(context, "/usr/local/var/krb5kdc/kadm5.keytab", &keytab);*/
		ret = krb5_kt_default(context, &keytab);
		if (ret != 0) {
			/* printf("ERR:krb5_kt_default:%s", krb5_get_err_text(context, ret)); */
			printf("ERR:krb5_kt_resolve:%s", krb5_get_err_text(context, ret));
			return(ret);
		}

	}

	/* get TGT */
	{
		krb5_creds mcreds;
		memset(&mcreds, 0, sizeof(mcreds));
		mcreds.client = princ_tn;
		mcreds.server = princ_krbtgt;

		ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &creds_tgt);
		if (ret != 0) {
			printf("ERR:krb5_cc_retrieve_cred:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
	}

	/* prepare authentiation context */
	{
		ret = krb5_auth_con_init(context, &auth_context);
		if (ret != 0) {
			printf("ERR:krb5_auth_con_init:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		ret = krb5_auth_con_setflags(context, auth_context,
					     KRB5_AUTH_CONTEXT_DO_SEQUENCE);
		if (ret != 0) {
			printf("ERR:krb5_auth_con_setflags:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/* if USE_SKEY */
		/*
		ret = krb5_auth_con_setuserkey(context, auth_context, &creds_tgt.session);
		if (ret != 0) {
			printf("ERR:krb5_auth_con_setuseruserkey:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
		*/
	}

	/* set keyblock in auth_context */
	if (ap_req_str != NULL) {
		krb5_ticket *ticket;
		krb5_flags ap_req_options;
		
		ap_req_options = AP_OPTS_MUTUAL_REQUIRED;
		ticket = NULL;
		ret = krb5_rd_req(context,
				  &auth_context,
				  &ap_req,
				  NULL,
				  keytab,
				  &ap_req_options,
				  &ticket);
		if (log_level) {
			printf("info: ticket.ticket.key is SKEYID_d\n");
			/*dump_krb5_ticket(context, *ticket);*/
		}
		if (log_level) {
			printf("ap_req_opt (%d)\n", ap_req_options);
		}
		if (ret != 0) {
			printf("ERR:krb5_rd_req:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
		if (log_level) {
			dump_krb5_keyblock(auth_context->keyblock);
		}

		krb5_free_ticket(context, ticket);
	}
	else {
		krb5_creds mcreds;
		krb5_creds *cred;
		krb5_creds cred_copy;

		memset(&mcreds, 0, sizeof(mcreds));
		mcreds.client = princ_tn;
		mcreds.server = princ_nut;

		ret = krb5_get_credentials(context, KRB5_GC_CACHED, ccache, &mcreds, &cred);
		if (ret != 0) {
			printf("ERR:krb5_get_credentials:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/* mk_req_extends reallocate cred, so use a copy */
		ret = krb5_copy_creds_contents(context,
					       (const krb5_creds *)cred,
					       &cred_copy);
		if (ret != 0) {
			printf("ERR:krb5_copy_creds_contents:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		/*
		 * If auth_con == NULL, one is allocated.
		 * This is used later. (keyblock is used to decrypt AP_REP)
		 */
		ret = krb5_mk_req_extended(context, &auth_context,
					   AP_OPTS_MUTUAL_REQUIRED,
					   NULL /* in_data */,
					   &cred_copy,
					   &ap_req);
		if (ret != 0) {
			printf("ERR:krb5_mk_req_extended:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
	}

	/* create checksum */
	{
		krb5_crypto crypto;
		krb5_checksum cksum;

		ret = krb5_crypto_init(context,
				       auth_context->keyblock,
				       auth_context->keyblock->keytype,
				       &crypto);
		if (ret != 0) {
			printf("ERR:krb5_crypto_init:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		if (0) {
			dump_krb5_keyblock(auth_context->keyblock);
		}
		ret = krb5_create_checksum(context,
					   crypto,
					   40,
					   0 /* krb5_cksumtype type */,
					   data,
					   data_len,
					   &cksum);
		if (ret != 0) {
			printf("ERR:krb5_create_checksum:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}
		if (log_level) {
			dump_krb5_checksum(cksum);
		}
		{ /* stdout */
			int i = 0;
			unsigned char *p;
			p = (unsigned char *)cksum.checksum.data;
			printf("std:cksum:");
			for (i = 0; i < cksum.checksum.length; i++) {
				printf("%02x", *p++);
			}
			printf("\n");
		}

		krb5_crypto_destroy(context, crypto);
	}

	/* clenaup */
	{
		/*free(data);*/
		/*krb5_data_free(&ap_req);*/
		krb5_free_cred_contents(context, &creds_tgt);

		ret = krb5_kt_close(context, keytab);
		if (ret != 0) {
			printf("ERR:krb5_kt_close:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		ret = krb5_cc_close(context, ccache);
		if (ret != 0) {
			printf("ERR:krb5_cc_close:%s\n", krb5_get_err_text(context, ret));
			return(ret);
		}

		krb5_free_principal(context, princ_krbtgt);
		krb5_free_principal(context, princ_nut);
		krb5_free_principal(context, princ_tn);
		krb5_free_context(context);
	}

	return(0);
}
Esempio n. 21
0
/* returns boolean */
static int DEFAULT_CC
k5_begin(struct k_opts *opts, struct k5_data *k5, struct user_info *u_info)
{
    krb5_error_code code = 0;

    code = krb5_init_context(&k5->ctx);

    if (code != 0)
    {
        g_printf("krb5_init_context failed in k5_begin\n");
        return 0;
    }

    if (opts->k5_cache_name)
    {
        code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);

        if (code != 0)
        {
            g_printf("krb5_cc_resolve failed in k5_begin\n");
            return 0;
        }
    }
    else
    {
        code = krb5_cc_default(k5->ctx, &k5->cc);

        if (code != 0)
        {
            g_printf("krb5_cc_default failed in k5_begin\n");
            return 0;
        }
    }

    if (opts->principal_name)
    {
        /* Use specified name */
        code = krb5_parse_name(k5->ctx, opts->principal_name, &k5->me);

        if (code != 0)
        {
            g_printf("krb5_parse_name failed in k5_begin\n");
            return 0;
        }
    }
    else
    {
        /* No principal name specified */
        if (opts->action == INIT_KT)
        {
            /* Use the default host/service name */
            code = krb5_sname_to_principal(k5->ctx, NULL, NULL,
                                           KRB5_NT_SRV_HST, &k5->me);

            if (code != 0)
            {
                g_printf("krb5_sname_to_principal failed in k5_begin\n");
                return 0;
            }
        }
        else
        {
            /* Get default principal from cache if one exists */
            code = krb5_cc_get_principal(k5->ctx, k5->cc, &k5->me);

            if (code != 0)
            {
                code = krb5_parse_name(k5->ctx, u_info->name, &k5->me);

                if (code != 0)
                {
                    g_printf("krb5_parse_name failed in k5_begin\n");
                    return 0;
                }
            }
        }
    }

    code = krb5_unparse_name(k5->ctx, k5->me, &k5->name);

    if (code != 0)
    {
        g_printf("krb5_unparse_name failed in k5_begin\n");
        return 0;
    }

    opts->principal_name = k5->name;
    return 1;
}
Esempio n. 22
0
/*	Given krb5 service (typically "kssl") and hostname in kssl_ctx,
**	Return encrypted Kerberos ticket for service @ hostname.
**	If authenp is non-NULL, also return encrypted authenticator,
**	whose data should be freed by caller.
**	(Originally was: Create Kerberos AP_REQ message for SSL Client.)
**
**	19990628	VRS 	Started; Returns Kerberos AP_REQ message.
**	20010409	VRS 	Modified for RFC2712; Returns enc tkt.
**	20010606	VRS 	May also return optional authenticator.
*/
krb5_error_code
kssl_cget_tkt(
	/* UPDATE */	KSSL_CTX *kssl_ctx,
	/* OUT    */	krb5_data **enc_ticketp,
	/* UPDATE */	krb5_data *authenp,
	/* OUT    */	KSSL_ERR *kssl_err)
{
	krb5_error_code		krb5rc = KRB5KRB_ERR_GENERIC;
	krb5_context		krb5context = NULL;
	krb5_auth_context	krb5auth_context = NULL;
	krb5_ccache 		krb5ccdef = NULL;
	krb5_creds		krb5creds, *krb5credsp = NULL;
	krb5_data		krb5_app_req;

	kssl_err_set(kssl_err, 0, "");
	memset((char *)&krb5creds, 0, sizeof(krb5creds));

	if (!kssl_ctx) {
		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
		    "No kssl_ctx defined.\n");
		goto err;
	} else if (!kssl_ctx->service_host) {
		kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT,
		    "kssl_ctx service_host undefined.\n");
		goto err;
	}

	if ((krb5rc = krb5_init_context(&krb5context)) != 0) {
		(void) snprintf(kssl_err->text, KSSL_ERR_MAX,
		    "krb5_init_context() fails: %d\n", krb5rc);
		kssl_err->reason = SSL_R_KRB5_C_INIT;
		goto err;
	}

	if ((krb5rc = krb5_sname_to_principal(krb5context,
	    kssl_ctx->service_host,
	    (kssl_ctx->service_name) ? kssl_ctx->service_name : KRB5SVC,
	    KRB5_NT_SRV_HST, &krb5creds.server)) != 0) {
		(void) snprintf(kssl_err->text, KSSL_ERR_MAX,
		    "krb5_sname_to_principal() fails for %s/%s\n",
		    kssl_ctx->service_host, (kssl_ctx->service_name) ?
		    kssl_ctx->service_name : KRB5SVC);
		kssl_err->reason = SSL_R_KRB5_C_INIT;
		goto err;
	}

	if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) {
		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
		    "krb5_cc_default fails.\n");
		goto err;
	}

	if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef,
	    &krb5creds.client)) != 0) {
		kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC,
		    "krb5_cc_get_principal() fails.\n");
		goto err;
	}

	if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef,
	    &krb5creds, &krb5credsp)) != 0) {
		kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED,
		    "krb5_get_credentials() fails.\n");
		goto err;
	}

	*enc_ticketp = &krb5credsp->ticket;
#ifdef KRB5_HEIMDAL
	kssl_ctx->enctype = krb5credsp->session.keytype;
#else
	kssl_ctx->enctype = krb5credsp->keyblock.enctype;
#endif

	krb5rc = KRB5KRB_ERR_GENERIC;
	/*	caller should free data of krb5_app_req  */
	/*  20010406 VRS deleted for real KerberosWrapper
	**  20010605 VRS reinstated to offer Authenticator to KerberosWrapper
	*/
	krb5_app_req.length = 0;
	if (authenp) {
		krb5_data	krb5in_data;
		const unsigned char	*p;
		long		arlen;
		KRB5_APREQBODY	*ap_req;

		authenp->length = 0;
		krb5in_data.data = NULL;
		krb5in_data.length = 0;
		if ((krb5rc = krb5_mk_req_extended(krb5context,
		    &krb5auth_context, 0, &krb5in_data, krb5credsp,
		    &krb5_app_req)) != 0) {
			kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ,
			    "krb5_mk_req_extended() fails.\n");
			goto err;
		}

		arlen = krb5_app_req.length;
		p = (unsigned char *)krb5_app_req.data;
		ap_req = (KRB5_APREQBODY *) d2i_KRB5_APREQ(NULL, &p, arlen);
		if (ap_req) {
			authenp->length = i2d_KRB5_ENCDATA(
			    ap_req->authenticator, NULL);
			if (authenp->length &&
			    (authenp->data = malloc(authenp->length))) {
				unsigned char	*adp = (unsigned char *)authenp->data;
				authenp->length = i2d_KRB5_ENCDATA(
				    ap_req->authenticator, &adp);
			}
		}

		if (ap_req)
			KRB5_APREQ_free((KRB5_APREQ *) ap_req);
		if (krb5_app_req.length)
			kssl_krb5_free_data_contents(krb5context, &krb5_app_req);
	}
#ifdef KRB5_HEIMDAL
	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) {
		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
		    "kssl_ctx_setkey() fails.\n");
	}
#else
	if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) {
		kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT,
		    "kssl_ctx_setkey() fails.\n");
	}
#endif
	else
		krb5rc = 0;

err:
#ifdef KSSL_DEBUG
	kssl_ctx_show(kssl_ctx);
#endif	/* KSSL_DEBUG */

	if (krb5creds.client)
		krb5_free_principal(krb5context, krb5creds.client);
	if (krb5creds.server)
		krb5_free_principal(krb5context, krb5creds.server);
	if (krb5auth_context)
		krb5_auth_con_free(krb5context, krb5auth_context);
	if (krb5context)
		krb5_free_context(krb5context);
	return (krb5rc);
}
Esempio n. 23
0
static int
krb5_forward_cred (krb5_auth_context auth_context,
		   int s,
		   const char *hostname,
		   int forwardable)
{
    krb5_error_code ret;
    krb5_ccache     ccache;
    krb5_creds      creds;
    krb5_kdc_flags  flags;
    krb5_data       out_data;
    krb5_principal  principal;

    memset (&creds, 0, sizeof(creds));

    ret = krb5_cc_default (context, &ccache);
    if (ret) {
	warnx ("could not forward creds: krb5_cc_default: %s",
	       krb5_get_err_text (context, ret));
	return 1;
    }

    ret = krb5_cc_get_principal (context, ccache, &principal);
    if (ret) {
	warnx ("could not forward creds: krb5_cc_get_principal: %s",
	       krb5_get_err_text (context, ret));
	return 1;
    }

    creds.client = principal;

    ret = krb5_make_principal(context,
			      &creds.server,
			      principal->realm,
			      "krbtgt",
			      principal->realm,
			      NULL);

    if (ret) {
	warnx ("could not forward creds: krb5_make_principal: %s",
	       krb5_get_err_text (context, ret));
	return 1;
    }

    creds.times.endtime = 0;

    flags.i = 0;
    flags.b.forwarded   = 1;
    flags.b.forwardable = forwardable;

    ret = krb5_get_forwarded_creds (context,
				    auth_context,
				    ccache,
				    flags.i,
				    hostname,
				    &creds,
				    &out_data);
    if (ret) {
	warnx ("could not forward creds: krb5_get_forwarded_creds: %s",
	       krb5_get_err_text (context, ret));
	return 1;
    }

    ret = krb5_write_message (context,
			      (void *)&s,
			      &out_data);
    krb5_data_free (&out_data);

    if (ret)
	warnx ("could not forward creds: krb5_write_message: %s",
	       krb5_get_err_text (context, ret));
    return 0;
}
Esempio n. 24
0
/*
 *  validate user/pass (Heimdal)
 */
static int krb5_auth(void *instance, REQUEST *request)
{
	rlm_krb5_t *inst = instance;

	krb5_error_code ret;
	krb5_ccache id;
	krb5_principal userP;

	krb5_context context = *(inst->context); /* copy data */
	const char *user, *pass;

	char service[SERVICE_NAME_LEN] = "host";
	char *server_name = NULL;
	char *princ_name;

	krb5_verify_opt krb_verify_options;
	krb5_keytab keytab;

	if (inst->service_princ != NULL) {
		server_name = strchr(inst->service_princ, '/');
		if (server_name != NULL) {
			*server_name = '\0';
		}

		strlcpy(service, inst->service_princ, sizeof(service));
		if (server_name != NULL) {
			*server_name = '/';
			server_name++;
		}
	}

	/*
	 *  We can only authenticate user requests which HAVE
	 *  a User-Name attribute.
	 */
	if (!request->username) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Name\" is required for authentication.");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 *  We can only authenticate user requests which HAVE
	 *  a User-Password attribute.
	 */
	if (!request->password) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.");
		
		return RLM_MODULE_INVALID;
	}

	/*
	 *  Ensure that we're being passed a plain-text password,
	 *  and not anything else.
	 */
	if (request->password->attribute != PW_USER_PASSWORD) {
		radlog(L_AUTH, "rlm_krb5: Attribute \"User-Password\" is required for authentication.  Cannot use \"%s\".", request->password->name);
		
		return RLM_MODULE_INVALID;
	}

	user = request->username->vp_strvalue;
	pass = request->password->vp_strvalue;

	ret = krb5_parse_name(context, user, &userP);
	if (ret) {
		radlog(L_AUTH, "rlm_krb5: [%s] krb5_parse_name failed: %s",
		       user, error_message(ret));
		       
		return RLM_MODULE_REJECT;
	}

	/*
	 *  Heimdal krb5 verification.
	 */
	 
	/*
	 *  The following bit allows us to also log user/instance@REALM if someone
	 *  logs in using an instance.
	 */
	ret = krb5_unparse_name(context, userP, &princ_name);
	if (ret != 0) {
		radlog(L_AUTH, "rlm_krb5: Unparsable name");
	} else {
		radlog(L_AUTH, "rlm_krb5: Parsed name is: %s", princ_name);
		free(princ_name);
	}

	krb5_cc_default(context, &id);

	/*
	 *  Set up krb5_verify_user options.
	 */
	krb5_verify_opt_init(&krb_verify_options);
	krb5_verify_opt_set_ccache(&krb_verify_options, id);

	/*
	 *  Resolve keytab name. This allows us to use something other than
	 *  the default system keytab
	 */
	if (inst->keytab != NULL) {
		ret = krb5_kt_resolve(context, inst->keytab, &keytab);
		if (ret) {
			radlog(L_AUTH, "rlm_krb5: unable to resolve keytab %s: %s",
			       inst->keytab, error_message(ret));
			krb5_kt_close(context, keytab);
			
			return RLM_MODULE_REJECT;
		}
		
		krb5_verify_opt_set_keytab(&krb_verify_options, keytab);
	}

	/*
	 *  Verify aquired credentials against the keytab.
	 */
	krb5_verify_opt_set_secure(&krb_verify_options, 1);

	/*
	 *  Allow us to use an arbitrary service name.
	 */
	krb5_verify_opt_set_service(&krb_verify_options, service);

	/* 
	 *  Verify the user, using the above set options.
	 */
	ret = krb5_verify_user_opt(context, userP, pass, &krb_verify_options);

	/*
	 *  We are done with the keytab, close it.
	 */
	krb5_kt_close(context, keytab);

	if (ret == 0)
		return RLM_MODULE_OK;

	radlog(L_AUTH, "rlm_krb5: failed verify_user: %s (%s@%s)",
	       error_message(ret),
	       *userP->name.name_string.val,
	       userP->realm);

	return RLM_MODULE_REJECT;
}
Esempio n. 25
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_ccache ccache;
    krb5_get_init_creds_opt *opts;
    krb5_principal principal;
    krb5_creds creds;
    krb5_error_code err;
    const char *errmsg;
    char *opt, *val;
    struct responder_data response;
    int c;

    err = krb5_init_context(&context);
    if (err != 0) {
        fprintf(stderr, "error starting Kerberos: %s\n", error_message(err));
        return err;
    }
    err = krb5_get_init_creds_opt_alloc(context, &opts);
    if (err != 0) {
        fprintf(stderr, "error initializing options: %s\n",
                error_message(err));
        return err;
    }
    err = krb5_cc_default(context, &ccache);
    if (err != 0) {
        fprintf(stderr, "error resolving default ccache: %s\n",
                error_message(err));
        return err;
    }
    err = krb5_get_init_creds_opt_set_out_ccache(context, opts, ccache);
    if (err != 0) {
        fprintf(stderr, "error setting output ccache: %s\n",
                error_message(err));
        return err;
    }

    memset(&response, 0, sizeof(response));
    while ((c = getopt(argc, argv, "X:x:cr:p:")) != -1) {
        switch (c) {
        case 'X':
            /* Like kinit, set a generic preauth option. */
            opt = strdup(optarg);
            val = opt + strcspn(opt, "=");
            if (*val != '\0') {
                *val++ = '\0';
            }
            err = krb5_get_init_creds_opt_set_pa(context, opts, opt, val);
            if (err != 0) {
                fprintf(stderr, "error setting option \"%s\": %s\n", opt,
                        error_message(err));
                return err;
            }
            free(opt);
            break;
        case 'x':
            /* Check that a particular question has a specific challenge. */
            response.challenge = optarg;
            break;
        case 'c':
            /* Note that we want a dump of the PKINIT challenge structure. */
            response.print_pkinit_challenge = TRUE;
            break;
        case 'r':
            /* Set a verbatim response for a verbatim challenge. */
            response.response = optarg;
            break;
        case 'p':
            /* Set a PKINIT answer for a specific PKINIT identity. */
            response.pkinit_answer = optarg;
            break;
        case 'o':
            /* Set an OTP answer for a specific OTP tokeninfo. */
            response.otp_answer = optarg;
            break;
        }
    }

    if (argc > optind) {
        err = krb5_parse_name(context, argv[optind], &principal);
        if (err != 0) {
            fprintf(stderr, "error parsing name \"%s\": %s", argv[optind],
                    error_message(err));
            return err;
        }
    } else {
        fprintf(stderr, "error: no principal name provided\n");
        return -1;
    }

    err = krb5_get_init_creds_opt_set_responder(context, opts,
                                                responder, &response);
    if (err != 0) {
        fprintf(stderr, "error setting responder: %s\n", error_message(err));
        return err;
    }
    memset(&creds, 0, sizeof(creds));
    err = krb5_get_init_creds_password(context, &creds, principal, NULL,
                                       NULL, NULL, 0, NULL, opts);
    if (err == 0)
        krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, principal);
    krb5_get_init_creds_opt_free(context, opts);
    krb5_cc_close(context, ccache);

    if (!response.called) {
        fprintf(stderr, "error: responder callback wasn't called\n");
        err = 1;
    } else if (err) {
        errmsg = krb5_get_error_message(context, err);
        fprintf(stderr, "error: krb5_get_init_creds_password failed: %s\n",
                errmsg);
        krb5_free_error_message(context, errmsg);
        err = 2;
    }
    krb5_free_context(context);
    return err;
}
Esempio n. 26
0
static OM_uint32 acquire_initiator_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   const gss_name_t desired_name,
		   OM_uint32 time_req,
		   const gss_OID_set desired_mechs,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle,
		   gss_OID_set * actual_mechs,
		   OM_uint32 * time_rec
		  )
{
    OM_uint32 ret;
    krb5_creds cred;
    krb5_principal def_princ;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache;
    krb5_keytab keytab;
    krb5_error_code kret;

    keytab = NULL;
    ccache = NULL;
    def_princ = NULL;
    ret = GSS_S_FAILURE;
    memset(&cred, 0, sizeof(cred));

    /*
     * If we have a preferred principal, lets try to find it in all
     * caches, otherwise, fall back to default cache, ignore all
     * errors while searching.
     */

    if (handle->principal) {
	kret = krb5_cc_cache_match (context,
				    handle->principal,
				    &ccache);
	if (kret == 0) {
	    ret = GSS_S_COMPLETE;
	    goto found;
	}
    }

    if (ccache == NULL) {
	kret = krb5_cc_default(context, &ccache);
	if (kret)
	    goto end;
    }
    kret = krb5_cc_get_principal(context, ccache, &def_princ);
    if (kret != 0) {
	/* we'll try to use a keytab below */
	krb5_cc_close(context, ccache);
	def_princ = NULL;
	kret = 0;
    } else if (handle->principal == NULL)  {
	kret = krb5_copy_principal(context, def_princ, &handle->principal);
	if (kret)
	    goto end;
    } else if (handle->principal != NULL &&
	       krb5_principal_compare(context, handle->principal,
				      def_princ) == FALSE) {
	krb5_free_principal(context, def_princ);
	def_princ = NULL;
	krb5_cc_close(context, ccache);
	ccache = NULL;
    }
    if (def_princ == NULL) {
	/* We have no existing credentials cache,
	 * so attempt to get a TGT using a keytab.
	 */
	if (handle->principal == NULL) {
	    kret = krb5_get_default_principal(context, &handle->principal);
	    if (kret)
		goto end;
	}
	kret = get_keytab(context, &keytab);
	if (kret)
	    goto end;
	kret = krb5_get_init_creds_opt_alloc(context, &opt);
	if (kret)
	    goto end;
	kret = krb5_get_init_creds_keytab(context, &cred,
	    handle->principal, keytab, 0, NULL, opt);
	krb5_get_init_creds_opt_free(context, opt);
	if (kret)
	    goto end;
	kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
				  NULL, &ccache);
	if (kret)
	    goto end;
	kret = krb5_cc_initialize(context, ccache, cred.client);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	kret = krb5_cc_store_cred(context, ccache, &cred);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	handle->lifetime = cred.times.endtime;
	handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
    } else {

	ret = __gsskrb5_ccache_lifetime(minor_status,
					context,
					ccache,
					handle->principal,
					&handle->lifetime);
	if (ret != GSS_S_COMPLETE) {
	    krb5_cc_close(context, ccache);
	    goto end;
	}
	kret = 0;
    }
 found:
    handle->ccache = ccache;
    ret = GSS_S_COMPLETE;

end:
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(context, def_princ);
    if (keytab != NULL)
	krb5_kt_close(context, keytab);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
    void ccache::destroy(){
	kerror=krb5_cc_destroy(ctx(),_cc);
	if(kerror) return;
	kerror=krb5_cc_default(ctx(),&_cc);	
    }
Esempio n. 28
0
static int
get_user_ccache(const ntlm_name name, char **username, struct ntlm_buf *key)
{
    krb5_context context = NULL;
    krb5_principal client;
    krb5_ccache id = NULL;
    krb5_error_code ret;
    char *confname;
    krb5_data data;

    *username = NULL;
    krb5_data_zero(&data);
    key->length = 0;
    key->data = NULL;

    ret = krb5_init_context(&context);
    if (ret)
	return ret;

    ret = krb5_cc_default(context, &id);
    if (ret)
	goto out;

    ret = krb5_cc_get_principal(context, id, &client);
    if (ret)
	goto out;

    ret = krb5_unparse_name_flags(context, client,
				  KRB5_PRINCIPAL_UNPARSE_NO_REALM,
				  username);
    krb5_free_principal(context, client);
    if (ret)
	goto out;

    asprintf(&confname, "ntlm-key-%s", name->domain);
    if (confname == NULL) {
	krb5_clear_error_message(context);
	ret = ENOMEM;
	goto out;
    }

    ret = krb5_cc_get_config(context, id, NULL,
			     confname, &data);
    if (ret)
	goto out;

    key->data = malloc(data.length);
    if (key->data == NULL) {
	ret = ENOMEM;
	goto out;
    }
    key->length = data.length;
    memcpy(key->data, data.data, data.length);

 out:
    krb5_data_free(&data);
    if (id)
	krb5_cc_close(context, id);

    krb5_free_context(context);

    return ret;
}
Esempio n. 29
0
File: kinit.c Progetto: cg2v/heimdal
static void
get_princ_kt(krb5_context context,
	     krb5_principal *principal,
	     char *name)
{
    krb5_error_code ret;
    krb5_principal tmp;
    krb5_ccache ccache;
    krb5_kt_cursor cursor;
    krb5_keytab_entry entry;
    char *def_realm;

    if (name == NULL) {
	/*
	 * If the credential cache exists and specifies a client principal,
	 * use that.
	 */
	if (krb5_cc_default(context, &ccache) == 0) {
	    ret = krb5_cc_get_principal(context, ccache, principal);
	    krb5_cc_close(context, ccache);
	    if (ret == 0)
		return;
	}
    }

    if (name) {
	/* If the principal specifies an explicit realm, just use that. */
	int parseflags = KRB5_PRINCIPAL_PARSE_NO_DEF_REALM;

	parse_name_realm(context, name, parseflags, NULL, &tmp);
	if (krb5_principal_get_realm(context, tmp) != NULL) {
	    *principal = tmp;
	    return;
	}
    } else {
	/* Otherwise, search keytab for bare name of the default principal. */
	get_default_principal(context, &tmp);
	set_princ_realm(context, tmp, NULL);
    }

    def_realm = get_default_realm(context);

    ret = krb5_kt_start_seq_get(context, kt, &cursor);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kt_start_seq_get");

    while (ret == 0 &&
           krb5_kt_next_entry(context, kt, &entry, &cursor) == 0) {
        const char *realm;

        if (!krb5_principal_compare_any_realm(context, tmp, entry.principal))
            continue;
        if (*principal &&
	    krb5_principal_compare(context, *principal, entry.principal))
            continue;
        /* The default realm takes precedence */
        realm = krb5_principal_get_realm(context, entry.principal);
        if (*principal && strcmp(def_realm, realm) == 0) {
            krb5_free_principal(context, *principal);
            ret = krb5_copy_principal(context, entry.principal, principal);
            break;
        }
        if (!*principal)
            ret = krb5_copy_principal(context, entry.principal, principal);
    }
    if (ret != 0 || (ret = krb5_kt_end_seq_get(context, kt, &cursor)) != 0)
	krb5_err(context, 1, ret, "get_princ_kt");
    if (!*principal) {
	if (name)
	    parse_name_realm(context, name, 0, NULL, principal);
	else
	    krb5_err(context, 1, KRB5_CC_NOTFOUND, "get_princ_kt");
    }

    krb5_free_principal(context, tmp);
    free(def_realm);
}
Esempio n. 30
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_ccache cache;
    krb5_creds in, *out;
    int optidx = 0;

    setprogname (argv[0]);

    ret = krb5_init_context (&context);
    if (ret)
	errx(1, "krb5_init_context failed: %d", ret);

    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 != 1)
	usage (1);

    ret = krb5_cc_default(context, &cache);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_default");

    memset(&in, 0, sizeof(in));

    if (etype_str) {
	krb5_enctype enctype;

	ret = krb5_string_to_enctype(context, etype_str, &enctype);
	if (ret)
	    krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
	in.session.keytype = enctype;
    }

    ret = krb5_cc_get_principal(context, cache, &in.client);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_get_principal");

    ret = krb5_parse_name(context, argv[0], &in.server);
    if (ret)
	krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);

    in.times.endtime = 0;
    ret = krb5_get_credentials(context, 0, cache, &in, &out);
    if (ret)
	krb5_err (context, 1, ret, "krb5_get_credentials");

    print_and_decode_tkt (context, &out->ticket, out->server,
			  out->session.keytype);

    krb5_free_cred_contents(context, out);
    return 0;
}