Esempio n. 1
0
/* Internalize a keyblock and convert it to a key. */
static krb5_error_code
intern_key(krb5_context ctx, krb5_key *key, krb5_octet **bp, size_t *sp)
{
    krb5_keyblock *keyblock;
    krb5_error_code ret;

    ret = krb5_internalize_opaque(ctx, KV5M_KEYBLOCK,
                                  (krb5_pointer *) &keyblock, bp, sp);
    if (ret != 0)
        return ret;
    ret = krb5_k_create_key(ctx, keyblock, key);
    krb5_free_keyblock(ctx, keyblock);
    return ret;
}
Esempio n. 2
0
/*
 * krb5_auth_context_internalize()	- Internalize the krb5_auth_context.
 */
static krb5_error_code
krb5_auth_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_auth_context	auth_context;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    krb5_int32		ivlen;
    krb5_int32		tag;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_AUTH_CONTEXT) {
	kret = ENOMEM;

	/* Get memory for the auth_context */
	if ((remain >= (5*sizeof(krb5_int32))) &&
	    (auth_context = (krb5_auth_context)
	     calloc(1, sizeof(struct _krb5_auth_context)))) {

	    /* Get auth_context_flags */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->auth_context_flags = ibuf;

	    /* Get remote_seq_number */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->remote_seq_number = ibuf;

	    /* Get local_seq_number */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->local_seq_number = ibuf;

	    /* Get req_cksumtype */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->req_cksumtype = (krb5_cksumtype) ibuf;

	    /* Get safe_cksumtype */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    auth_context->safe_cksumtype = (krb5_cksumtype) ibuf;

	    /* Get length of i_vector */
	    (void) krb5_ser_unpack_int32(&ivlen, &bp, &remain);

	    if (ivlen) {
		if ((auth_context->i_vector =
		     (krb5_pointer) malloc((size_t)ivlen)))
		    kret = krb5_ser_unpack_bytes(auth_context->i_vector,
						 (size_t) ivlen,
						 &bp,
						 &remain);
		else
		    kret = ENOMEM;
	    }
	    else
		kret = 0;
	    
	    /* Peek at next token */
	    tag = 0;
	    if (!kret)
		kret = krb5_ser_unpack_int32(&tag, &bp, &remain);

	    /* This is the remote_addr */
	    if (!kret && (tag == TOKEN_RADDR)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     remote_addr,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the remote_port */
	    if (!kret && (tag == TOKEN_RPORT)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     remote_port,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the local_addr */
	    if (!kret && (tag == TOKEN_LADDR)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     local_addr,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the local_port */
	    if (!kret && (tag == TOKEN_LPORT)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_ADDRESS,
						     (krb5_pointer *)
						     &auth_context->
						     local_port,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the keyblock */
	    if (!kret && (tag == TOKEN_KEYBLOCK)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_KEYBLOCK,
						     (krb5_pointer *)
						     &auth_context->keyblock,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the send_subkey */
	    if (!kret && (tag == TOKEN_LSKBLOCK)) {
		if (!(kret = krb5_internalize_opaque(kcontext,
						     KV5M_KEYBLOCK,
						     (krb5_pointer *)
						     &auth_context->
						     send_subkey,
						     &bp,
						     &remain)))
		    kret = krb5_ser_unpack_int32(&tag, &bp, &remain);
	    }

	    /* This is the recv_subkey */
	    if (!kret) {
		if (tag == TOKEN_RSKBLOCK) {
		    kret = krb5_internalize_opaque(kcontext,
						   KV5M_KEYBLOCK,
						   (krb5_pointer *)
						   &auth_context->
						   recv_subkey,
						   &bp,
						   &remain);
		}
		else {
		    /*
		     * We read the next tag, but it's not of any use here, so
		     * we effectively 'unget' it here.
		     */
		    bp -= sizeof(krb5_int32);
		    remain += sizeof(krb5_int32);
		}
	    }

	    /* Now find the authentp */
	    if (!kret) {
		if ((kret = krb5_internalize_opaque(kcontext,
						    KV5M_AUTHENTICATOR,
						    (krb5_pointer *)
						    &auth_context->authentp,
						    &bp,
						    &remain))) {
		    if (kret == EINVAL)
			kret = 0;
		}
	    }

	    /* Finally, find the trailer */
	    if (!kret) {
		kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
		if (!kret && (ibuf != KV5M_AUTH_CONTEXT))
		    kret = EINVAL;
	    }
	    if (!kret) {
		*buffer = bp;
		*lenremain = remain;
		auth_context->magic = KV5M_AUTH_CONTEXT;
		*argp = (krb5_pointer) auth_context;
	    }
	    else
		krb5_auth_con_free(kcontext, auth_context);
	}
    }
    return(kret);
}
Esempio n. 3
0
static krb5_error_code
s4u2proxy_internalize(krb5_context kcontext,
                      krb5_authdata_context context,
                      void *plugin_context,
                      void *request_context,
                      krb5_octet **buffer,
                      size_t *lenremain)
{
    struct s4u2proxy_context *s4uctx = (struct s4u2proxy_context *)request_context;
    krb5_error_code code;
    krb5_int32 ibuf;
    krb5_octet *bp;
    size_t remain;
    int count;
    krb5_principal *delegated = NULL;

    bp = *buffer;
    remain = *lenremain;

    /* version */
    code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (code != 0)
        goto cleanup;

    if (ibuf != 1) {
        code = EINVAL;
        goto cleanup;
    }

    /* count */
    code = krb5_ser_unpack_int32(&count, &bp, &remain);
    if (code != 0)
        goto cleanup;

    if (count > 65535)
        return ERANGE; /* let's set some reasonable limits here */
    else if (count > 0) {
        int i;

        delegated = k5calloc(count + 1, sizeof(krb5_principal), &code);
        if (delegated == NULL)
            goto cleanup;

        for (i = 0; i < count; i++) {
            code = krb5_internalize_opaque(kcontext, KV5M_PRINCIPAL,
                                           (krb5_pointer *)&delegated[i],
                                           &bp, &remain);
            if (code != 0)
                goto cleanup;
        }

        delegated[i] = NULL;
    }

    code = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
    if (code != 0)
        goto cleanup;

    s4u2proxy_free_internal(kcontext, context,
                            plugin_context, request_context,
                            s4uctx->delegated);

    s4uctx->count = count;
    s4uctx->delegated = delegated;
    s4uctx->authenticated = (ibuf != 0);

    delegated = NULL;

    *buffer = bp;
    *lenremain = remain;

cleanup:
    s4u2proxy_free_internal(kcontext, context,
                            plugin_context, request_context,
                            delegated);

    return code;
}
Esempio n. 4
0
/*
 * krb5_authenticator_internalize()	- Internalize the krb5_authenticator.
 */
static krb5_error_code
krb5_authenticator_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_authenticator	*authenticator;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    int			i;
    krb5_int32		nadata;
    size_t		len;

    bp = *buffer;
    remain = *lenremain;
    kret = EINVAL;
    /* Read our magic number */
    if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
	ibuf = 0;
    if (ibuf == KV5M_AUTHENTICATOR) {
	kret = ENOMEM;

	/* Get memory for the authenticator */
	if ((remain >= (3*sizeof(krb5_int32))) &&
	    (authenticator = (krb5_authenticator *) 
	     calloc(1, sizeof(krb5_authenticator)))) {

	    /* Get ctime */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    authenticator->ctime = (krb5_timestamp) ibuf;

	    /* Get cusec */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    authenticator->cusec = ibuf;

	    /* Get seq_number */
	    (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
	    authenticator->seq_number = ibuf;
	    
	    kret = 0;

	    /* Attempt to read in the client */
	    kret = krb5_internalize_opaque(kcontext,
					   KV5M_PRINCIPAL,
					   (krb5_pointer *)
					   &authenticator->client,
					   &bp,
					   &remain);
	    if (kret == EINVAL)
		kret = 0;

	    /* Attempt to read in the checksum */
	    if (!kret) {
		kret = krb5_internalize_opaque(kcontext,
					       KV5M_CHECKSUM,
					       (krb5_pointer *)
					       &authenticator->checksum,
					       &bp,
					       &remain);
		if (kret == EINVAL)
		    kret = 0;
	    }

	    /* Attempt to read in the subkey */
	    if (!kret) {
		kret = krb5_internalize_opaque(kcontext,
					       KV5M_KEYBLOCK,
					       (krb5_pointer *)
					       &authenticator->subkey,
					       &bp,
					       &remain);
		if (kret == EINVAL)
		    kret = 0;
	    }

	    /* Attempt to read in the authorization data count */
	    if (!(kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain))) {
		nadata = ibuf;
		len = (size_t) (nadata + 1);

		/* Get memory for the authorization data pointers */
		if ((authenticator->authorization_data = (krb5_authdata **)
		     calloc(len, sizeof(krb5_authdata *)))) {
		    for (i=0; !kret && (i<nadata); i++) {
			kret = krb5_internalize_opaque(kcontext,
						       KV5M_AUTHDATA,
						       (krb5_pointer *)
						       &authenticator->
						       authorization_data[i],
						       &bp,
						       &remain);
		    }

		    /* Finally, find the trailer */
		    if (!kret) {
			kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
			if (!kret && (ibuf == KV5M_AUTHENTICATOR))
			    authenticator->magic = KV5M_AUTHENTICATOR;
			else
			    kret = EINVAL;
		    }
		}
	    }
	    if (!kret) {
		*buffer = bp;
		*lenremain = remain;
		*argp = (krb5_pointer) authenticator;
	    }
	    else
		krb5_free_authenticator(kcontext, authenticator);
	}
    }
    return(kret);
}
Esempio n. 5
0
/*
 * Do a serialization test.
 */
static krb5_error_code
ser_data(int verbose, char *msg, krb5_pointer ctx, krb5_magic dtype)
{
    krb5_error_code	kret;
    krb5_context	ser_ctx;
    krb5_pointer	nctx;
    krb5_octet		*outrep, *ibuf, *outrep2;
    size_t		outlen, ilen, outlen2;

    /* Initialize context and initialize all Kerberos serializers */
    if ((kret = krb5_init_context(&ser_ctx))) {
	    printf("Couldn't initialize krb5 library: %s\n",
		   error_message(kret));
	    exit(1);
    }
    krb5_ser_context_init(ser_ctx);
    krb5_ser_auth_context_init(ser_ctx);
    krb5_ser_ccache_init(ser_ctx);
    krb5_ser_rcache_init(ser_ctx);
    krb5_ser_keytab_init(ser_ctx);

    /* Externalize the data */
    kret = krb5_externalize_data(ser_ctx, ctx, &outrep, &outlen);
    if (!kret) {
	if (verbose) {
	    printf("%s: externalized in %d bytes\n", msg, outlen);
	    print_erep(outrep, outlen);
	}

	/* Now attempt to re-constitute it */
	ibuf = outrep;
	ilen = outlen;
	kret = krb5_internalize_opaque(ser_ctx,
				       dtype,
				       (krb5_pointer *) &nctx,
				       &ibuf,
				       &ilen);
	if (!kret) {
	    if (ilen)
		printf("%s: %d bytes left over after internalize\n",
		       msg, ilen);
	    /* Now attempt to re-externalize it */
	    kret = krb5_externalize_data(ser_ctx, nctx, &outrep2, &outlen2);
	    if (!kret) {
		/* Compare the results. */
		if ((outlen2 != outlen) ||
		    memcmp(outrep, outrep2, outlen)) {
		    printf("%s: comparison failed\n", msg);
		    print_erep(outrep2, outlen2);
		}
		else {
		    if (verbose)
			printf("%s: compare succeeded\n", msg);
		}
		krb5_xfree(outrep2);
	    }
	    else
		printf("%s: second externalize returned %d\n", msg, kret);

	    /* Free the data */
	    switch (dtype) {
	    case KV5M_CONTEXT:
		krb5_free_context((krb5_context) nctx);
		break;
	    case KV5M_AUTH_CONTEXT:
		if (nctx) {
		    krb5_auth_context	actx;

		    actx = (krb5_auth_context) nctx;
		    if (actx->i_vector)
			krb5_xfree(actx->i_vector);
		}
		krb5_auth_con_free(ser_ctx, (krb5_auth_context) nctx);
		break;
	    case KV5M_CCACHE:
		krb5_cc_close(ser_ctx, (krb5_ccache) nctx);
		break;
	    case KV5M_RCACHE:
		krb5_rc_close(ser_ctx, (krb5_rcache) nctx);
		break;
	    case KV5M_KEYTAB:
		krb5_kt_close(ser_ctx, (krb5_keytab) nctx);
		break;
	    case KV5M_ENCRYPT_BLOCK:
		if (nctx) {
		    krb5_encrypt_block *eblock;

		    eblock = (krb5_encrypt_block *) nctx;
#if 0
		    if (eblock->priv && eblock->priv_size)
			krb5_xfree(eblock->priv);
#endif
		    if (eblock->key)
			krb5_free_keyblock(ser_ctx, eblock->key);
		    krb5_xfree(eblock);
		}
		break;
	    case KV5M_PRINCIPAL:
		krb5_free_principal(ser_ctx, (krb5_principal) nctx);
		break;
	    case KV5M_CHECKSUM:
		krb5_free_checksum(ser_ctx, (krb5_checksum *) nctx);
		break;
	    default:
		printf("don't know how to free %d\n", dtype);
		break;
	    }
	}
	else
	    printf("%s: internalize returned %d\n", msg, kret);
	krb5_xfree(outrep);
    }
    else
	printf("%s: externalize_data returned %d\n", msg, kret);
    krb5_free_context(ser_ctx);
    return(kret);
}
Esempio n. 6
0
/*
 * krb5_context_internalize()	- Internalize the krb5_context.
 */
static krb5_error_code
krb5_context_internalize(krb5_context kcontext, krb5_pointer *argp, krb5_octet **buffer, size_t *lenremain)
{
    krb5_error_code	kret;
    krb5_context	context;
    krb5_int32		ibuf;
    krb5_octet		*bp;
    size_t		remain;
    int			i;

    bp = *buffer;
    remain = *lenremain;

    /* Read our magic number */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	return (EINVAL);

    if (ibuf != KV5M_CONTEXT)
	return (EINVAL);

    /* Get memory for the context */
    context = (krb5_context) MALLOC(sizeof(struct _krb5_context));
    if (!context)
	return (ENOMEM);
    (void) memset(context, 0, sizeof(struct _krb5_context));

    /* Get the size of the default realm */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;

    if (ibuf) {
	context->default_realm = (char *) MALLOC((size_t) ibuf+1);
	if (!context->default_realm) {
	    kret = ENOMEM;
	    goto cleanup;
	}

	kret = krb5_ser_unpack_bytes((krb5_octet *) context->default_realm,
				     (size_t) ibuf, &bp, &remain);
	if (kret)
	    goto cleanup;
	
	context->default_realm[ibuf] = '\0';
    }
	
    /* Get the number of in_tkt_ktypes */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    
    context->in_tkt_ktype_count = (int) ibuf;
    context->in_tkt_ktypes = (krb5_enctype *) MALLOC(sizeof(krb5_enctype) *
				     (context->in_tkt_ktype_count+1));
    if (!context->in_tkt_ktypes) {
	kret = ENOMEM;
	goto cleanup;
    }
    (void) memset(context->in_tkt_ktypes, 0, (sizeof(krb5_enctype) *
				       (context->in_tkt_ktype_count + 1)));
    
    for (i=0; i<context->in_tkt_ktype_count; i++) {
	if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	    goto cleanup;
	context->in_tkt_ktypes[i] = (krb5_enctype) ibuf;
    }

    /* Get the number of tgs_ktypes */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    
    context->tgs_ktype_count = (int) ibuf;
    context->tgs_ktypes = (krb5_enctype *) MALLOC(sizeof(krb5_enctype) *
				  (context->tgs_ktype_count+1));
    if (!context->tgs_ktypes) {
	kret = ENOMEM;
	goto cleanup;
    }
    (void) memset(context->tgs_ktypes, 0, (sizeof(krb5_enctype) *
				    (context->tgs_ktype_count + 1)));
    for (i=0; i<context->tgs_ktype_count; i++) {
	if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	    goto cleanup;
	context->tgs_ktypes[i] = (krb5_enctype) ibuf;
    }

    /* Allowable checksum */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->clockskew = (krb5_deltat) ibuf;
    
    /* kdc_req_sumtype */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->kdc_req_sumtype = (krb5_cksumtype) ibuf;
    
    /* default ap_req_sumtype */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->default_ap_req_sumtype = (krb5_cksumtype) ibuf;
    
    /* default_safe_sumtype */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->default_safe_sumtype = (krb5_cksumtype) ibuf;

    /* kdc_default_options */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->kdc_default_options = (krb5_flags) ibuf;

    /* library_options */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->library_options = (krb5_flags) ibuf;

    /* profile_secure */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->profile_secure = (krb5_boolean) ibuf;

    /* fcc_default_format */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->fcc_default_format = (int) ibuf;

    /* scc_default_format */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;
    context->scc_default_format = (int) ibuf;
    
    /* Attempt to read in the os_context.  It's an array now, but
       we still treat it in most places as a separate object with
       a pointer.  */
    {
	krb5_os_context osp = 0;
	kret = krb5_internalize_opaque(kcontext, KV5M_OS_CONTEXT,
				       (krb5_pointer *) &osp,
				       &bp, &remain);
	if (kret && (kret != EINVAL) && (kret != ENOENT))
	    goto cleanup;
	/* Put the newly allocated data into the krb5_context
	   structure where we're really keeping it these days.  */
	if (osp)
	    *context->os_context = *osp;
	free(osp);
    }

    /* Attempt to read in the db_context */
    kret = krb5_internalize_opaque(kcontext, KV5M_DB_CONTEXT,
				   (krb5_pointer *) &context->db_context,
				   &bp, &remain);
    if (kret && (kret != EINVAL) && (kret != ENOENT))
	goto cleanup;
   
#ifndef _KERNEL 
    /* Attempt to read in the profile */
    kret = krb5_internalize_opaque(kcontext, PROF_MAGIC_PROFILE,
				   (krb5_pointer *) &context->profile,
				   &bp, &remain);
#endif
    if (kret && (kret != EINVAL) && (kret != ENOENT))
	goto cleanup;
    
    /* Finally, find the trailer */
    if ((kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain)))
	goto cleanup;

    if (ibuf != KV5M_CONTEXT) {
	kret = EINVAL;
	goto cleanup;
    }

    context->magic = KV5M_CONTEXT;
    *buffer = bp;
    *lenremain = remain;
    *argp = (krb5_pointer) context;

    return 0;

cleanup:
    if (context)
	krb5_free_context(context);
    return(kret);
}