Ejemplo n.º 1
0
static int
corner_tag(void)
{
    struct {
	int ok;
	const char *ptr;
	size_t len;
    } tests[] = {
	{ 1, "\x00", 1 },
	{ 0, "\xff", 1 },
	{ 0, "\xff\xff\xff\xff\xff\xff\xff\xff", 8 }
    };
    int i, ret;
    Der_class cl;
    Der_type ty;
    unsigned int tag;
    size_t size;

    for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
	ret = der_get_tag((const unsigned char*)tests[i].ptr,
			  tests[i].len, &cl, &ty, &tag, &size);
	if (ret) {
	    if (tests[i].ok)
		errx(1, "failed while shouldn't");
	} else {
	    if (!tests[i].ok)
		errx(1, "passed while shouldn't");
	}
    }
    return 0;
}
Ejemplo n.º 2
0
int
decode_heim_any(const unsigned char *p, size_t len, 
		heim_any *data, size_t *size)
{
    size_t len_len, length, l;
    Der_class thisclass;
    Der_type thistype;
    unsigned int thistag;
    int e;

    memset(data, 0, sizeof(*data));

    e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
    if (e) return e;
    if (l > len)
	return ASN1_OVERFLOW;
    e = der_get_length(p + l, len - l, &length, &len_len);
    if (e) return e;
    if (length + len_len + l > len)
	return ASN1_OVERFLOW;

    data->data = malloc(length + len_len + l);
    if (data->data == NULL)
	return ENOMEM;
    data->length = length + len_len + l;
    memcpy(data->data, p, length + len_len + l);

    if (size)
	*size = length + len_len + l;

    return 0;
}
Ejemplo n.º 3
0
krb5_error_code
hdb_replace_extension(krb5_context context, 
		      hdb_entry *entry, 
		      const HDB_extension *ext)
{
    HDB_extension *ext2;
    HDB_extension *es;
    int ret;

    ext2 = NULL;

    if (entry->extensions == NULL) {
	entry->extensions = calloc(1, sizeof(*entry->extensions));
	if (entry->extensions == NULL) {
	    krb5_set_error_string(context, "malloc: out of memory");
	    return ENOMEM;
	}
    } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) {
	ext2 = hdb_find_extension(entry, ext->data.element);
    } else {
	/* 
	 * This is an unknown extention, and we are asked to replace a
	 * possible entry in `entry' that is of the same type. This
	 * might seem impossible, but ASN.1 CHOICE comes to our
	 * rescue. The first tag in each branch in the CHOICE is
	 * unique, so just find the element in the list that have the
	 * same tag was we are putting into the list.
	 */
	Der_class replace_class, list_class;
	Der_type replace_type, list_type;
	unsigned int replace_tag, list_tag;
	size_t size;
	int i;

	ret = der_get_tag(ext->data.u.asn1_ellipsis.data,
			  ext->data.u.asn1_ellipsis.length,
			  &replace_class, &replace_type, &replace_tag,
			  &size);
	if (ret) {
	    krb5_set_error_string(context, "hdb: failed to decode "
				  "replacement hdb extention");
	    return ret;
	}

	for (i = 0; i < entry->extensions->len; i++) {
	    HDB_extension *ext3 = &entry->extensions->val[i];

	    if (ext3->data.element != choice_HDB_extension_data_asn1_ellipsis)
		continue;

	    ret = der_get_tag(ext3->data.u.asn1_ellipsis.data,
			      ext3->data.u.asn1_ellipsis.length,
			      &list_class, &list_type, &list_tag,
			      &size);
	    if (ret) {
		krb5_set_error_string(context, "hdb: failed to decode "
				      "present hdb extention");
		return ret;
	    }

	    if (MAKE_TAG(replace_class,replace_type,replace_type) ==
		MAKE_TAG(list_class,list_type,list_type)) {
		ext2 = ext3;
		break;
	    }
	}
    }

    if (ext2) {
	free_HDB_extension(ext2);
	ret = copy_HDB_extension(ext, ext2);
	if (ret)
	    krb5_set_error_string(context, "hdb: failed to copy replacement "
				  "hdb extention");
	return ret;
    }

    es = realloc(entry->extensions->val, 
		 (entry->extensions->len+1)*sizeof(entry->extensions->val[0]));
    if (es == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	return ENOMEM;
    }
    entry->extensions->val = es;

    ret = copy_HDB_extension(ext,
			     &entry->extensions->val[entry->extensions->len]);
    if (ret == 0)
	entry->extensions->len++;
    else
	krb5_set_error_string(context, "hdb: failed to copy new extension");

    return ret;
}
Ejemplo n.º 4
0
int
main(int argc, char **argv)
{
    krb5_error_code ret;
    krb5_context context;
    krb5_kdc_configuration *config;
    krb5_storage *sp;
    int fd, optidx = 0;

    setprogname(argv[0]);

    if(getarg(args, num_args, argc, argv, &optidx))
	usage(1);

    if(help_flag)
	usage(0);

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

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed to parse configuration file");

    ret = krb5_kdc_get_config(context, &config);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kdc_default_config");

    kdc_openlog(context, "kdc-replay", config);

    ret = krb5_kdc_set_dbinfo(context, config);
    if (ret)
	krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo");

#ifdef PKINIT
    if (config->enable_pkinit) {
	if (config->pkinit_kdc_identity == NULL)
	    krb5_errx(context, 1, "pkinit enabled but no identity");

	if (config->pkinit_kdc_anchors == NULL)
	    krb5_errx(context, 1, "pkinit enabled but no X509 anchors");

	krb5_kdc_pk_initialize(context, config,
			       config->pkinit_kdc_identity,
			       config->pkinit_kdc_anchors,
			       config->pkinit_kdc_cert_pool,
			       config->pkinit_kdc_revoke);

    }
#endif /* PKINIT */

    if (argc != 2)
	errx(1, "argc != 2");

    printf("kdc replay\n");

    fd = open(argv[1], O_RDONLY);
    if (fd < 0)
	err(1, "open: %s", argv[1]);

    sp = krb5_storage_from_fd(fd);
    if (sp == NULL)
	krb5_errx(context, 1, "krb5_storage_from_fd");

    while(1) {
	struct sockaddr_storage sa;
	krb5_socklen_t salen = sizeof(sa);
	struct timeval tv;
	krb5_address a;
	krb5_data d, r;
	uint32_t t, clty, tag;
	char astr[80];

	ret = krb5_ret_uint32(sp, &t);
	if (ret == HEIM_ERR_EOF)
	    break;
	else if (ret)
	    krb5_errx(context, 1, "krb5_ret_uint32(version)");
	if (t != 1)
	    krb5_errx(context, 1, "version not 1");
	ret = krb5_ret_uint32(sp, &t);
	if (ret)
	    krb5_errx(context, 1, "krb5_ret_uint32(time)");
	ret = krb5_ret_address(sp, &a);
	if (ret)
	    krb5_errx(context, 1, "krb5_ret_address");
	ret = krb5_ret_data(sp, &d);
	if (ret)
	    krb5_errx(context, 1, "krb5_ret_data");
	ret = krb5_ret_uint32(sp, &clty);
	if (ret)
	    krb5_errx(context, 1, "krb5_ret_uint32(class|type)");
	ret = krb5_ret_uint32(sp, &tag);
	if (ret)
	    krb5_errx(context, 1, "krb5_ret_uint32(tag)");


	ret = krb5_addr2sockaddr (context, &a, (struct sockaddr *)&sa,
				  &salen, 88);
	if (ret == KRB5_PROG_ATYPE_NOSUPP)
	    goto out;
	else if (ret)
	    krb5_err(context, 1, ret, "krb5_addr2sockaddr");

	ret = krb5_print_address(&a, astr, sizeof(astr), NULL);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_print_address");

	printf("processing request from %s, %lu bytes\n",
	       astr, (unsigned long)d.length);

	r.length = 0;
	r.data = NULL;

	tv.tv_sec = t;
	tv.tv_usec = 0;

	krb5_kdc_update_time(&tv);
	krb5_set_real_time(context, tv.tv_sec, 0);

	ret = krb5_kdc_process_request(context, config, d.data, d.length,
				       &r, NULL, astr,
				       (struct sockaddr *)&sa, 0);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_kdc_process_request");

	if (r.length) {
	    Der_class cl;
	    Der_type ty;
	    unsigned int tag2;
	    ret = der_get_tag (r.data, r.length,
			       &cl, &ty, &tag2, NULL);
	    if (MAKE_TAG(cl, ty, 0) != clty)
		krb5_errx(context, 1, "class|type mismatch: %d != %d",
			  (int)MAKE_TAG(cl, ty, 0), (int)clty);
	    if (tag != tag2)
		krb5_errx(context, 1, "tag mismatch");

	    krb5_data_free(&r);
	} else {
	    if (clty != 0xffffffff)
		krb5_errx(context, 1, "clty not invalid");
	    if (tag != 0xffffffff)
		krb5_errx(context, 1, "tag not invalid");
	}

    out:
	krb5_data_free(&d);
	krb5_free_address(context, &a);
    }

    krb5_storage_free(sp);
    krb5_free_context(context);

    printf("done\n");

    return 0;
}
Ejemplo n.º 5
0
int
krb5_kdc_save_request(krb5_context context,
		      const char *fn,
		      const unsigned char *buf,
		      size_t len,
		      const krb5_data *reply,
		      const struct sockaddr *sa)
{
    krb5_storage *sp;
    krb5_address a;
    int fd, ret;
    uint32_t t;
    krb5_data d;

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

    d.data = rk_UNCONST(buf);
    d.length = len;
    t = _kdc_now.tv_sec;

    fd = open(fn, O_WRONLY|O_CREAT|O_APPEND, 0600);
    if (fd < 0) {
	int saved_errno = errno;
	krb5_set_error_message(context, saved_errno, "Failed to open: %s", fn);
	return saved_errno;
    }

    sp = krb5_storage_from_fd(fd);
    close(fd);
    if (sp == NULL) {
	krb5_set_error_message(context, ENOMEM, "Storage failed to open fd");
	return ENOMEM;
    }

    ret = krb5_sockaddr2address(context, sa, &a);
    if (ret)
	goto out;

    krb5_store_uint32(sp, 1);
    krb5_store_uint32(sp, t);
    krb5_store_address(sp, a);
    krb5_store_data(sp, d);
    {
	Der_class cl;
	Der_type ty;
	unsigned int tag;
	ret = der_get_tag (reply->data, reply->length,
			   &cl, &ty, &tag, NULL);
	if (ret) {
	    krb5_store_uint32(sp, 0xffffffff);
	    krb5_store_uint32(sp, 0xffffffff);
	} else {
	    krb5_store_uint32(sp, MAKE_TAG(cl, ty, 0));
	    krb5_store_uint32(sp, tag);
	}
    }

    krb5_free_address(context, &a);
out:
    krb5_storage_free(sp);

    return 0;
}