Exemplo n.º 1
0
static krb5_error_code
set_etypes (krb5_context context,
	    const char *name,
	    krb5_enctype **ret_enctypes)
{
    char **etypes_str;
    krb5_enctype *etypes = NULL;

    etypes_str = krb5_config_get_strings(context, NULL, "libdefaults",
					 name, NULL);
    if(etypes_str){
	int i, j, k;
	for(i = 0; etypes_str[i]; i++);
	etypes = malloc((i+1) * sizeof(*etypes));
	if (etypes == NULL) {
	    krb5_config_free_strings (etypes_str);
	    return krb5_enomem(context);
	}
	for(j = 0, k = 0; j < i; j++) {
	    krb5_enctype e;
	    if(krb5_string_to_enctype(context, etypes_str[j], &e) != 0)
		continue;
	    if (krb5_enctype_valid(context, e) != 0)
		continue;
	    etypes[k++] = e;
	}
	etypes[k] = ETYPE_NULL;
	krb5_config_free_strings(etypes_str);
    }
    *ret_enctypes = etypes;
    return 0;
}
Exemplo n.º 2
0
Arquivo: init_ctx.c Projeto: PADL/krb5
/*
 * Set *result to a zero-terminated list of enctypes resulting from
 * parsing profstr.  profstr may be modified during parsing.
 */
krb5_error_code
krb5int_parse_enctype_list(krb5_context context, const char *profkey,
                           char *profstr, krb5_enctype *default_list,
                           krb5_enctype **result)
{
    char *token, *delim = " \t\r\n,", *save = NULL;
    krb5_boolean sel, weak = context->allow_weak_crypto;
    krb5_enctype etype, *list;
    unsigned int i;

    *result = NULL;

    /* Set up an empty list.  Allocation failure is detected at the end. */
    list = malloc(sizeof(krb5_enctype));
    if (list != NULL)
        list[0] = 0;

    /* Walk through the words in profstr. */
    for (token = strtok_r(profstr, delim, &save); token;
         token = strtok_r(NULL, delim, &save)) {
        /* Determine if we are adding or removing enctypes. */
        sel = TRUE;
        if (*token == '+' || *token == '-')
            sel = (*token++ == '+');

        if (strcasecmp(token, "DEFAULT") == 0) {
            /* Set all enctypes in the default list. */
            for (i = 0; default_list[i]; i++)
                mod_list(default_list[i], sel, weak, &list);
        } else if (strcasecmp(token, "des") == 0) {
            mod_list(ENCTYPE_DES_CBC_CRC, sel, weak, &list);
            mod_list(ENCTYPE_DES_CBC_MD5, sel, weak, &list);
            mod_list(ENCTYPE_DES_CBC_MD4, sel, weak, &list);
        } else if (strcasecmp(token, "des3") == 0) {
            mod_list(ENCTYPE_DES3_CBC_SHA1, sel, weak, &list);
        } else if (strcasecmp(token, "aes") == 0) {
            mod_list(ENCTYPE_AES256_CTS_HMAC_SHA1_96, sel, weak, &list);
            mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, &list);
            mod_list(ENCTYPE_AES256_CTS_HMAC_SHA384_192, sel, weak, &list);
            mod_list(ENCTYPE_AES128_CTS_HMAC_SHA256_128, sel, weak, &list);
        } else if (strcasecmp(token, "rc4") == 0) {
            mod_list(ENCTYPE_ARCFOUR_HMAC, sel, weak, &list);
        } else if (strcasecmp(token, "camellia") == 0) {
            mod_list(ENCTYPE_CAMELLIA256_CTS_CMAC, sel, weak, &list);
            mod_list(ENCTYPE_CAMELLIA128_CTS_CMAC, sel, weak, &list);
        } else if (krb5_string_to_enctype(token, &etype) == 0) {
            /* Set a specific enctype. */
            mod_list(etype, sel, weak, &list);
        } else {
            TRACE_ENCTYPE_LIST_UNKNOWN(context, profkey, token);
        }
    }

    if (list == NULL)
        return ENOMEM;
    *result = list;
    return 0;
}
Exemplo n.º 3
0
int
kt_remove(struct remove_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab_entry entry;
    krb5_keytab keytab;
    krb5_principal principal = NULL;
    krb5_enctype enctype = 0;

    if(opt->principal_string) {
	ret = krb5_parse_name(context, opt->principal_string, &principal);
	if(ret) {
	    krb5_warn(context, ret, "%s", opt->principal_string);
	    return 1;
	}
    }
    if(opt->enctype_string) {
	ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype);
	if(ret) {
	    int t;
	    if(sscanf(opt->enctype_string, "%d", &t) == 1)
		enctype = t;
	    else {
		krb5_warn(context, ret, "%s", opt->enctype_string);
		if(principal)
		    krb5_free_principal(context, principal);
		return 1;
	    }
	}
    }
    if (!principal && !enctype && !opt->kvno_integer) {
	krb5_warnx(context,
		   "You must give at least one of "
		   "principal, enctype or kvno.");
	ret = EINVAL;
	goto out;
    }

    if((keytab = ktutil_open_keytab()) == NULL) {
	ret = 1;
	goto out;
    }

    entry.principal = principal;
    entry.keyblock.keytype = enctype;
    entry.vno = opt->kvno_integer;
    ret = krb5_kt_remove_entry(context, keytab, &entry);
    krb5_kt_close(context, keytab);
    if(ret)
	krb5_warn(context, ret, "remove");
 out:
    if(principal)
	krb5_free_principal(context, principal);
    return ret != 0;
}
Exemplo n.º 4
0
krb5_error_code
srp_gen_keyblock(
    krb5_context krb5_ctx,
    char *enc_keytype,
    char *pass,
    char *salt,
    krb5_keyblock *key)
{
    krb5_error_code krb_err = 0;
    krb5_enctype enctype;
    krb5_data pass_data = {0};
    krb5_data salt_data = {0};

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

    pass_data.data = pass;
    pass_data.length = (int) strlen(pass);
    salt_data.data = salt;
    salt_data.length = (int) strlen(salt);

#if 0
    /* Prefer to use this, as it takes ENCTYPE_AES256_CTS_HMAC_SHA1_96 */
    enctype = find_enctype(enc_keytype);
    if (!enctype)
    {
        krb_err = EINVAL;
        goto error;
    }
#else
    krb_err = krb5_string_to_enctype(
                  enc_keytype,
                  &enctype);
    if (krb_err)
    {
        goto error;
    }
#endif

    krb_err = krb5_c_string_to_key(
                  krb5_ctx,
                  enctype,
                  &pass_data,
                  &salt_data,
                  key);
    if (krb_err)
    {
        goto error;
    }

error:

    return krb_err;
}
Exemplo n.º 5
0
static PyObject *
k5_c_valid_enctype(PyObject *self, PyObject *args)
{
    char *name;
    krb5_context ctx;
    krb5_enctype type;
    krb5_error_code code;
    krb5_boolean valid;
    PyObject *ret;

    if (!PyArg_ParseTuple( args, "s", &name))
	return NULL;

    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_string_to_enctype(name, &type);
    RETURN_ON_ERROR("krb5_string_to_enctype()", code);
    valid = krb5_c_valid_enctype(type);
    ret = PyBool_FromLong((long) valid);
    krb5_free_context(ctx);

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

    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 (debug_flag) {
        ret = krb5_set_debug_dest(context, getprogname(), "STDERR");
        if (ret)
            krb5_warn(context, ret, "krb5_set_debug_dest");
    }

    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, N_("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);
        krb5_free_principal(context, impersonate);
    }

    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 (canonicalize_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_CANONICALIZE);
    if (!store_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE);
    if (cached_only_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_CACHED);

    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_message(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);
    }

    if (nametype_str != NULL) {
        ret = krb5_parse_nametype(context, nametype_str, &nametype);
        if (ret)
            krb5_err(context, 1, ret, "krb5_parse_nametype");
    }

    if (nametype == KRB5_NT_SRV_HST ||
        nametype == KRB5_NT_SRV_HST_NEEDS_CANON)
        is_hostbased_flag = 1;

    if (is_hostbased_flag) {
	const char *sname = NULL;
	const char *hname = NULL;

        if (nametype_str != NULL &&
            nametype != KRB5_NT_SRV_HST &&
            nametype != KRB5_NT_SRV_HST_NEEDS_CANON)
            krb5_errx(context, 1, "--hostbased not compatible with "
                      "non-hostbased --name-type");

        if (is_canonical_flag)
            nametype = KRB5_NT_SRV_HST;
        else
            nametype = KRB5_NT_SRV_HST_NEEDS_CANON;

        /*
         * Host-based service names can have more than one component.
         *
         * RFC5179 did not, but should have, assign a Kerberos name-type
         * corresponding to GSS_C_NT_DOMAINBASED.  But it's basically a
         * host-based service name type with one additional component.
         *
         * So that's how we're treating host-based service names here:
         * two or more components.
         */

        if (argc == 0) {
            usage(1);
        } else if (argc == 1) {
            krb5_principal server2;

            /*
             * In this case the one argument is a principal name, not the
             * service name.
             *
             * We parse the argument as a principal name, extract the service
             * and hostname components, use krb5_sname_to_principal(), then
             * extract the service and hostname components from that.
             */

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

            /*
             * If a single-component principal name is given, then we'll
             * default the hostname, as krb5_principal_get_comp_string()
             * returns NULL in this case.
             */
            hname = krb5_principal_get_comp_string(context, server, 1);

	    ret = krb5_sname_to_principal(context, hname, sname,
					   KRB5_NT_SRV_HST, &server2);
            sname = krb5_principal_get_comp_string(context, server2, 0);
            hname = krb5_principal_get_comp_string(context, server2, 1);

            /*
             * Modify the original with the new sname/hname.  This way we
             * retain any additional principal name components from the given
             * principal name.
             *
             * The name-type is set further below.
             */
            ret = krb5_principal_set_comp_string(context, server, 0, sname);
            if (ret)
                krb5_err(context, 1, ret, "krb5_principal_set_comp_string %s", argv[0]);
            ret = krb5_principal_set_comp_string(context, server, 1, hname);
            if (ret)
                krb5_err(context, 1, ret, "krb5_principal_set_comp_string %s", argv[0]);
            krb5_free_principal(context, server2);
        } else {
            size_t i;

            /*
             * In this case the arguments are principal name components.
             *
             * The service and hostname components can be defaulted by passing
             * empty strings.
             */
	    sname = argv[0];
            if (*sname == '\0')
                sname = NULL;
	    hname = argv[1];
            if (hname == NULL || *hname == '\0')
                hname = NULL;
	    ret = krb5_sname_to_principal(context, hname, sname,
                                          KRB5_NT_SRV_HST, &server);
	    if (ret)
		krb5_err(context, 1, ret, "krb5_sname_to_principal");

            for (i = 2; i < argc; i++) {
                ret = krb5_principal_set_comp_string(context, server, i, argv[i]);
                if (ret)
                    krb5_err(context, 1, ret, "krb5_principal_set_comp_string");
            }
	}
    } else if (argc == 1) {
	ret = krb5_parse_name(context, argv[0], &server);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_parse_name %s", argv[0]);
    } else {
	usage(1);
    }

    if (nametype != KRB5_NT_UNKNOWN)
        server->name.name_type = (NAME_TYPE)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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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, N_("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 (canonicalize_flag)
	krb5_get_creds_opt_add_options(context, opt, KRB5_GC_CANONICALIZE);

    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_message(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) {
	int32_t nametype;

	ret = krb5_parse_nametype(context, nametype_str, &nametype);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_parse_nametype");

	server->name.name_type = (NAME_TYPE)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;
}
Exemplo n.º 10
0
/* Determines Encryption and Salt types,
 * allocates key_salt data storage,
 * filters out equivalent encodings,
 * returns 0 if no enctypes available, >0 if enctypes are available */
static int prep_ksdata(krb5_context krbctx, const char *str,
                       struct keys_container *keys,
                       char **err_msg)
{
    struct krb_key_salt *ksdata;
    krb5_error_code krberr;
    int n, i, j, nkeys;

    *err_msg = NULL;

    if (str == NULL) {
        krb5_enctype *ktypes;

        krberr = krb5_get_permitted_enctypes(krbctx, &ktypes);
        if (krberr) {
            *err_msg = _("No system preferred enctypes ?!\n");
            return 0;
        }

        for (n = 0; ktypes[n]; n++) /* count */ ;

        ksdata = calloc(n + 1, sizeof(struct krb_key_salt));
        if (NULL == ksdata) {
            *err_msg = _("Out of memory!?\n");
            return 0;
        }

        for (i = 0; i < n; i++) {
            ksdata[i].enctype = ktypes[i];
            ksdata[i].salttype = KRB5_KDB_SALTTYPE_NORMAL;
        }

        ipa_krb5_free_ktypes(krbctx, ktypes);

        nkeys = i;

    } else {
        char *tmp, *t, *p, *q;

        t = tmp = strdup(str);
        if (!tmp) {
            *err_msg = _("Out of memory\n");
            return 0;
        }

        /* count */
        n = 0;
        while ((p = strchr(t, ','))) {
            t = p+1;
            n++;
        }
        n++; /* count the last one that is 0 terminated instead */

        /* at the end we will have at most n entries + 1 terminating */
        ksdata = calloc(n + 1, sizeof(struct krb_key_salt));
        if (!ksdata) {
            *err_msg = _("Out of memory\n");
            return 0;
        }

        for (i = 0, j = 0, t = tmp; i < n; i++) {

            p = strchr(t, ',');
            if (p) *p = '\0';

            q = strchr(t, ':');
            if (q) *q++ = '\0';

            krberr = krb5_string_to_enctype(t, &ksdata[j].enctype);
            if (krberr != 0) {
                *err_msg = _("Warning unrecognized encryption type.\n");
                if (p) t = p + 1;
                continue;
            }
            if (p) t = p + 1;

            if (!q) {
                ksdata[j].salttype = KRB5_KDB_SALTTYPE_NORMAL;
                j++;
                continue;
            }

            krberr = krb5_string_to_salttype(q, &ksdata[j].salttype);
            if (krberr != 0) {
                *err_msg = _("Warning unrecognized salt type.\n");
                continue;
            }

            j++;
        }

        nkeys = j;

        free(tmp);
    }

    /* Check we don't already have a key with a similar encoding,
     * it would just produce redundant data and this is what the
     * MIT code do anyway */

    for (i = 0, n = 0; i < nkeys; i++ ) {
        krb5_boolean similar = 0;

        for (j = 0; j < i; j++) {
            krberr = krb5_c_enctype_compare(krbctx,
                                            ksdata[j].enctype,
                                            ksdata[i].enctype,
                                            &similar);
            if (krberr) {
                free_keys_contents(krbctx, keys);
                free(ksdata);
                *err_msg = _("Enctype comparison failed!\n");
                return 0;
            }
            if (similar &&
                (ksdata[j].salttype == ksdata[i].salttype)) {
                break;
            }
        }
        if (j < i) {
            /* redundant encoding, remove it, and shift others */
            int x;
            for (x = i; x < nkeys-1; x++) {
                ksdata[x].enctype = ksdata[x+1].enctype;
                ksdata[x].salttype = ksdata[x+1].salttype;
            }
            continue;
        }
        /* count only confirmed enc/salt tuples */
        n++;
    }

    keys->nkeys = n;
    keys->ksdata = ksdata;

    return n;
}
Exemplo n.º 11
0
int
main(int argc, char **argv)
{
    int optind = 0;
    OM_uint32 min_stat, maj_stat;
    gss_ctx_id_t cctx, sctx;
    void *ctx;
    gss_OID nameoid, mechoid, actual_mech, actual_mech2;
    gss_cred_id_t client_cred = GSS_C_NO_CREDENTIAL, deleg_cred = GSS_C_NO_CREDENTIAL;
    gss_name_t cname = GSS_C_NO_NAME;
    gss_buffer_desc credential_data = GSS_C_EMPTY_BUFFER;

    setprogname(argv[0]);

    init_o2n();

    if (krb5_init_context(&context))
	errx(1, "krb5_init_context");

    cctx = sctx = GSS_C_NO_CONTEXT;

    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);

    if (dns_canon_flag != -1)
	gsskrb5_set_dns_canonicalize(dns_canon_flag);

    if (type_string == NULL)
	nameoid = GSS_C_NT_HOSTBASED_SERVICE;
    else if (strcmp(type_string, "hostbased-service") == 0)
	nameoid = GSS_C_NT_HOSTBASED_SERVICE;
    else if (strcmp(type_string, "krb5-principal-name") == 0)
	nameoid = GSS_KRB5_NT_PRINCIPAL_NAME;
    else
	errx(1, "%s not suppported", type_string);

    if (mech_string == NULL)
	mechoid = GSS_KRB5_MECHANISM;
    else
	mechoid = string_to_oid(mech_string);

    if (gsskrb5_acceptor_identity) {
	maj_stat = gsskrb5_register_acceptor_identity(gsskrb5_acceptor_identity);
	if (maj_stat)
	    errx(1, "gsskrb5_acceptor_identity: %s",
		 gssapi_err(maj_stat, 0, GSS_C_NO_OID));
    }

    if (client_password) {
	credential_data.value = client_password;
	credential_data.length = strlen(client_password);
    }

    if (client_name) {
	gss_buffer_desc cn;

	cn.value = client_name;
	cn.length = strlen(client_name);

	maj_stat = gss_import_name(&min_stat, &cn, GSS_C_NT_USER_NAME, &cname);
	if (maj_stat)
	    errx(1, "gss_import_name: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    }

    if (client_password) {
	maj_stat = gss_acquire_cred_with_password(&min_stat,
						  cname,
						  &credential_data,
						  GSS_C_INDEFINITE,
						  GSS_C_NO_OID_SET,
						  GSS_C_INITIATE,
						  &client_cred,
						  NULL,
						  NULL);
	if (GSS_ERROR(maj_stat))
	    errx(1, "gss_acquire_cred_with_password: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    } else {
	maj_stat = gss_acquire_cred(&min_stat,
				    cname,
				    GSS_C_INDEFINITE,
				    GSS_C_NO_OID_SET,
				    GSS_C_INITIATE,
				    &client_cred,
				    NULL,
				    NULL);
	if (GSS_ERROR(maj_stat))
	    errx(1, "gss_acquire_cred: %s",
		 gssapi_err(maj_stat, min_stat, GSS_C_NO_OID));
    }

    if (limit_enctype_string) {
	krb5_error_code ret;

	ret = krb5_string_to_enctype(context,
				     limit_enctype_string,
				     &limit_enctype);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_string_to_enctype");
    }


    if (limit_enctype) {
	if (client_cred == NULL)
	    errx(1, "client_cred missing");

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

    loop(mechoid, nameoid, argv[0], client_cred,
	 &sctx, &cctx, &actual_mech, &deleg_cred);

    if (verbose_flag)
	printf("resulting mech: %s\n", oid_to_string(actual_mech));

    if (ret_mech_string) {
	gss_OID retoid;

	retoid = string_to_oid(ret_mech_string);

	if (gss_oid_equal(retoid, actual_mech) == 0)
	    errx(1, "actual_mech mech is not the expected type %s",
		 ret_mech_string);
    }

    /* XXX should be actual_mech */
    if (gss_oid_equal(mechoid, GSS_KRB5_MECHANISM)) {
	time_t time;
	gss_buffer_desc authz_data;
	gss_buffer_desc in, out1, out2;
	krb5_keyblock *keyblock, *keyblock2;
	krb5_timestamp now;
	krb5_error_code ret;

	ret = krb5_timeofday(context, &now);
	if (ret)
	    errx(1, "krb5_timeofday failed");

	/* client */
	maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
						     &cctx,
						     1, /* version */
						     &ctx);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
		 gssapi_err(maj_stat, min_stat, actual_mech));


	maj_stat = gss_krb5_free_lucid_sec_context(&maj_stat, ctx);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	/* server */
	maj_stat = gss_krb5_export_lucid_sec_context(&min_stat,
						     &sctx,
						     1, /* version */
						     &ctx);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_krb5_export_lucid_sec_context failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));
	maj_stat = gss_krb5_free_lucid_sec_context(&min_stat, ctx);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gss_krb5_free_lucid_sec_context failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

 	maj_stat = gsskrb5_extract_authtime_from_sec_context(&min_stat,
							     sctx,
							     &time);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gsskrb5_extract_authtime_from_sec_context failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	if (time > now)
	    errx(1, "gsskrb5_extract_authtime_from_sec_context failed: "
		 "time authtime is before now: %ld %ld",
		 (long)time, (long)now);

 	maj_stat = gsskrb5_extract_service_keyblock(&min_stat,
						    sctx,
						    &keyblock);
	if (maj_stat != GSS_S_COMPLETE)
	    errx(1, "gsskrb5_export_service_keyblock failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	krb5_free_keyblock(context, keyblock);

 	maj_stat = gsskrb5_get_subkey(&min_stat,
				      sctx,
				      &keyblock);
	if (maj_stat != GSS_S_COMPLETE
	    && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
	    errx(1, "gsskrb5_get_subkey server failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	if (maj_stat != GSS_S_COMPLETE)
	    keyblock = NULL;
	else if (limit_enctype && keyblock->keytype != limit_enctype)
	    errx(1, "gsskrb5_get_subkey wrong enctype");

 	maj_stat = gsskrb5_get_subkey(&min_stat,
				      cctx,
				      &keyblock2);
	if (maj_stat != GSS_S_COMPLETE
	    && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
	    errx(1, "gsskrb5_get_subkey client failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	if (maj_stat != GSS_S_COMPLETE)
	    keyblock2 = NULL;
	else if (limit_enctype && keyblock->keytype != limit_enctype)
	    errx(1, "gsskrb5_get_subkey wrong enctype");

	if (keyblock || keyblock2) {
	    if (keyblock == NULL)
		errx(1, "server missing token keyblock");
	    if (keyblock2 == NULL)
		errx(1, "client missing token keyblock");

	    if (keyblock->keytype != keyblock2->keytype)
		errx(1, "enctype mismatch");
	    if (keyblock->keyvalue.length != keyblock2->keyvalue.length)
		errx(1, "key length mismatch");
	    if (memcmp(keyblock->keyvalue.data, keyblock2->keyvalue.data,
		       keyblock2->keyvalue.length) != 0)
		errx(1, "key data mismatch");
	}

	if (session_enctype_string) {
	    krb5_enctype enctype;

	    ret = krb5_string_to_enctype(context,
					 session_enctype_string,
					 &enctype);

	    if (ret)
		krb5_err(context, 1, ret, "krb5_string_to_enctype");

	    if (enctype != keyblock->keytype)
		errx(1, "keytype is not the expected %d != %d",
		     (int)enctype, (int)keyblock2->keytype);
	}

	if (keyblock)
	    krb5_free_keyblock(context, keyblock);
	if (keyblock2)
	    krb5_free_keyblock(context, keyblock2);

 	maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
						sctx,
						&keyblock);
	if (maj_stat != GSS_S_COMPLETE
	    && (!(maj_stat == GSS_S_FAILURE && min_stat == GSS_KRB5_S_KG_NO_SUBKEY)))
	    errx(1, "gsskrb5_get_initiator_subkey failed: %s",
		     gssapi_err(maj_stat, min_stat, actual_mech));

	if (maj_stat == GSS_S_COMPLETE) {

	    if (limit_enctype && keyblock->keytype != limit_enctype)
		errx(1, "gsskrb5_get_initiator_subkey wrong enctype");
	    krb5_free_keyblock(context, keyblock);
	}

 	maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
							       sctx,
							       128,
							       &authz_data);
	if (maj_stat == GSS_S_COMPLETE)
	    gss_release_buffer(&min_stat, &authz_data);


	memset(&out1, 0, sizeof(out1));
	memset(&out2, 0, sizeof(out2));

	in.value = "foo";
	in.length = 3;

	gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
			  100, &out1);
	gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_FULL, &in,
			  100, &out2);

	if (out1.length != out2.length)
	    errx(1, "prf len mismatch");
	if (memcmp(out1.value, out2.value, out1.length) != 0)
	    errx(1, "prf data mismatch");

	gss_release_buffer(&min_stat, &out1);

	gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_FULL, &in,
			  100, &out1);

	if (out1.length != out2.length)
	    errx(1, "prf len mismatch");
	if (memcmp(out1.value, out2.value, out1.length) != 0)
	    errx(1, "prf data mismatch");

	gss_release_buffer(&min_stat, &out1);
	gss_release_buffer(&min_stat, &out2);

	in.value = "bar";
	in.length = 3;

	gss_pseudo_random(&min_stat, sctx, GSS_C_PRF_KEY_PARTIAL, &in,
			  100, &out1);
	gss_pseudo_random(&min_stat, cctx, GSS_C_PRF_KEY_PARTIAL, &in,
			  100, &out2);

	if (out1.length != out2.length)
	    errx(1, "prf len mismatch");
	if (memcmp(out1.value, out2.value, out1.length) != 0)
	    errx(1, "prf data mismatch");

	gss_release_buffer(&min_stat, &out1);
	gss_release_buffer(&min_stat, &out2);

	wrapunwrap_flag = 1;
	getverifymic_flag = 1;
    }

    if (wrapunwrap_flag) {
	wrapunwrap(cctx, sctx, 0, actual_mech);
	wrapunwrap(cctx, sctx, 1, actual_mech);
	wrapunwrap(sctx, cctx, 0, actual_mech);
	wrapunwrap(sctx, cctx, 1, actual_mech);
    }

    if (iov_flag) {
	wrapunwrap_iov(cctx, sctx, 0, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);

	wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|USE_SIGN_ONLY|FORCE_IOV, actual_mech);

/* works */
	wrapunwrap_iov(cctx, sctx, 0, actual_mech);
	wrapunwrap_iov(cctx, sctx, FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_CONF, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_SIGN_ONLY|FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_SIGN_ONLY|FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_HEADER_ONLY|FORCE_IOV, actual_mech);

	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY, actual_mech);
	wrapunwrap_iov(cctx, sctx, USE_CONF|USE_HEADER_ONLY|FORCE_IOV, actual_mech);
    }

    if (getverifymic_flag) {
	getverifymic(cctx, sctx, actual_mech);
	getverifymic(cctx, sctx, actual_mech);
	getverifymic(sctx, cctx, actual_mech);
	getverifymic(sctx, cctx, actual_mech);
    }


    gss_delete_sec_context(&min_stat, &cctx, NULL);
    gss_delete_sec_context(&min_stat, &sctx, NULL);

    if (deleg_cred != GSS_C_NO_CREDENTIAL) {
	gss_cred_id_t cred2 = GSS_C_NO_CREDENTIAL;
	gss_buffer_desc cb;

	if (verbose_flag)
	    printf("checking actual mech (%s) on delegated cred\n",
		   oid_to_string(actual_mech));
	loop(actual_mech, nameoid, argv[0], deleg_cred, &sctx, &cctx, &actual_mech2, &cred2);

	gss_delete_sec_context(&min_stat, &cctx, NULL);
	gss_delete_sec_context(&min_stat, &sctx, NULL);

	gss_release_cred(&min_stat, &cred2);

	/* try again using SPNEGO */
	if (verbose_flag)
	    printf("checking spnego on delegated cred\n");
	loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], deleg_cred, &sctx, &cctx,
	     &actual_mech2, &cred2);

	gss_delete_sec_context(&min_stat, &cctx, NULL);
	gss_delete_sec_context(&min_stat, &sctx, NULL);

	gss_release_cred(&min_stat, &cred2);

	/* check export/import */
	if (ei_flag) {

	    maj_stat = gss_export_cred(&min_stat, deleg_cred, &cb);
	    if (maj_stat != GSS_S_COMPLETE)
		errx(1, "export failed: %s",
		     gssapi_err(maj_stat, min_stat, NULL));

	    maj_stat = gss_import_cred(&min_stat, &cb, &cred2);
	    if (maj_stat != GSS_S_COMPLETE)
		errx(1, "import failed: %s",
		     gssapi_err(maj_stat, min_stat, NULL));

	    gss_release_buffer(&min_stat, &cb);
	    gss_release_cred(&min_stat, &deleg_cred);

	    if (verbose_flag)
		printf("checking actual mech (%s) on export/imported cred\n",
		       oid_to_string(actual_mech));
	    loop(actual_mech, nameoid, argv[0], cred2, &sctx, &cctx,
		 &actual_mech2, &deleg_cred);

	    gss_release_cred(&min_stat, &deleg_cred);

	    gss_delete_sec_context(&min_stat, &cctx, NULL);
	    gss_delete_sec_context(&min_stat, &sctx, NULL);

	    /* try again using SPNEGO */
	    if (verbose_flag)
		printf("checking SPNEGO on export/imported cred\n");
	    loop(GSS_SPNEGO_MECHANISM, nameoid, argv[0], cred2, &sctx, &cctx,
		 &actual_mech2, &deleg_cred);

	    gss_release_cred(&min_stat, &deleg_cred);

	    gss_delete_sec_context(&min_stat, &cctx, NULL);
	    gss_delete_sec_context(&min_stat, &sctx, NULL);

	    gss_release_cred(&min_stat, &cred2);

	} else  {
	    gss_release_cred(&min_stat, &deleg_cred);
	}

    }

    empty_release();

    krb5_free_context(context);

    return 0;
}
Exemplo n.º 12
0
static krb5_error_code
parse_key_set(krb5_context context, const char *key,
	      krb5_enctype **ret_enctypes, size_t *ret_num_enctypes,
	      krb5_salt *salt, krb5_principal principal)
{
    const char *p;
    char buf[3][256];
    int num_buf = 0;
    int i, num_enctypes = 0;
    krb5_enctype e;
    const krb5_enctype *enctypes = NULL;
    krb5_error_code ret;

    p = key;

    *ret_enctypes = NULL;
    *ret_num_enctypes = 0;

    /* split p in a list of :-separated strings */
    for(num_buf = 0; num_buf < 3; num_buf++)
	if(strsep_copy(&p, ":", buf[num_buf], sizeof(buf[num_buf])) == -1)
	    break;

    salt->saltvalue.data = NULL;
    salt->saltvalue.length = 0;

    for(i = 0; i < num_buf; i++) {
	if(enctypes == NULL && num_buf > 1) {
	    /* this might be a etype specifier */
	    /* XXX there should be a string_to_etypes handling
	       special cases like `des' and `all' */
	    if(strcmp(buf[i], "des") == 0) {
		enctypes = des_etypes;
		num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]);
	    } else if(strcmp(buf[i], "des3") == 0) {
		e = ETYPE_DES3_CBC_SHA1;
		enctypes = &e;
		num_enctypes = 1;
	    } else {
		ret = krb5_string_to_enctype(context, buf[i], &e);
		if (ret == 0) {
		    enctypes = &e;
		    num_enctypes = 1;
		} else
		    return ret;
	    }
	    continue;
	}
	if(salt->salttype == 0) {
	    /* interpret string as a salt specifier, if no etype
	       is set, this sets default values */
	    /* XXX should perhaps use string_to_salttype, but that
	       interface sucks */
	    if(strcmp(buf[i], "pw-salt") == 0) {
		if(enctypes == NULL) {
		    enctypes = all_etypes;
		    num_enctypes = sizeof(all_etypes)/sizeof(all_etypes[0]);
		}
		salt->salttype = KRB5_PW_SALT;
	    } else if(strcmp(buf[i], "afs3-salt") == 0) {
		if(enctypes == NULL) {
		    enctypes = des_etypes;
		    num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]);
		}
		salt->salttype = KRB5_AFS3_SALT;
	    }
	    continue;
	}

	{
	    /* if there is a final string, use it as the string to
	       salt with, this is mostly useful with null salt for
	       v4 compat, and a cell name for afs compat */
	    salt->saltvalue.data = strdup(buf[i]);
	    if (salt->saltvalue.data == NULL) {
		krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
		return ENOMEM;
	    }
	    salt->saltvalue.length = strlen(buf[i]);
	}
    }

    if(enctypes == NULL || salt->salttype == 0) {
	krb5_set_error_message(context, EINVAL, "bad value for default_keys `%s'", key);
	return EINVAL;
    }

    /* if no salt was specified make up default salt */
    if(salt->saltvalue.data == NULL) {
	if(salt->salttype == KRB5_PW_SALT)
	    ret = krb5_get_pw_salt(context, principal, salt);
	else if(salt->salttype == KRB5_AFS3_SALT) {
	    krb5_const_realm realm = krb5_principal_get_realm(context, principal);
	    salt->saltvalue.data = strdup(realm);
	    if(salt->saltvalue.data == NULL) {
		krb5_set_error_message(context, ENOMEM,
				       "out of memory while "
				       "parsing salt specifiers");
		return ENOMEM;
	    }
	    strlwr(salt->saltvalue.data);
	    salt->saltvalue.length = strlen(realm);
	}
    }

    *ret_enctypes = malloc(sizeof(enctypes[0]) * num_enctypes);
    if (*ret_enctypes == NULL) {
	krb5_free_salt(context, *salt);
	krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
	return ENOMEM;
    }
    memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes);
    *ret_num_enctypes = num_enctypes;

    return 0;
}
Exemplo n.º 13
0
void
initialize_realms(krb5_context kcontext, int argc, char **argv)
{
    int 		c;
    char		*db_name = (char *) NULL;
    char		*mkey_name = (char *) NULL;
    char		*rcname = KDCRCACHE;
    char		*lrealm = NULL;
    krb5_error_code	retval;
    krb5_enctype	menctype = ENCTYPE_UNKNOWN;
    kdc_realm_t		*rdatap;
    krb5_boolean	manual = FALSE;
    char		*default_udp_ports = 0;
    char		*default_tcp_ports = 0;
    krb5_pointer	aprof;
    const char		*hierarchy[3];
    char               **db_args      = NULL;
    int                  db_args_size = 0;

#ifdef KRB5_KRB4_COMPAT
    char                *v4mode = 0;
#endif
    extern char *optarg;

    if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
	hierarchy[0] = "kdcdefaults";
	hierarchy[1] = "kdc_ports";
	hierarchy[2] = (char *) NULL;
	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
	    default_udp_ports = 0;
	hierarchy[1] = "kdc_tcp_ports";
	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
	    default_tcp_ports = 0;
	hierarchy[1] = "kdc_max_tcp_connections";
	if (krb5_aprof_get_int32(aprof, hierarchy, TRUE,
		&max_tcp_data_connections)) {
	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
	} else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) {
	    max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS;
	}
#ifdef KRB5_KRB4_COMPAT
	hierarchy[1] = "v4_mode";
	if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
	    v4mode = 0;
#endif
	/* aprof_init can return 0 with aprof == NULL */
	if (aprof)
	     krb5_aprof_finish(aprof);
    }
    if (default_udp_ports == 0)
	default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
    if (default_tcp_ports == 0)
	default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
    /*
     * Loop through the option list.  Each time we encounter a realm name,
     * use the previously scanned options to fill in for defaults.
     */
    while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
	switch(c) {
	case 'x':
	    db_args_size++;
	    {
		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
		if( temp == NULL )
		{
			/* Solaris Kerberos: Keep error messages consistent */
		    com_err(argv[0], errno, gettext("while initializing KDC"));
		    exit(1);
		}

		db_args = temp;
	    }
	    db_args[db_args_size-1] = optarg;
	    db_args[db_args_size]   = NULL;
	  break;

	case 'r':			/* realm name for db */
	    if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
		if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
		    if ((retval = init_realm(kcontext, argv[0], rdatap, optarg, 
					     mkey_name, menctype,
					     default_udp_ports,
					     default_tcp_ports, manual, db_args))) {
			/* Solaris Kerberos: Keep error messages consistent */
			com_err(argv[0], retval, gettext("while initializing realm %s"), optarg);
			exit(1);
		    }
		    kdc_realmlist[kdc_numrealms] = rdatap;
		    kdc_numrealms++;
		    free(db_args), db_args=NULL, db_args_size = 0;
		}
		else
		{
			/* Solaris Kerberos: Keep error messages consistent */
			com_err(argv[0], errno, gettext("while initializing realm %s"), optarg);
			exit(1);
		}
	    }
	    break;
	case 'd':			/* pathname for db */
	    /* now db_name is not a seperate argument. It has to be passed as part of the db_args */
	    if( db_name == NULL )
	    {
		db_name = malloc(sizeof("dbname=") + strlen(optarg));
		if( db_name == NULL )
		{
			/* Solaris Kerberos: Keep error messages consistent */
			com_err(argv[0], errno, gettext("while initializing KDC"));
			exit(1);
		}

		sprintf( db_name, "dbname=%s", optarg);
	    }

	    db_args_size++;
	    {
		char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
		if( temp == NULL )
		{
			/* Solaris Kerberos: Keep error messages consistent */
		    com_err(argv[0], errno, gettext("while initializing KDC"));
		    exit(1);
		}

		db_args = temp;
	    }
	    db_args[db_args_size-1] = db_name;
	    db_args[db_args_size]   = NULL;
	    break;
	case 'm':			/* manual type-in of master key */
	    manual = TRUE;
	    if (menctype == ENCTYPE_UNKNOWN)
		menctype = ENCTYPE_DES_CBC_CRC;
	    break;
	case 'M':			/* master key name in DB */
	    mkey_name = optarg;
	    break;
	case 'n':
	    nofork++;			/* don't detach from terminal */
	    break;
	case 'k':			/* enctype for master key */
		/* Solaris Kerberos: Keep error messages consistent */
	    if (retval = krb5_string_to_enctype(optarg, &menctype))
		com_err(argv[0], retval,
		    gettext("while converting %s to an enctype"), optarg);
	    break;
	case 'R':
	    rcname = optarg;
	    break;
	case 'p':
	    if (default_udp_ports)
		free(default_udp_ports);
	    default_udp_ports = strdup(optarg);

	    if (default_tcp_ports)
		free(default_tcp_ports);
	    default_tcp_ports = strdup(optarg);

	    break;
	case '4':
#ifdef KRB5_KRB4_COMPAT
	    if (v4mode)
		free(v4mode);
	    v4mode = strdup(optarg);
#endif
	    break;
	case 'X':
#ifdef KRB5_KRB4_COMPAT
		enable_v4_crossrealm(argv[0]);
#endif
		break;
	case '?':
	default:
	    usage(argv[0]);
	    exit(1);
	}
    }

#ifdef KRB5_KRB4_COMPAT
    /*
     * Setup the v4 mode 
     */
    process_v4_mode(argv[0], v4mode);
    free(v4mode);
#endif

    /*
     * Check to see if we processed any realms.
     */
    if (kdc_numrealms == 0) {
	/* no realm specified, use default realm */
	if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
	    com_err(argv[0], retval,
		gettext("while attempting to retrieve default realm"));
	/* Solaris Kerberos: avoid double logging */
#if 0
	    fprintf (stderr, "%s: %s, %s", argv[0], error_message (retval),
		gettext("attempting to retrieve default realm\n"));
#endif
	    exit(1);
	}
	if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
	    if ((retval = init_realm(kcontext, argv[0], rdatap, lrealm, 
				     mkey_name, menctype, default_udp_ports,
				     default_tcp_ports, manual, db_args))) {
		/* Solaris Kerberos: Keep error messages consistent */
		com_err(argv[0], retval, gettext("while initializing realm %s"), lrealm);
		exit(1);
	    }
	    kdc_realmlist[0] = rdatap;
	    kdc_numrealms++;
	} else {
    	    if (lrealm)
		free(lrealm);
	}
    }

#ifdef USE_RCACHE
    /*
     * Now handle the replay cache.
     */
    if ((retval = kdc_initialize_rcache(kcontext, rcname))) {
	com_err(argv[0], retval, gettext("while initializing KDC replay cache '%s'"),
		rcname);
	exit(1);
    }
#endif

    /* Ensure that this is set for our first request. */
    kdc_active_realm = kdc_realmlist[0];

    if (default_udp_ports)
	free(default_udp_ports);
    if (default_tcp_ports)
	free(default_tcp_ports);
    if (db_args)
	free(db_args);
    if (db_name)
	free(db_name);

    return;
}
Exemplo n.º 14
0
void
kdb5_add_mkey(int argc, char *argv[])
{
    int optchar;
    krb5_error_code retval;
    char *mkey_fullname;
    char *pw_str = 0;
    unsigned int pw_size = 0;
    int do_stash = 0;
    krb5_data pwd;
    krb5_kvno new_mkey_kvno;
    krb5_keyblock new_mkeyblock;
    krb5_enctype new_master_enctype = ENCTYPE_UNKNOWN;
    char *new_mkey_password;
    krb5_db_entry *master_entry;
    krb5_timestamp now;

    /*
     * The command table entry for this command causes open_db_and_mkey() to be
     * called first to open the KDB and get the current mkey.
     */

    memset(&new_mkeyblock, 0, sizeof(new_mkeyblock));
    memset(&master_princ, 0, sizeof(master_princ));
    master_salt.data = NULL;

    while ((optchar = getopt(argc, argv, "e:s")) != -1) {
        switch(optchar) {
        case 'e':
            if (krb5_string_to_enctype(optarg, &new_master_enctype)) {
                com_err(progname, EINVAL, _("%s is an invalid enctype"),
                        optarg);
                exit_status++;
                return;
            }
            break;
        case 's':
            do_stash++;
            break;
        case '?':
        default:
            usage();
            return;
        }
    }

    if (new_master_enctype == ENCTYPE_UNKNOWN)
        new_master_enctype = global_params.enctype;

    /* assemble & parse the master key name */
    if ((retval = krb5_db_setup_mkey_name(util_context,
                                          global_params.mkey_name,
                                          global_params.realm,
                                          &mkey_fullname, &master_princ))) {
        com_err(progname, retval, _("while setting up master key name"));
        exit_status++;
        return;
    }

    retval = krb5_db_get_principal(util_context, master_princ, 0,
                                   &master_entry);
    if (retval != 0) {
        com_err(progname, retval, _("while getting master key principal %s"),
                mkey_fullname);
        exit_status++;
        goto cleanup_return;
    }

    printf(_("Creating new master key for master key principal '%s'\n"),
           mkey_fullname);

    printf(_("You will be prompted for a new database Master Password.\n"));
    printf(_("It is important that you NOT FORGET this password.\n"));
    fflush(stdout);

    pw_size = 1024;
    pw_str = malloc(pw_size);
    if (pw_str == NULL) {
        com_err(progname, ENOMEM, _("while creating new master key"));
        exit_status++;
        goto cleanup_return;
    }

    retval = krb5_read_password(util_context, KRB5_KDC_MKEY_1, KRB5_KDC_MKEY_2,
                                pw_str, &pw_size);
    if (retval) {
        com_err(progname, retval,
                _("while reading new master key from keyboard"));
        exit_status++;
        goto cleanup_return;
    }
    new_mkey_password = pw_str;

    pwd.data = new_mkey_password;
    pwd.length = strlen(new_mkey_password);
    retval = krb5_principal2salt(util_context, master_princ, &master_salt);
    if (retval) {
        com_err(progname, retval, _("while calculating master key salt"));
        exit_status++;
        goto cleanup_return;
    }

    retval = krb5_c_string_to_key(util_context, new_master_enctype,
                                  &pwd, &master_salt, &new_mkeyblock);
    if (retval) {
        com_err(progname, retval,
                _("while transforming master key from password"));
        exit_status++;
        goto cleanup_return;
    }

    new_mkey_kvno = get_next_kvno(util_context, master_entry);
    retval = add_new_mkey(util_context, master_entry, &new_mkeyblock,
                          new_mkey_kvno);
    if (retval) {
        com_err(progname, retval,
                _("adding new master key to master principal"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_timeofday(util_context, &now))) {
        com_err(progname, retval, _("while getting current time"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_dbe_update_mod_princ_data(util_context, master_entry,
                                                 now, master_princ))) {
        com_err(progname, retval, _("while updating the master key principal "
                                    "modification time"));
        exit_status++;
        goto cleanup_return;
    }

    if ((retval = krb5_db_put_principal(util_context, master_entry))) {
        (void) krb5_db_fini(util_context);
        com_err(progname, retval, _("while adding master key entry to the "
                                    "database"));
        exit_status++;
        goto cleanup_return;
    }

    if (do_stash) {
        retval = krb5_db_store_master_key(util_context,
                                          global_params.stash_file,
                                          master_princ,
                                          new_mkey_kvno,
                                          &new_mkeyblock,
                                          mkey_password);
        if (retval) {
            com_err(progname, errno, _("while storing key"));
            printf(_("Warning: couldn't stash master key.\n"));
        }
    }

cleanup_return:
    /* clean up */
    (void) krb5_db_fini(util_context);
    zap((char *)master_keyblock.contents, master_keyblock.length);
    free(master_keyblock.contents);
    zap((char *)new_mkeyblock.contents, new_mkeyblock.length);
    free(new_mkeyblock.contents);
    if (pw_str) {
        zap(pw_str, pw_size);
        free(pw_str);
    }
    free(master_salt.data);
    krb5_free_unparsed_name(util_context, mkey_fullname);
    return;
}
Exemplo n.º 15
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    int optidx = 0;
    const char *from_name, *to_name;
    krb5_ccache from_ccache, to_ccache;
    unsigned int matched;
    struct ctx ctx;

    setprogname(argv[0]);

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

    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 || argc > 2)
	usage(1);

    if (krb5_init_context(&context))
	errx(1, "krb5_init_context failed");

    if (service_string) {
	ret = krb5_parse_name(context, service_string, &ctx.mcreds.server);
	if (ret)
	    krb5_err(context, 1, ret, "%s", service_string);
    }
    if (enctype_string) {
	krb5_enctype enctype;
	ret = krb5_string_to_enctype(context, enctype_string, &enctype);
	if (ret)
	    krb5_err(context, 1, ret, "%s", enctype_string);
	ctx.whichfields |= KRB5_TC_MATCH_KEYTYPE;
	ctx.mcreds.session.keytype = enctype;
    }
    if (flags_string) {
	parse_ticket_flags(context, flags_string, &ctx.mcreds.flags);
	ctx.whichfields |= KRB5_TC_MATCH_FLAGS;
    }
    if (valid_string) {
	time_t t = parse_time(valid_string, "s");
	if(t < 0)
	    errx(1, "unknown time \"%s\"", valid_string);
	ctx.mcreds.times.endtime = time(NULL) + t;
	ctx.whichfields |= KRB5_TC_MATCH_TIMES;
    }
    if (fcache_version)
	krb5_set_fcache_version(context, fcache_version);

    if (argc == 1) {
	from_name = krb5_cc_default_name(context);
	to_name = argv[0];
    } else {
	from_name = argv[0];
	to_name = argv[1];
    }

    ret = krb5_cc_resolve(context, from_name, &from_ccache);
    if (ret)
	krb5_err(context, 1, ret, "%s", from_name);

    if (krbtgt_only_flag) {
	krb5_principal client;
	ret = krb5_cc_get_principal(context, from_ccache, &client);
	if (ret)
	    krb5_err(context, 1, ret, "getting default principal");
	ret = krb5_make_principal(context, &ctx.mcreds.server,
				  krb5_principal_get_realm(context, client),
				  KRB5_TGS_NAME,
				  krb5_principal_get_realm(context, client),
				  NULL);
	if (ret)
	    krb5_err(context, 1, ret, "constructing krbtgt principal");
	krb5_free_principal(context, client);
    }
    ret = krb5_cc_resolve(context, to_name, &to_ccache);
    if (ret)
	krb5_err(context, 1, ret, "%s", to_name);

    ret = krb5_cc_copy_match_f(context, from_ccache, to_ccache,
			       matchfunc, &ctx, &matched);
    if (ret)
	krb5_err(context, 1, ret, "copying cred cache");

    krb5_cc_close(context, from_ccache);
    if(matched == 0)
	krb5_cc_destroy(context, to_ccache);
    else
	krb5_cc_close(context, to_ccache);
    krb5_free_context(context);
    return matched == 0;
}
Exemplo n.º 16
0
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
		       unsigned int ctx_count, krb5_enctype *ctx_list)
{
    krb5_enctype *old_ktypes = NULL;

    if (ctx_count) {
	/* application-set defaults */
	if ((old_ktypes = 
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) *
				    (ctx_count + 1)))) {
	    (void) memcpy(old_ktypes, ctx_list,
		sizeof(krb5_enctype) * ctx_count);
	    old_ktypes[ctx_count] = 0;
	} else {
	    return ENOMEM;
	}
    } else {
        /*
	   XXX - For now, we only support libdefaults
	   Perhaps this should be extended to allow for per-host / per-realm
	   session key types.
	 */

	char *retval = NULL;
	char *sp, *ep;
	int j, checked_enctypes, count;
	krb5_error_code code;

	code = profile_get_string(context->profile, "libdefaults", profstr,
				  NULL, DEFAULT_ETYPE_LIST, &retval);
	if (code)
	    return code;

	if (!retval)  /* SUNW14resync - just in case */
            return PROF_EINVAL;  /* XXX */

	count = 0;
	sp = retval;
	while (*sp) {
	    for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
		;
	    if (*ep) {
		*ep++ = '\0';
		while (isspace((int) (*ep)) || *ep == ',')
		    *ep++ = '\0';
	    }
	    count++;
	    sp = ep;
	}
	
	if ((old_ktypes =
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
	    (krb5_enctype *) NULL)
	    return ENOMEM;
	
	sp = retval;
	j = checked_enctypes = 0;
	/*CONSTCOND*/
	while (TRUE) {
	    checked_enctypes++;
	    if (krb5_string_to_enctype(sp, &old_ktypes[j]))
		old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;

	    /*
	     * If 'null' has been specified as a tkt_enctype in
	     * krb5.conf, we need to assign an ENCTYPE_UNKNOWN
	     * value to the corresponding old_ktypes[j] entry.
	     */
	    if (old_ktypes[j] == (unsigned int)ENCTYPE_NULL)
		old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN;

	    /* Only include known/valid enctypes in the final list */
	    if (old_ktypes[j] != ENCTYPE_UNKNOWN) {
		j++;
	    }
	    /* If we checked all the enctypes, we are done */
	    if (checked_enctypes == count) {
		break;
	    }

	    /* skip to next token */
	    while (*sp) sp++;
	    while (! *sp) sp++;
	}

	old_ktypes[j] = (krb5_enctype) 0;
	profile_release_string(retval);
    }

    if (old_ktypes[0] == 0) {
	free (old_ktypes);
	*ktypes = 0;
	return KRB5_CONFIG_ETYPE_NOSUPP;
    }

    *ktypes = old_ktypes;
    return 0;
}
Exemplo n.º 17
0
int
main(int argc, char **argv)
{
    char buf[1024];
    krb5_error_code ret;

    krb5_enctype enctype;

    hdb_master_key mkey;

    krb5_program_setup(&context, argc, argv, args, num_args, NULL);

    if(help_flag)
	krb5_std_usage(0, args, num_args);
    if(version_flag){
	print_version(NULL);
	exit(0);
    }

    if (master_key_fd != -1 && random_key_flag)
	krb5_errx(context, 1, "random-key and master-key-fd "
		  "is mutual exclusive");

    if (keyfile == NULL)
	asprintf(&keyfile, "%s/m-key", hdb_db_dir(context));

    ret = krb5_string_to_enctype(context, enctype_str, &enctype);
    if(ret)
	krb5_err(context, 1, ret, "krb5_string_to_enctype");

    ret = hdb_read_master_key(context, keyfile, &mkey);
    if(ret && ret != ENOENT)
	krb5_err(context, 1, ret, "reading master key from %s", keyfile);

    if (convert_flag) {
	if (ret)
	    krb5_err(context, 1, ret, "reading master key from %s", keyfile);
    } else {
	krb5_keyblock key;
	krb5_salt salt;
	salt.salttype = KRB5_PW_SALT;
	/* XXX better value? */
	salt.saltvalue.data = NULL;
	salt.saltvalue.length = 0;
	if (random_key_flag) {
	    ret = krb5_generate_random_keyblock(context, enctype, &key);
	    if (ret)
		krb5_err(context, 1, ret, "krb5_generate_random_keyblock");

	} else {
	    if(master_key_fd != -1) {
		ssize_t n;
		n = read(master_key_fd, buf, sizeof(buf));
		if(n <= 0)
		    krb5_err(context, 1, errno, "failed to read passphrase");
		buf[n] = '\0';
		buf[strcspn(buf, "\r\n")] = '\0';
		
	    } else {
		if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Master key: ", 1))
		    exit(1);
	    }
	    krb5_string_to_key_salt(context, enctype, buf, salt, &key);
	}
	ret = hdb_add_master_key(context, &key, &mkey);
	
	krb5_free_keyblock_contents(context, &key);

    }

    {
	char *new, *old;
	asprintf(&old, "%s.old", keyfile);
	asprintf(&new, "%s.new", keyfile);
	if(unlink(new) < 0 && errno != ENOENT) {
	    ret = errno;
	    goto out;
	}
	krb5_warnx(context, "writing key to `%s'", keyfile);
	ret = hdb_write_master_key(context, new, mkey);
	if(ret)
	    unlink(new);
	else {
#ifndef NO_POSIX_LINKS
	    unlink(old);
	    if(link(keyfile, old) < 0 && errno != ENOENT) {
		ret = errno;
		unlink(new);
	    } else {
#endif
		if(rename(new, keyfile) < 0) {
Exemplo n.º 18
0
static krb5_error_code
get_profile_etype_list(krb5_context context, krb5_enctype **ktypes, char *profstr,
		       unsigned int ctx_count, krb5_enctype *ctx_list)
{
    krb5_enctype *old_ktypes;

    if (ctx_count) {
	/* application-set defaults */
	if ((old_ktypes = 
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) *
				    (ctx_count + 1)))) {
	    memcpy(old_ktypes, ctx_list, sizeof(krb5_enctype) * ctx_count);
	    old_ktypes[ctx_count] = 0;
	} else {
	    return ENOMEM;
	}
    } else {
        /*
	   XXX - For now, we only support libdefaults
	   Perhaps this should be extended to allow for per-host / per-realm
	   session key types.
	 */

	char *retval;
	char *sp, *ep;
	int i, j, count;
	krb5_error_code code;

	code = profile_get_string(context->profile, "libdefaults", profstr,
				  NULL, DEFAULT_ETYPE_LIST, &retval);
	if (code)
	    return code;

	count = 0;
	sp = retval;
	while (*sp) {
	    for (ep = sp; *ep && (*ep != ',') && !isspace((int) (*ep)); ep++)
		;
	    if (*ep) {
		*ep++ = '\0';
		while (isspace((int) (*ep)) || *ep == ',')
		    *ep++ = '\0';
	    }
	    count++;
	    sp = ep;
	}
	
	if ((old_ktypes =
	     (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) ==
	    (krb5_enctype *) NULL) {
	    profile_release_string(retval);
	    return ENOMEM;
	}
	
	sp = retval;
	j = 0;
	i = 1;
	while (1) {
	    if (! krb5_string_to_enctype(sp, &old_ktypes[j]))
		j++;

	    if (i++ >= count)
		break;

	    /* skip to next token */
	    while (*sp) sp++;
	    while (! *sp) sp++;
	}

	old_ktypes[j] = (krb5_enctype) 0;
	profile_release_string(retval);
    }

    if (old_ktypes[0] == 0) {
	free (old_ktypes);
	*ktypes = 0;
	return KRB5_CONFIG_ETYPE_NOSUPP;
    }

    *ktypes = old_ktypes;
    return 0;
}
Exemplo n.º 19
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_principal princ;
    krb5_salt salt;
    int optidx;
    char buf[1024];
    krb5_enctype etype;
    krb5_error_code ret;

    optidx = krb5_program_setup(&context, argc, argv, args, num_args, NULL);

    if(help)
	usage(0);

    if(version){
	print_version (NULL);
	return 0;
    }

    argc -= optidx;
    argv += optidx;

    if (argc > 1)
	usage(1);

    if(!version5 && !version4 && !afs)
	version5 = 1;

    ret = krb5_string_to_enctype(context, keytype_str, &etype);
    if(ret)
	krb5_err(context, 1, ret, "krb5_string_to_enctype");

    if((etype != (krb5_enctype)ETYPE_DES_CBC_CRC &&
	etype != (krb5_enctype)ETYPE_DES_CBC_MD4 &&
	etype != (krb5_enctype)ETYPE_DES_CBC_MD5) &&
       (afs || version4)) {
	if(!version5) {
	    etype = ETYPE_DES_CBC_CRC;
	} else {
	    krb5_errx(context, 1,
		      "DES is the only valid keytype for AFS and Kerberos 4");
	}
    }

    if(version5 && principal == NULL){
	printf("Kerberos v5 principal: ");
	if(fgets(buf, sizeof(buf), stdin) == NULL)
	    return 1;
	buf[strcspn(buf, "\r\n")] = '\0';
	principal = estrdup(buf);
    }
    if(afs && cell == NULL){
	printf("AFS cell: ");
	if(fgets(buf, sizeof(buf), stdin) == NULL)
	    return 1;
	buf[strcspn(buf, "\r\n")] = '\0';
	cell = estrdup(buf);
    }
    if(argv[0])
	password = argv[0];
    if(password == NULL){
	if(UI_UTIL_read_pw_string(buf, sizeof(buf), "Password: "******"Kerberos 5 (%s)");
	krb5_free_salt(context, salt);
    }
    if(version4){
	salt.salttype = KRB5_PW_SALT;
	salt.saltvalue.length = 0;
	salt.saltvalue.data = NULL;
	tokey(context, ETYPE_DES_CBC_MD5, password, salt, "Kerberos 4");
    }
    if(afs){
	salt.salttype = KRB5_AFS3_SALT;
	salt.saltvalue.length = strlen(cell);
	salt.saltvalue.data = cell;
	tokey(context, ETYPE_DES_CBC_MD5, password, salt, "AFS");
    }
    return 0;
}
Exemplo n.º 20
0
Arquivo: kinit.c Projeto: aosm/Heimdal
static krb5_error_code
get_new_tickets(krb5_context context,
		krb5_principal principal,
		krb5_ccache ccache,
		krb5_deltat ticket_life,
		int interactive)
{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt;
    krb5_creds cred;
    char passwd[256];
    krb5_deltat start_time = 0;
    krb5_deltat renew = 0;
    const char *renewstr = NULL;
    krb5_enctype *enctype = NULL;
    krb5_ccache tempccache;
    krb5_init_creds_context icc;
    krb5_keytab kt = NULL;
    int will_use_keytab =  (use_keytab || keytab_str);
    krb5_prompter_fct prompter = NULL;
    int need_prompt;

    passwd[0] = '\0';

    if (password_file) {
	FILE *f;

	if (strcasecmp("STDIN", password_file) == 0)
	    f = stdin;
	else
	    f = fopen(password_file, "r");
	if (f == NULL)
	    krb5_errx(context, 1, "Failed to open the password file %s",
		      password_file);

	if (fgets(passwd, sizeof(passwd), f) == NULL)
	    krb5_errx(context, 1,
		      N_("Failed to read password from file %s", ""),
		      password_file);
	if (f != stdin)
	    fclose(f);
	passwd[strcspn(passwd, "\n")] = '\0';
    }

#if defined(__APPLE__) && !defined(__APPLE_TARGET_EMBEDDED__)
    if (passwd[0] == '\0' && !will_use_keytab && home_directory_flag) {
	const char *realm;
	OSStatus osret;
	UInt32 length;
	void *buffer;
	char *name;

	realm = krb5_principal_get_realm(context, principal);

	ret = krb5_unparse_name_flags(context, principal,
				      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret)
	    goto nopassword;

	osret = SecKeychainFindGenericPassword(NULL, (UInt32)strlen(realm), realm,
					       (UInt32)strlen(name), name,
					       &length, &buffer, &passwordItem);
	free(name);
	if (osret != noErr)
	    goto nopassword;

	if (length < sizeof(passwd) - 1) {
	    memcpy(passwd, buffer, length);
	    passwd[length] = '\0';
	}
	SecKeychainItemFreeContent(NULL, buffer);
    nopassword:
	do { } while(0);
    }
#endif

    need_prompt = !(pk_user_id || ent_user_id || anonymous_flag || will_use_keytab || passwd[0] != '\0') && interactive;
    if (need_prompt)
	prompter = krb5_prompter_posix;
    else
	prompter = krb5_prompter_print_only;

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

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

    krb5_get_init_creds_opt_set_default_flags(context, "kinit",
	krb5_principal_get_realm(context, principal), opt);

    if(forwardable_flag != -1)
	krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);

    if(proxiable_flag != -1)
	krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
    if(anonymous_flag)
	krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
    if (pac_flag != -1)
	krb5_get_init_creds_opt_set_pac_request(context, opt,
						pac_flag ? TRUE : FALSE);
    if (canonicalize_flag)
	krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
    if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
	krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
    if (pk_user_id || ent_user_id || anonymous_flag) {
	ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
						 principal,
						 pk_user_id,
						 pk_x509_anchors,
						 NULL,
						 NULL,
						 pk_use_enckey ? 2 : 0 |
						 anonymous_flag ? 4 : 0,
						 interactive ? krb5_prompter_posix : krb5_prompter_print_only,
						 NULL,
						 passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
	if (ent_user_id)
	    krb5_get_init_creds_opt_set_pkinit_user_cert(context, opt, ent_user_id);
    }

    if (addrs_flag != -1)
	krb5_get_init_creds_opt_set_addressless(context, opt,
						addrs_flag ? FALSE : TRUE);

    if (renew_life == NULL && renewable_flag)
	renewstr = "1 month";
    if (renew_life)
	renewstr = renew_life;
    if (renewstr) {
	renew = parse_time (renewstr, "s");
	if (renew < 0)
	    errx (1, "unparsable time: %s", renewstr);

	krb5_get_init_creds_opt_set_renew_life (opt, renew);
    }

    if(ticket_life != 0)
	krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life);

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

	start_time = tmp;
    }

    if(etype_str.num_strings) {
	int i;

	enctype = malloc(etype_str.num_strings * sizeof(*enctype));
	if(enctype == NULL)
	    errx(1, "out of memory");
	for(i = 0; i < etype_str.num_strings; i++) {
	    ret = krb5_string_to_enctype(context,
					 etype_str.strings[i],
					 &enctype[i]);
	    if(ret)
		krb5_err(context, 1, ret, "unrecognized enctype: %s",
			 etype_str.strings[i]);
	}
	krb5_get_init_creds_opt_set_etype_list(opt, enctype,
					       etype_str.num_strings);
    }

    ret = krb5_init_creds_init(context, principal,
			       prompter, NULL,
			       start_time, opt, &icc);
    if (ret)
	krb5_err (context, 1, ret, "krb5_init_creds_init");

    if (server_str) {
	ret = krb5_init_creds_set_service(context, icc, server_str);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_service");
    }

    if (kdc_hostname)
	krb5_init_creds_set_kdc_hostname(context, icc, kdc_hostname);

    if (fast_armor_cache_string) {
	krb5_ccache fastid;
	
	ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_cc_resolve(FAST cache)");
	
	ret = krb5_init_creds_set_fast_ccache(context, icc, fastid);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_fast_ccache");
    }

    if(will_use_keytab) {
	if(keytab_str)
	    ret = krb5_kt_resolve(context, keytab_str, &kt);
	else
	    ret = krb5_kt_default(context, &kt);
	if (ret)
	    krb5_err (context, 1, ret, "resolving keytab");

	ret = krb5_init_creds_set_keytab(context, icc, kt);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_init_creds_set_keytab");
    }

    if (passwd[0] == '\0' && need_prompt) {
	char *p, *prompt;

	krb5_unparse_name(context, principal, &p);
	asprintf (&prompt, N_("%s's Password: "******""), p);
	free(p);

	if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
	    memset(passwd, 0, sizeof(passwd));
	    errx(1, "failed to read password");
	}
	free (prompt);
    }

    if (passwd[0]) {
	ret = krb5_init_creds_set_password(context, icc, passwd);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_init_creds_set_password");
    }

    ret = krb5_init_creds_get(context, icc);

#ifdef __APPLE__
    /*
     * Save password in Keychain
     */
    if (ret == 0 && keychain_flag && passwordItem == NULL) {
	krb5_error_code ret2;
	const char *realm;
	char *name;

	realm = krb5_principal_get_realm(context, principal);
	ret2 = krb5_unparse_name_flags(context, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret2 == 0) {
	    (void)SecKeychainAddGenericPassword(NULL,
						(UInt32)strlen(realm), realm,
						(UInt32)strlen(name), name,
						(UInt32)strlen(passwd), passwd,
						NULL);
	    free(name);
	}
    }
#endif

    memset(passwd, 0, sizeof(passwd));

    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
	exit(1);
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
    case KRB5KDC_ERR_PREAUTH_FAILED:
    case KRB5_GET_IN_TKT_LOOP:
#ifdef __APPLE__
	if (passwordItem)
	    SecKeychainItemDelete(passwordItem);
#endif
	krb5_errx(context, 1, N_("Password incorrect", ""));
    case KRB5KRB_AP_ERR_V4_REPLY:
	krb5_errx(context, 1, N_("Looks like a Kerberos 4 reply", ""));
    case KRB5KDC_ERR_KEY_EXPIRED:
	krb5_errx(context, 1, N_("Password expired", ""));
    default:
	krb5_err(context, 1, ret, "krb5_get_init_creds");
    }

    ret = krb5_init_creds_get_creds(context, icc, &cred);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_get_creds");

    krb5_process_last_request(context, opt, icc);

    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
			     NULL, &tempccache);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_new_unique");

    ret = krb5_init_creds_store(context, icc, tempccache);
    if (ret)
	krb5_err(context, 1, ret, "krb5_init_creds_store");

    ret = krb5_init_creds_store_config(context, icc, tempccache);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_store_config");

    ret = krb5_init_creds_warn_user(context, icc);
    if (ret)
	krb5_warn(context, ret, "krb5_init_creds_warn_user");

#ifdef __APPLE__
    /*
     * Set for this case, default to * so that all processes can use
     * this cache.
     */
    {
	heim_array_t bundleacl = heim_array_create();
	heim_string_t ace;

	if (bundle_acl_strings.num_strings > 0) {
	    int i;
	    for (i = 0; i < bundle_acl_strings.num_strings; i++) {
		ace = heim_string_create(bundle_acl_strings.strings[i]);
		heim_array_append_value(bundleacl, ace);
		heim_release(ace);
	    }
	} else {
	    ace = heim_string_create("*");
	    heim_array_append_value(bundleacl, ace);
	    heim_release(ace);
	}
	krb5_cc_set_acl(context, tempccache, "kHEIMAttrBundleIdentifierACL", bundleacl);
	heim_release(bundleacl);
    }
#endif

    ret = krb5_cc_move(context, tempccache, ccache);
    if (ret) {
	(void)krb5_cc_destroy(context, tempccache);
	krb5_err (context, 1, ret, "krb5_cc_move");
    }

    if (switch_cache_flags)
	krb5_cc_switch(context, ccache);

    if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
	unsigned char d = 0;
	krb5_data data;

	if (ok_as_delegate_flag || windows_flag)
	    d |= 1;
	if (use_referrals_flag || windows_flag)
	    d |= 2;

	data.length = 1;
	data.data = &d;

	krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
    }

    if (enctype)
	free(enctype);

    krb5_init_creds_free(context, icc);
    krb5_get_init_creds_opt_free(context, opt);

    if (kt)
	krb5_kt_close(context, kt);

#ifdef __APPLE__
    if (passwordItem)
	CFRelease(passwordItem);
#endif

    return 0;
}
Exemplo n.º 21
0
static void do_kcpytkt (int count, char *names[], 
                        char *fromccachestr, char *etypestr, int flags)
{
    krb5_context context;
    krb5_error_code ret;
    int i, errors;
    krb5_enctype etype;
    krb5_ccache fromccache;
    krb5_ccache destccache;
    krb5_principal me;
    krb5_creds in_creds, out_creds;
    int retflags;
    char *princ;

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

    if (etypestr) {
        ret = krb5_string_to_enctype(context, etypestr, &etype);
	if (ret)
	    krb5_err(context, 1, ret, "Can't convert enctype %s", etypestr);
        retflags = KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_MATCH_KEYTYPE;
    } else {
	etype = 0;
        retflags = KRB5_TC_MATCH_SRV_NAMEONLY;
    }

    if (fromccachestr)
        ret = krb5_cc_resolve(context, fromccachestr, &fromccache);
    else
        ret = krb5_cc_default(context, &fromccache);
    if (ret)
        krb5_err(context, 1, ret, "Can't resolve credentials cache");

    ret = krb5_cc_get_principal(context, fromccache, &me);
    if (ret)
        krb5_err(context, 1, ret, "Can't query client principal name");

    ret = krb5_cc_resolve(context, names[0], &destccache);
    if (ret)
        krb5_err(context, 1, ret, "Can't resolve destination cache");

    errors = 0;

    for (i = 1; i < count; i++) {
	memset(&in_creds, 0, sizeof(in_creds));

	in_creds.client = me;

	ret = krb5_parse_name(context, names[i], &in_creds.server);
	if (ret) {
	    if (!quiet_flag)
                krb5_warn(context, ret, "Parse error for %s", names[i]);
	    errors++;
	    continue;
	}

	ret = krb5_unparse_name(context, in_creds.server, &princ);
	if (ret) {
            krb5_warn(context, ret, "Unparse error for %s", names[i]);
	    errors++;
	    continue;
	}

	in_creds.session.keytype = etype;

        ret = krb5_cc_retrieve_cred(context, fromccache, retflags,
                                    &in_creds, &out_creds);  
	if (ret) {
            krb5_warn(context, ret, "Can't retrieve credentials for %s", princ);

	    krb5_free_unparsed_name(context, princ);

	    errors++;
	    continue;
	}

	ret = krb5_cc_store_cred(context, destccache, &out_creds);

	krb5_free_principal(context, in_creds.server);

	if (ret) {
            krb5_warn(context, ret, "Can't store credentials for %s", princ);

            krb5_free_cred_contents(context, &out_creds);
	    krb5_free_unparsed_name(context, princ);

	    errors++;
	    continue;
	}

	krb5_free_unparsed_name(context, princ);
        krb5_free_cred_contents(context, &out_creds);
    }

    krb5_free_principal(context, me);
    krb5_cc_close(context, fromccache);
    krb5_cc_close(context, destccache);
    krb5_free_context(context);

    if (errors)
	exit(1);

    exit(0);
}
Exemplo n.º 22
0
static void do_v5_kvno (int count, char *names[], 
                        char * ccache_name, char *etype_str, char *keytab_name,
			char *sname)
{
    krb5_error_code ret;
    krb5_context context = 0;
    int i, errors;
    krb5_enctype etype;
    krb5_ccache ccache;
    krb5_principal me;
    krb5_creds in_creds, *out_creds = NULL;
    Ticket ticket;
    size_t len;
    char *princ = NULL;
    krb5_keytab keytab = NULL;

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

    if (etype_str) {
        ret = krb5_string_to_enctype(context, etype_str, &etype);
	if (ret)
	    krb5_err(context, 1, ret, "Failed to convert encryption type %s", etype_str);
    } else {
	etype = 0;
    }

    if (ccache_name)
        ret = krb5_cc_resolve(context, ccache_name, &ccache);
    else
        ret = krb5_cc_default(context, &ccache);
    if (ret)
        krb5_err(context, 1, ret, "Failed to open credentials cache %s",
                 (ccache_name) ? ccache_name : "(Default)");

    if (keytab_name) {
	ret = krb5_kt_resolve(context, keytab_name, &keytab);
	if (ret)
            krb5_err(context, 1, ret, "Can't resolve keytab %s", keytab_name);
    }

    ret = krb5_cc_get_principal(context, ccache, &me);
    if (ret)
        krb5_err(context, 1, ret, "krb5_cc_get_principal");

    errors = 0;

    for (i = 0; i < count; i++) {
	memset(&in_creds, 0, sizeof(in_creds));
        memset(&ticket, 0, sizeof(ticket));

	in_creds.client = me;

	if (sname != NULL) {
	    ret = krb5_sname_to_principal(context, names[i],
					  sname, KRB5_NT_SRV_HST,
					  &in_creds.server);
	} else {
	    ret = krb5_parse_name(context, names[i], &in_creds.server);
	}
	if (ret) {
	    if (!quiet_flag)
                krb5_warn(context, ret, "Couldn't parse principal name %s", names[i]);
            errors++;
	    continue;
	}

	ret = krb5_unparse_name(context, in_creds.server, &princ);
	if (ret) {
            krb5_warn(context, ret, "Couldn't format parsed principal name for '%s'",
                      names[i]);
	    errors++;
            goto next;
	}

	in_creds.session.keytype = etype;

	ret = krb5_get_credentials(context, 0, ccache, &in_creds, &out_creds);

	if (ret) {
            krb5_warn(context, ret, "Couldn't get credentials for %s", princ);
	    errors++;
	    goto next;
	}

	ret = decode_Ticket(out_creds->ticket.data, out_creds->ticket.length,
                            &ticket, &len);
	if (ret) {
	    krb5_err(context, 1, ret, "Can't decode ticket for %s", princ);
	    errors++;
            goto next;
	    continue;
	}

	if (keytab) {
            krb5_keytab_entry   kte;
            krb5_crypto         crypto;
            krb5_data           dec_data;
            EncTicketPart       decr_part;

            ret = krb5_kt_get_entry(context, keytab, in_creds.server,
                                    (ticket.enc_part.kvno != NULL)?
                                    *ticket.enc_part.kvno : 0,
                                    ticket.enc_part.etype,
                                    &kte);
            if (ret) {
                krb5_warn(context, ret, "Can't decrypt ticket for %s", princ);
                if (!quiet_flag)
                    printf("%s: kvno = %d, keytab entry invalid", princ,
                           (ticket.enc_part.kvno != NULL)?
                           *ticket.enc_part.kvno : 0);
                errors ++;
                goto next;
            }

            ret = krb5_crypto_init(context, &kte.keyblock, 0, &crypto);
            if (ret) {
                krb5_warn(context, ret, "krb5_crypto_init");
                errors ++;
                krb5_kt_free_entry(context, &kte);
                goto next;
            }

            ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
                                              &ticket.enc_part, &dec_data);
            krb5_crypto_destroy(context, crypto);
            krb5_kt_free_entry(context, &kte);

            if (ret) {
                krb5_warn(context, ret, "krb5_decrypt_EncryptedData");
                errors ++;
                goto next;
            }

            ret = decode_EncTicketPart(dec_data.data, dec_data.length,
                                       &decr_part, &len);
            krb5_data_free(&dec_data);
            if (ret) {
                krb5_warn(context, ret, "decode_EncTicketPart");
                errors ++;
                goto next;
            }

            if (!quiet_flag)
		printf("%s: kvno = %d, keytab entry valid\n", princ,
                       (ticket.enc_part.kvno != NULL)?
                       *ticket.enc_part.kvno : 0);

            free_EncTicketPart(&decr_part);
	} else {
	    if (!quiet_flag)
		printf("%s: kvno = %d\n", princ,
                       (ticket.enc_part.kvno != NULL)? *ticket.enc_part.kvno : 0);
	}

    next:
        if (out_creds) {
            krb5_free_creds(context, out_creds);
            out_creds = NULL;
        }

        if (princ) {
            krb5_free_unparsed_name(context, princ);
            princ = NULL;
        }

	krb5_free_principal(context, in_creds.server);

        free_Ticket(&ticket);
    }

    if (keytab)
	krb5_kt_close(context, keytab);
    krb5_free_principal(context, me);
    krb5_cc_close(context, ccache);
    krb5_free_context(context);

    if (errors)
	exit(1);

    exit(0);
}
Exemplo n.º 23
0
krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext,
                                           const char * const *vals,
                                           int n_vals,
                                           krb5_key_salt_tuple **kst,
                                           int *n_kst)
{
    krb5_error_code kerr;
    krb5_key_salt_tuple *ks;
    int n_ks;
    int i;

    ks = calloc(n_vals + 1, sizeof(krb5_key_salt_tuple));
    if (!ks) {
        return ENOMEM;
    }

    for (i = 0, n_ks = 0; i < n_vals; i++) {
        char *enc, *salt;
        krb5_int32 tmpsalt;
        krb5_enctype tmpenc;
        krb5_boolean similar;
        krb5_error_code krberr;
        int j;

        enc = strdup(vals[i]);
        if (!enc) {
            kerr = ENOMEM;
            goto fail;
        }

        salt = strchr(enc, ':');
        if (!salt) {
            free(enc);
            continue;
        }
        *salt = '\0'; /* null terminate the enc type */
        salt++; /* skip : */

        krberr = krb5_string_to_enctype(enc, &tmpenc);
        if (krberr) {
            free(enc);
            continue;
        }

        krberr = krb5_string_to_salttype(salt, &tmpsalt);
        for (j = 0; j < n_ks; j++) {
            krb5_c_enctype_compare(kcontext,
                                   ks[j].ks_enctype, tmpenc, &similar);
            if (similar && (ks[j].ks_salttype == tmpsalt)) {
                break;
            }
        }

        if (j == n_ks) {
            /* not found */
            ks[j].ks_enctype = tmpenc;
            ks[j].ks_salttype = tmpsalt;
            n_ks++;
        }

        free(enc);
    }

    *kst = ks;
    *n_kst = n_ks;

    return 0;

fail:
    free(ks);
    return kerr;
}
Exemplo n.º 24
0
int
add_enctype(struct add_enctype_options*opt, int argc, char **argv)
{
    kadm5_principal_ent_rec princ;
    krb5_principal princ_ent = NULL;
    krb5_error_code ret;
    const char *princ_name;
    int i, j;
    krb5_key_data *new_key_data;
    int n_etypes;
    krb5_enctype *etypes;

    if (!opt->random_key_flag) {
	krb5_warnx (context, "only random key is supported now");
	return 0;
    }

    memset (&princ, 0, sizeof(princ));
    princ_name = argv[0];
    n_etypes   = argc - 1;
    etypes     = malloc (n_etypes * sizeof(*etypes));
    if (etypes == NULL) {
	krb5_warnx (context, "out of memory");
	return 0;
    }
    argv++;
    for (i = 0; i < n_etypes; ++i) {
	ret = krb5_string_to_enctype (context, argv[i], &etypes[i]);
	if (ret) {
	    krb5_warnx (context, "bad enctype \"%s\"", argv[i]);
	    goto out2;
	}
    }

    ret = krb5_parse_name(context, princ_name, &princ_ent);
    if (ret) {
	krb5_warn (context, ret, "krb5_parse_name %s", princ_name);
	goto out2;
    }

    ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
			      KADM5_PRINCIPAL | KADM5_KEY_DATA);
    if (ret) {
	krb5_free_principal (context, princ_ent);
	krb5_warnx (context, "no such principal: %s", princ_name);
	goto out2;
    }

    new_key_data   = malloc((princ.n_key_data + n_etypes)
			    * sizeof(*new_key_data));
    if (new_key_data == NULL) {
	krb5_warnx (context, "out of memory");
	goto out;
    }

    for (i = 0; i < princ.n_key_data; ++i) {
	krb5_key_data *key = &princ.key_data[i];

	for (j = 0; j < n_etypes; ++j) {
	    if (etypes[j] == key->key_data_type[0]) {
		krb5_warnx(context, "enctype %d already exists",
			   (int)etypes[j]);
		free(new_key_data);
		goto out;
	    }
	}
	new_key_data[i] = *key;
    }

    for (i = 0; i < n_etypes; ++i) {
	int n = princ.n_key_data + i;
	krb5_keyblock keyblock;

	memset(&new_key_data[n], 0, sizeof(new_key_data[n]));
	new_key_data[n].key_data_ver = 2;
	new_key_data[n].key_data_kvno = 0;

	ret = krb5_generate_random_keyblock (context, etypes[i], &keyblock);
	if (ret) {
	    krb5_warnx(context, "genernate enctype %d failed", (int)etypes[i]);
	    while (--i >= 0)
		free(new_key_data[--n].key_data_contents[0]);
	    goto out;
	}

	/* key */
	new_key_data[n].key_data_type[0] = etypes[i];
	new_key_data[n].key_data_contents[0] = malloc(keyblock.keyvalue.length);
	if (new_key_data[n].key_data_contents[0] == NULL) {
	    ret = ENOMEM;
	    krb5_warn(context, ret, "out of memory");
	    while (--i >= 0)
		free(new_key_data[--n].key_data_contents[0]);
	    goto out;
	}
	new_key_data[n].key_data_length[0]   = keyblock.keyvalue.length;
	memcpy(new_key_data[n].key_data_contents[0],
	       keyblock.keyvalue.data,
	       keyblock.keyvalue.length);
	krb5_free_keyblock_contents(context, &keyblock);

	/* salt */
	new_key_data[n].key_data_type[1]     = KRB5_PW_SALT;
	new_key_data[n].key_data_length[1]   = 0;
	new_key_data[n].key_data_contents[1] = NULL;

    }

    free (princ.key_data);
    princ.n_key_data += n_etypes;
    princ.key_data   = new_key_data;
    new_key_data = NULL;

    ret = kadm5_modify_principal (kadm_handle, &princ, KADM5_KEY_DATA);
    if (ret)
	krb5_warn(context, ret, "kadm5_modify_principal");
out:
    krb5_free_principal (context, princ_ent);
    kadm5_free_principal_ent(kadm_handle, &princ);
out2:
    free (etypes);
    return ret != 0;
}
Exemplo n.º 25
0
int
kt_get(struct get_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab keytab;
    void *kadm_handle = NULL;
    krb5_enctype *etypes = NULL;
    size_t netypes = 0;
    size_t i;
    int a, j;
    unsigned int failed = 0;

    if((keytab = ktutil_open_keytab()) == NULL)
	return 1;

    if(opt->realm_string)
	krb5_set_default_realm(context, opt->realm_string);

    if (opt->enctypes_strings.num_strings != 0) {

	etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes));
	if (etypes == NULL) {
	    krb5_warnx(context, "malloc failed");
	    goto out;
	}
	netypes = opt->enctypes_strings.num_strings;
	for(i = 0; i < netypes; i++) {
	    ret = krb5_string_to_enctype(context,
					 opt->enctypes_strings.strings[i],
					 &etypes[i]);
	    if(ret) {
		krb5_warnx(context, "unrecognized enctype: %s",
			   opt->enctypes_strings.strings[i]);
		goto out;
	    }
	}
    }


    for(a = 0; a < argc; a++){
	krb5_principal princ_ent;
	kadm5_principal_ent_rec princ;
	int mask = 0;
	krb5_keyblock *keys;
	int n_keys;
	int created = 0;
	krb5_keytab_entry entry;

	ret = krb5_parse_name(context, argv[a], &princ_ent);
	if (ret) {
	    krb5_warn(context, ret, "can't parse principal %s", argv[a]);
	    failed++;
	    continue;
	}
	memset(&princ, 0, sizeof(princ));
	princ.principal = princ_ent;
	mask |= KADM5_PRINCIPAL;
	princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
	mask |= KADM5_ATTRIBUTES;
	princ.princ_expire_time = 0;
	mask |= KADM5_PRINC_EXPIRE_TIME;

	if(kadm_handle == NULL) {
	    const char *r;
	    if(opt->realm_string != NULL)
		r = opt->realm_string;
	    else
		r = krb5_principal_get_realm(context, princ_ent);
	    kadm_handle = open_kadmin_connection(opt->principal_string,
						 r,
						 opt->admin_server_string,
						 opt->server_port_integer);
	    if(kadm_handle == NULL)
		break;
	}

	ret = kadm5_create_principal(kadm_handle, &princ, mask, "x");
	if(ret == 0)
	    created = 1;
	else if(ret != KADM5_DUP) {
	    krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}

	ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
			      KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]);
	    for (j = 0; j < n_keys; j++)
		krb5_free_keyblock_contents(context, &keys[j]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX))
	    krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]);
	princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
	mask = KADM5_ATTRIBUTES;
	if(created) {
	    princ.kvno = 1;
	    mask |= KADM5_KVNO;
	}
	ret = kadm5_modify_principal(kadm_handle, &princ, mask);
	if (ret) {
	    krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]);
	    for (j = 0; j < n_keys; j++)
		krb5_free_keyblock_contents(context, &keys[j]);
	    krb5_free_principal(context, princ_ent);
	    failed++;
	    continue;
	}
	for(j = 0; j < n_keys; j++) {
	    int do_add = TRUE;

	    if (netypes) {
		size_t k;

		do_add = FALSE;
		for (k = 0; k < netypes; ++k)
		    if (keys[j].keytype == etypes[k]) {
			do_add = TRUE;
			break;
		    }
	    }
	    if (do_add) {
		entry.principal = princ_ent;
		entry.vno = princ.kvno;
		entry.keyblock = keys[j];
		entry.timestamp = time (NULL);
		ret = krb5_kt_add_entry(context, keytab, &entry);
		if (ret)
		    krb5_warn(context, ret, "krb5_kt_add_entry");
	    }
	    krb5_free_keyblock_contents(context, &keys[j]);
	}

	kadm5_free_principal_ent(kadm_handle, &princ);
	krb5_free_principal(context, princ_ent);
    }
 out:
    free(etypes);
    if (kadm_handle)
	kadm5_destroy(kadm_handle);
    krb5_kt_close(context, keytab);
    return ret != 0 || failed > 0;
}
Exemplo n.º 26
0
/*
 * Initialize a realm control structure from the alternate profile or from
 * the specified defaults.
 *
 * After we're complete here, the essence of the realm is embodied in the
 * realm data and we should be all set to begin operation for that realm.
 */
static  krb5_error_code
init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm,
           char *def_mpname, krb5_enctype def_enctype, char *def_udp_listen,
           char *def_tcp_listen, krb5_boolean def_manual,
           krb5_boolean def_restrict_anon, char **db_args, char *no_referral,
           char *hostbased)
{
    krb5_error_code     kret;
    krb5_boolean        manual;
    int                 kdb_open_flags;
    char                *svalue = NULL;
    const char          *hierarchy[4];
    krb5_kvno       mkvno = IGNORE_VNO;

    memset(rdp, 0, sizeof(kdc_realm_t));
    if (!realm) {
        kret = EINVAL;
        goto whoops;
    }
    hierarchy[0] = KRB5_CONF_REALMS;
    hierarchy[1] = realm;
    hierarchy[3] = NULL;

    rdp->realm_name = strdup(realm);
    if (rdp->realm_name == NULL) {
        kret = ENOMEM;
        goto whoops;
    }
    kret = krb5int_init_context_kdc(&rdp->realm_context);
    if (kret) {
        kdc_err(NULL, kret, _("while getting context for realm %s"), realm);
        goto whoops;
    }
    if (time_offset != 0)
        (void)krb5_set_time_offsets(rdp->realm_context, time_offset, 0);

    /* Handle master key name */
    hierarchy[2] = KRB5_CONF_MASTER_KEY_NAME;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_mpname)) {
        rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) :
            strdup(KRB5_KDB_M_NAME);
    }
    if (!rdp->realm_mpname) {
        kret = ENOMEM;
        goto whoops;
    }

    /* Handle KDC addresses/ports */
    hierarchy[2] = KRB5_CONF_KDC_LISTEN;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) {
        /* Try the old kdc_ports configuration option. */
        hierarchy[2] = KRB5_CONF_KDC_PORTS;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen))
            rdp->realm_listen = strdup(def_udp_listen);
    }
    if (!rdp->realm_listen) {
        kret = ENOMEM;
        goto whoops;
    }
    hierarchy[2] = KRB5_CONF_KDC_TCP_LISTEN;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE,
                              &rdp->realm_tcp_listen)) {
        /* Try the old kdc_tcp_ports configuration option. */
        hierarchy[2] = KRB5_CONF_KDC_TCP_PORTS;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE,
                                  &rdp->realm_tcp_listen))
            rdp->realm_tcp_listen = strdup(def_tcp_listen);
    }
    if (!rdp->realm_tcp_listen) {
        kret = ENOMEM;
        goto whoops;
    }
    /* Handle stash file */
    hierarchy[2] = KRB5_CONF_KEY_STASH_FILE;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_stash))
        manual = def_manual;
    else
        manual = FALSE;

    hierarchy[2] = KRB5_CONF_RESTRICT_ANONYMOUS_TO_TGT;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                               &rdp->realm_restrict_anon))
        rdp->realm_restrict_anon = def_restrict_anon;

    /* Handle master key type */
    hierarchy[2] = KRB5_CONF_MASTER_KEY_TYPE;
    if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &svalue) ||
        krb5_string_to_enctype(svalue, &rdp->realm_mkey.enctype))
        rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN;
    free(svalue);
    svalue = NULL;

    /* Handle reject-bad-transit flag */
    hierarchy[2] = KRB5_CONF_REJECT_BAD_TRANSIT;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                                &rdp->realm_reject_bad_transit))
        rdp->realm_reject_bad_transit = TRUE;

    /* Handle assume des-cbc-crc is supported for session keys */
    hierarchy[2] = KRB5_CONF_DES_CRC_SESSION_SUPPORTED;
    if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE,
                               &rdp->realm_assume_des_crc_sess))
        rdp->realm_assume_des_crc_sess = TRUE;

    /* Handle ticket maximum life */
    hierarchy[2] = KRB5_CONF_MAX_LIFE;
    if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxlife))
        rdp->realm_maxlife = KRB5_KDB_MAX_LIFE;

    /* Handle ticket renewable maximum life */
    hierarchy[2] = KRB5_CONF_MAX_RENEWABLE_LIFE;
    if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxrlife))
        rdp->realm_maxrlife = KRB5_KDB_MAX_RLIFE;

    /* Handle KDC referrals */
    hierarchy[2] = KRB5_CONF_NO_HOST_REFERRAL;
    (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue);
    kret = combine(no_referral, svalue, &rdp->realm_no_referral);
    if (kret)
        goto whoops;
    free(svalue);
    svalue = NULL;

    hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES;
    (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue);
    kret = combine(hostbased, svalue, &rdp->realm_hostbased);
    if (kret)
        goto whoops;
    free(svalue);
    svalue = NULL;

    /*
     * We've got our parameters, now go and setup our realm context.
     */

    /* Set the default realm of this context */
    if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting default realm to %s"), realm);
        goto whoops;
    }

    /* first open the database  before doing anything */
    kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC;
    if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) {
        kdc_err(rdp->realm_context, kret,
                _("while initializing database for realm %s"), realm);
        goto whoops;
    }

    /* Assemble and parse the master key name */
    if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname,
                                        rdp->realm_name, (char **) NULL,
                                        &rdp->realm_mprinc))) {
        kdc_err(rdp->realm_context, kret,
                _("while setting up master key name %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    /*
     * Get the master key (note, may not be the most current mkey).
     */
    if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc,
                                   rdp->realm_mkey.enctype, manual,
                                   FALSE, rdp->realm_stash,
                                   &mkvno, NULL, &rdp->realm_mkey))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master key %s for realm %s"),
                rdp->realm_mpname, realm);
        goto whoops;
    }

    if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc,
                                        &rdp->realm_mkey))) {
        kdc_err(rdp->realm_context, kret,
                _("while fetching master keys list for realm %s"), realm);
        goto whoops;
    }


    /* Set up the keytab */
    if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL,
                                   &rdp->realm_keytab))) {
        kdc_err(rdp->realm_context, kret,
                _("while resolving kdb keytab for realm %s"), realm);
        goto whoops;
    }

    /* Preformat the TGS name */
    if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc,
                                     strlen(realm), realm, KRB5_TGS_NAME,
                                     realm, (char *) NULL))) {
        kdc_err(rdp->realm_context, kret,
                _("while building TGS name for realm %s"), realm);
        goto whoops;
    }

    if (!rkey_init_done) {
        krb5_data seed;
        /*
         * If all that worked, then initialize the random key
         * generators.
         */

        seed.length = rdp->realm_mkey.length;
        seed.data = (char *)rdp->realm_mkey.contents;

        if ((kret = krb5_c_random_add_entropy(rdp->realm_context,
                                              KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed)))
            goto whoops;

        rkey_init_done = 1;
    }
whoops:
    /*
     * If we choked, then clean up any dirt we may have dropped on the floor.
     */
    if (kret) {

        finish_realm(rdp);
    }
    return(kret);
}
Exemplo n.º 27
0
static void
initialize_realms(krb5_context kcontext, int argc, char **argv)
{
    int                 c;
    char                *db_name = (char *) NULL;
    char                *lrealm = (char *) NULL;
    char                *mkey_name = (char *) NULL;
    krb5_error_code     retval;
    krb5_enctype        menctype = ENCTYPE_UNKNOWN;
    kdc_realm_t         *rdatap = NULL;
    krb5_boolean        manual = FALSE;
    krb5_boolean        def_restrict_anon;
    char                *default_udp_ports = 0;
    char                *default_tcp_ports = 0;
    krb5_pointer        aprof;
    const char          *hierarchy[3];
    char                *no_refrls = NULL;
    char                *host_based_srvcs = NULL;
    int                  db_args_size = 0;
    char                **db_args = NULL;

    extern char *optarg;

    if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) {
        hierarchy[0] = KRB5_CONF_KDCDEFAULTS;
        hierarchy[1] = KRB5_CONF_KDC_PORTS;
        hierarchy[2] = (char *) NULL;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports))
            default_udp_ports = 0;
        hierarchy[1] = KRB5_CONF_KDC_TCP_PORTS;
        if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports))
            default_tcp_ports = 0;
        hierarchy[1] = KRB5_CONF_MAX_DGRAM_REPLY_SIZE;
        if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, &max_dgram_reply_size))
            max_dgram_reply_size = MAX_DGRAM_SIZE;
        hierarchy[1] = KRB5_CONF_RESTRICT_ANONYMOUS_TO_TGT;
        if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &def_restrict_anon))
            def_restrict_anon = FALSE;
        hierarchy[1] = KRB5_CONF_NO_HOST_REFERRAL;
        if (krb5_aprof_get_string_all(aprof, hierarchy, &no_refrls))
            no_refrls = 0;
        if (!no_refrls ||
            krb5_match_config_pattern(no_refrls, KRB5_CONF_ASTERISK) == FALSE) {
            hierarchy[1] = KRB5_CONF_HOST_BASED_SERVICES;
            if (krb5_aprof_get_string_all(aprof, hierarchy, &host_based_srvcs))
                host_based_srvcs = 0;
        }

        krb5_aprof_finish(aprof);
    }

    if (default_udp_ports == 0) {
        default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST);
        if (default_udp_ports == 0) {
            fprintf(stderr, _(" KDC cannot initialize. Not enough memory\n"));
            exit(1);
        }
    }
    if (default_tcp_ports == 0) {
        default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST);
        if (default_tcp_ports == 0) {
            fprintf(stderr, _(" KDC cannot initialize. Not enough memory\n"));
            exit(1);
        }
    }

    /*
     * Loop through the option list.  Each time we encounter a realm name,
     * use the previously scanned options to fill in for defaults.
     */
    while ((c = getopt(argc, argv, "x:r:d:mM:k:R:e:P:p:s:nw:4:X3")) != -1) {
        switch(c) {
        case 'x':
            db_args_size++;
            {
                char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
                if( temp == NULL )
                {
                    fprintf(stderr, _("%s: KDC cannot initialize. Not enough "
                                      "memory\n"), argv[0]);
                    exit(1);
                }

                db_args = temp;
            }
            db_args[db_args_size-1] = optarg;
            db_args[db_args_size]   = NULL;
            break;

        case 'r':                       /* realm name for db */
            if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
                if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
                    if ((retval = init_realm(rdatap, optarg, mkey_name,
                                             menctype, default_udp_ports,
                                             default_tcp_ports, manual,
                                             def_restrict_anon, db_args,
                                             no_refrls, host_based_srvcs))) {
                        fprintf(stderr, _("%s: cannot initialize realm %s - "
                                          "see log file for details\n"),
                                argv[0], optarg);
                        exit(1);
                    }
                    kdc_realmlist[kdc_numrealms] = rdatap;
                    kdc_numrealms++;
                    free(db_args), db_args=NULL, db_args_size = 0;
                }
                else
                {
                    fprintf(stderr, _("%s: cannot initialize realm %s. Not "
                                      "enough memory\n"), argv[0], optarg);
                    exit(1);
                }
            }
            break;
        case 'd':                       /* pathname for db */
            /* now db_name is not a seperate argument.
             * It has to be passed as part of the db_args
             */
            if( db_name == NULL ) {
                if (asprintf(&db_name, "dbname=%s", optarg) < 0) {
                    fprintf(stderr, _("%s: KDC cannot initialize. Not enough "
                                      "memory\n"), argv[0]);
                    exit(1);
                }
            }

            db_args_size++;
            {
                char **temp = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* one for NULL */
                if( temp == NULL )
                {
                    fprintf(stderr, _("%s: KDC cannot initialize. Not enough "
                                      "memory\n"), argv[0]);
                    exit(1);
                }

                db_args = temp;
            }
            db_args[db_args_size-1] = db_name;
            db_args[db_args_size]   = NULL;
            break;
        case 'm':                       /* manual type-in of master key */
            manual = TRUE;
            if (menctype == ENCTYPE_UNKNOWN)
                menctype = ENCTYPE_DES_CBC_CRC;
            break;
        case 'M':                       /* master key name in DB */
            mkey_name = optarg;
            break;
        case 'n':
            nofork++;                   /* don't detach from terminal */
            break;
        case 'w':                       /* create multiple worker processes */
            workers = atoi(optarg);
            if (workers <= 0)
                usage(argv[0]);
            break;
        case 'k':                       /* enctype for master key */
            if (krb5_string_to_enctype(optarg, &menctype))
                com_err(argv[0], 0, _("invalid enctype %s"), optarg);
            break;
        case 'R':
            /* Replay cache name; defunct since we don't use a replay cache. */
            break;
        case 'P':
            pid_file = optarg;
            break;
        case 'p':
            if (default_udp_ports)
                free(default_udp_ports);
            default_udp_ports = strdup(optarg);
            if (!default_udp_ports) {
                fprintf(stderr, _(" KDC cannot initialize. Not enough "
                                  "memory\n"));
                exit(1);
            }
#if 0 /* not yet */
            if (default_tcp_ports)
                free(default_tcp_ports);
            default_tcp_ports = strdup(optarg);
#endif
            break;
        case '4':
            break;
        case 'X':
            break;
        case '?':
        default:
            usage(argv[0]);
        }
    }

    /*
     * Check to see if we processed any realms.
     */
    if (kdc_numrealms == 0) {
        /* no realm specified, use default realm */
        if ((retval = krb5_get_default_realm(kcontext, &lrealm))) {
            com_err(argv[0], retval,
                    _("while attempting to retrieve default realm"));
            fprintf (stderr,
                     _("%s: %s, attempting to retrieve default realm\n"),
                     argv[0], krb5_get_error_message(kcontext, retval));
            exit(1);
        }
        if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) {
            if ((retval = init_realm(rdatap, lrealm, mkey_name, menctype,
                                     default_udp_ports, default_tcp_ports,
                                     manual, def_restrict_anon, db_args,
                                     no_refrls, host_based_srvcs))) {
                fprintf(stderr, _("%s: cannot initialize realm %s - see log "
                                  "file for details\n"), argv[0], lrealm);
                exit(1);
            }
            kdc_realmlist[0] = rdatap;
            kdc_numrealms++;
        }
        krb5_free_default_realm(kcontext, lrealm);
    }

    /* Ensure that this is set for our first request. */
    kdc_active_realm = kdc_realmlist[0];
    if (default_udp_ports)
        free(default_udp_ports);
    if (default_tcp_ports)
        free(default_tcp_ports);
    if (db_args)
        free(db_args);
    if (db_name)
        free(db_name);
    if (host_based_srvcs)
        free(host_based_srvcs);
    if (no_refrls)
        free(no_refrls);

    return;
}
Exemplo n.º 28
0
static int
create_krb5_tickets (krb5_context context, krb5_keytab kt)
{
    krb5_error_code ret;
    krb5_keytab_entry entry;
    krb5_creds cred;
    krb5_enctype etype;
    krb5_ccache ccache;

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

    ret = krb5_string_to_enctype (context, enc_type, &etype);
    if (ret)
	krb5_err (context, 1, ret, "krb5_string_to_enctype");
    ret = krb5_kt_get_entry (context, kt, server_principal,
			     0, etype, &entry);
    if (ret)
	krb5_err (context, 1, ret, "krb5_kt_get_entry");

    /*
     * setup cred
     */


    ret = krb5_copy_principal (context, client_principal, &cred.client);
    if (ret)
	krb5_err (context, 1, ret, "krb5_copy_principal");
    ret = krb5_copy_principal (context, server_principal, &cred.server);
    if (ret)
	krb5_err (context, 1, ret, "krb5_copy_principal");
    krb5_generate_random_keyblock(context, etype, &cred.session);

    cred.times.authtime = time(NULL);
    cred.times.starttime = time(NULL);
    cred.times.endtime = time(NULL) + expiration_time;
    cred.times.renew_till = 0;
    krb5_data_zero(&cred.second_ticket);

    ret = krb5_get_all_client_addrs (context, &cred.addresses);
    if (ret)
	krb5_err (context, 1, ret, "krb5_get_all_client_addrs");
    cred.flags.b = ticket_flags;


    /*
     * Encode encrypted part of ticket
     */

    encode_ticket (context, &entry.keyblock, etype, entry.vno, &cred);

    /*
     * Write to cc
     */

    if (ccache_str) {
	ret = krb5_cc_resolve(context, ccache_str, &ccache);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_resolve");
    } else {
	ret = krb5_cc_default (context, &ccache);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_cc_default");
    }

    ret = krb5_cc_initialize (context, ccache, cred.client);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_store_cred (context, ccache, &cred);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents (context, &cred);
    krb5_cc_close (context, ccache);

    return 0;
}
Exemplo n.º 29
0
static krb5_error_code
get_new_tickets(krb5_context context,
		krb5_principal principal,
		krb5_ccache ccache,
		krb5_deltat ticket_life,
		int interactive)
{
    krb5_error_code ret;
    krb5_creds cred;
    char passwd[256];
    krb5_deltat start_time = 0;
    krb5_deltat renew = 0;
    const char *renewstr = NULL;
    krb5_enctype *enctype = NULL;
    krb5_ccache tempccache = NULL;
    krb5_init_creds_context ctx = NULL;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_prompter_fct prompter = krb5_prompter_posix;
#ifndef NO_NTLM
    struct ntlm_buf ntlmkey;
    memset(&ntlmkey, 0, sizeof(ntlmkey));
#endif
    passwd[0] = '\0';

    if (!interactive)
	prompter = NULL;

    if (password_file) {
	FILE *f;

	if (strcasecmp("STDIN", password_file) == 0)
	    f = stdin;
	else
	    f = fopen(password_file, "r");
	if (f == NULL) {
	    krb5_warnx(context, "Failed to open the password file %s",
		       password_file);
	    return errno;
	}

	if (fgets(passwd, sizeof(passwd), f) == NULL) {
	    krb5_warnx(context, N_("Failed to read password from file %s", ""),
		       password_file);
	    fclose(f);
	    return EINVAL; /* XXX Need a better error */
	}
	if (f != stdin)
	    fclose(f);
	passwd[strcspn(passwd, "\n")] = '\0';
    }

#ifdef __APPLE__
    if (passwd[0] == '\0') {
	const char *realm;
	OSStatus osret;
	UInt32 length;
	void *buffer;
	char *name;

	realm = krb5_principal_get_realm(context, principal);

	ret = krb5_unparse_name_flags(context, principal,
				      KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
	if (ret)
	    goto nopassword;

	osret = SecKeychainFindGenericPassword(NULL, strlen(realm), realm,
					       strlen(name), name,
					       &length, &buffer, NULL);
	free(name);
	if (osret == noErr && length < sizeof(passwd) - 1) {
	    memcpy(passwd, buffer, length);
	    passwd[length] = '\0';
	}
    nopassword:
	do { } while(0);
    }
#endif

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

    ret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (ret) {
	krb5_warn(context, ret, "krb5_get_init_creds_opt_alloc");
	goto out;
    }

    krb5_get_init_creds_opt_set_default_flags(context, "kinit",
	krb5_principal_get_realm(context, principal), opt);

    if (forwardable_flag != -1)
	krb5_get_init_creds_opt_set_forwardable(opt, forwardable_flag);
    if (proxiable_flag != -1)
	krb5_get_init_creds_opt_set_proxiable(opt, proxiable_flag);
    if (anonymous_flag)
	krb5_get_init_creds_opt_set_anonymous(opt, anonymous_flag);
    if (pac_flag != -1)
	krb5_get_init_creds_opt_set_pac_request(context, opt,
						pac_flag ? TRUE : FALSE);
    if (canonicalize_flag)
	krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
    if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
	krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
    if (pk_user_id || ent_user_id || anonymous_flag) {
	ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
						 principal,
						 pk_user_id,
						 pk_x509_anchors,
						 NULL,
						 NULL,
						 pk_use_enckey ? 2 : 0 |
						 anonymous_flag ? 4 : 0,
						 prompter,
						 NULL,
						 passwd);
	if (ret) {
	    krb5_warn(context, ret, "krb5_get_init_creds_opt_set_pkinit");
	    goto out;
	}
	if (ent_user_id)
	    krb5_get_init_creds_opt_set_pkinit_user_certs(context, opt, ent_user_id);
    }

    if (addrs_flag != -1)
	krb5_get_init_creds_opt_set_addressless(context, opt,
						addrs_flag ? FALSE : TRUE);

    if (renew_life == NULL && renewable_flag)
	renewstr = "1 month";
    if (renew_life)
	renewstr = renew_life;
    if (renewstr) {
	renew = parse_time(renewstr, "s");
	if (renew < 0)
	    errx(1, "unparsable time: %s", renewstr);

	krb5_get_init_creds_opt_set_renew_life(opt, renew);
    }

    if (ticket_life != 0)
	krb5_get_init_creds_opt_set_tkt_life(opt, ticket_life);

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

	start_time = tmp;
    }

    if (etype_str.num_strings) {
	int i;

	enctype = malloc(etype_str.num_strings * sizeof(*enctype));
	if (enctype == NULL)
	    errx(1, "out of memory");
	for(i = 0; i < etype_str.num_strings; i++) {
	    ret = krb5_string_to_enctype(context,
					 etype_str.strings[i],
					 &enctype[i]);
	    if (ret)
		errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
	}
	krb5_get_init_creds_opt_set_etype_list(opt, enctype,
					       etype_str.num_strings);
    }

    ret = krb5_init_creds_init(context, principal, prompter, NULL, start_time, opt, &ctx);
    if (ret) {
	krb5_warn(context, ret, "krb5_init_creds_init");
	goto out;
    }

    if (server_str) {
	ret = krb5_init_creds_set_service(context, ctx, server_str);
	if (ret) {
	    krb5_warn(context, ret, "krb5_init_creds_set_service");
	    goto out;
	}
    }

    if (fast_armor_cache_string) {
	krb5_ccache fastid;
	
	ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
	if (ret) {
	    krb5_warn(context, ret, "krb5_cc_resolve(FAST cache)");
	    goto out;
	}
	
	ret = krb5_init_creds_set_fast_ccache(context, ctx, fastid);
	if (ret) {
	    krb5_warn(context, ret, "krb5_init_creds_set_fast_ccache");
	    goto out;
	}
    }

    if (use_keytab || keytab_str) {
	ret = krb5_init_creds_set_keytab(context, ctx, kt);
	if (ret) {
	    krb5_warn(context, ret, "krb5_init_creds_set_keytab");
	    goto out;
	}
    } else if (pk_user_id || ent_user_id || anonymous_flag) {

    } else if (!interactive && passwd[0] == '\0') {
	static int already_warned = 0;

	if (!already_warned)
	    krb5_warnx(context, "Not interactive, failed to get "
	      "initial ticket");
	krb5_get_init_creds_opt_free(context, opt);
	already_warned = 1;
	return 0;
    } else {

	if (passwd[0] == '\0') {
	    char *p, *prompt;
	    int aret = 0;

	    ret = krb5_unparse_name(context, principal, &p);
	    if (ret)
		errx(1, "failed to generate passwd prompt: not enough memory");

	    aret = asprintf(&prompt, N_("%s's Password: "******""), p);
	    free(p);
	    if (aret == -1)
		errx(1, "failed to generate passwd prompt: not enough memory");

	    if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
		memset(passwd, 0, sizeof(passwd));
		errx(1, "failed to read password");
	    }
	    free(prompt);
	}

	if (passwd[0]) {
	    ret = krb5_init_creds_set_password(context, ctx, passwd);
	    if (ret) {
		krb5_warn(context, ret, "krb5_init_creds_set_password");
		goto out;
	    }
	}
    }

    ret = krb5_init_creds_get(context, ctx);

#ifndef NO_NTLM
    if (ntlm_domain && passwd[0])
	heim_ntlm_nt_key(passwd, &ntlmkey);
#endif
    memset(passwd, 0, sizeof(passwd));

    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
	exit(1);
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
    case KRB5KDC_ERR_PREAUTH_FAILED:
    case KRB5_GET_IN_TKT_LOOP:
	krb5_warnx(context, N_("Password incorrect", ""));
	goto out;
    case KRB5KRB_AP_ERR_V4_REPLY:
	krb5_warnx(context, N_("Looks like a Kerberos 4 reply", ""));
	goto out;
    case KRB5KDC_ERR_KEY_EXPIRED:
	krb5_warnx(context, N_("Password expired", ""));
	goto out;
    default:
	krb5_warn(context, ret, "krb5_get_init_creds");
	goto out;
    }

    krb5_process_last_request(context, opt, ctx);

    ret = krb5_init_creds_get_creds(context, ctx, &cred);
    if (ret) {
	krb5_warn(context, ret, "krb5_init_creds_get_creds");
	goto out;
    }

    if (ticket_life != 0) {
	if (abs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
	    char life[64];
	    unparse_time_approx(cred.times.endtime - cred.times.starttime,
				life, sizeof(life));
	    krb5_warnx(context, N_("NOTICE: ticket lifetime is %s", ""), life);
	}
    }
    if (renew_life) {
	if (abs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
	    char life[64];
	    unparse_time_approx(cred.times.renew_till - cred.times.starttime,
				life, sizeof(life));
	    krb5_warnx(context,
		       N_("NOTICE: ticket renewable lifetime is %s", ""),
		       life);
	}
    }
    krb5_free_cred_contents(context, &cred);

    ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
			     NULL, &tempccache);
    if (ret) {
	krb5_warn(context, ret, "krb5_cc_new_unique");
	goto out;
    }

    ret = krb5_init_creds_store(context, ctx, tempccache);
    if (ret) {
	krb5_warn(context, ret, "krb5_init_creds_store");
	goto out;
    }

    krb5_init_creds_free(context, ctx);
    ctx = NULL;

    ret = krb5_cc_move(context, tempccache, ccache);
    if (ret) {
	krb5_warn(context, ret, "krb5_cc_move");
	goto out;
    }
    tempccache = NULL;

    if (switch_cache_flags)
	krb5_cc_switch(context, ccache);

#ifndef NO_NTLM
    if (ntlm_domain && ntlmkey.data)
	store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
#endif

    if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
	unsigned char d = 0;
	krb5_data data;

	if (ok_as_delegate_flag || windows_flag)
	    d |= 1;
	if (use_referrals_flag || windows_flag)
	    d |= 2;

	data.length = 1;
	data.data = &d;

	krb5_cc_set_config(context, ccache, NULL, "realm-config", &data);
    }

out:
    krb5_get_init_creds_opt_free(context, opt);
    if (ctx)
	krb5_init_creds_free(context, ctx);
    if (tempccache)
	krb5_cc_close(context, tempccache);

    if (enctype)
	free(enctype);

    return ret;
}
Exemplo n.º 30
0
int
del_enctype(void *opt, int argc, char **argv)
{
    kadm5_principal_ent_rec princ;
    krb5_principal princ_ent = NULL;
    krb5_error_code ret;
    const char *princ_name;
    int i, j, k;
    krb5_key_data *new_key_data;
    int n_etypes;
    krb5_enctype *etypes;

    memset (&princ, 0, sizeof(princ));
    princ_name = argv[0];
    n_etypes   = argc - 1;
    etypes     = malloc (n_etypes * sizeof(*etypes));
    if (etypes == NULL) {
        krb5_warnx (context, "out of memory");
        return 0;
    }
    argv++;
    for (i = 0; i < n_etypes; ++i) {
        ret = krb5_string_to_enctype (context, argv[i], &etypes[i]);
        if (ret) {
            krb5_warnx (context, "bad enctype \"%s\"", argv[i]);
            goto out2;
        }
    }

    ret = krb5_parse_name(context, princ_name, &princ_ent);
    if (ret) {
        krb5_warn (context, ret, "krb5_parse_name %s", princ_name);
        goto out2;
    }

    ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
                              KADM5_PRINCIPAL | KADM5_KEY_DATA);
    if (ret) {
        krb5_free_principal (context, princ_ent);
        krb5_warnx (context, "no such principal: %s", princ_name);
        goto out2;
    }

    new_key_data   = malloc(princ.n_key_data * sizeof(*new_key_data));
    if (new_key_data == NULL && princ.n_key_data != 0) {
        krb5_warnx (context, "out of memory");
        goto out;
    }

    for (i = 0, j = 0; i < princ.n_key_data; ++i) {
        krb5_key_data *key = &princ.key_data[i];
        int docopy = 1;

        for (k = 0; k < n_etypes; ++k)
            if (etypes[k] == key->key_data_type[0]) {
                docopy = 0;
                break;
            }
        if (docopy) {
            new_key_data[j++] = *key;
        } else {
            int16_t ignore = 1;

            kadm5_free_key_data (kadm_handle, &ignore, key);
        }
    }

    free (princ.key_data);
    princ.n_key_data = j;
    princ.key_data   = new_key_data;

    ret = kadm5_modify_principal (kadm_handle, &princ, KADM5_KEY_DATA);
    if (ret)
        krb5_warn(context, ret, "kadm5_modify_principal");
out:
    krb5_free_principal (context, princ_ent);
    kadm5_free_principal_ent(kadm_handle, &princ);
out2:
    free (etypes);
    return ret != 0;
}