Ejemplo n.º 1
0
krb5_error_code
krb5_auth_con_setaddrs(krb5_context context, krb5_auth_context auth_context, krb5_address *local_addr, krb5_address *remote_addr)
{
    krb5_error_code     retval;

    /* Free old addresses */
    if (auth_context->local_addr)
        (void) krb5_free_address(context, auth_context->local_addr);
    if (auth_context->remote_addr)
        (void) krb5_free_address(context, auth_context->remote_addr);

    retval = 0;
    if (local_addr)
        retval = krb5_copy_addr(context,
                                local_addr,
                                &auth_context->local_addr);
    else
        auth_context->local_addr = NULL;

    if (!retval && remote_addr)
        retval = krb5_copy_addr(context,
                                remote_addr,
                                &auth_context->remote_addr);
    else
        auth_context->remote_addr = NULL;

    return retval;
}
Ejemplo n.º 2
0
krb5_error_code KRB5_CALLCONV
krb5_auth_con_setports(krb5_context context, krb5_auth_context auth_context, krb5_address *local_port, krb5_address *remote_port)
{
    krb5_error_code     retval;

    /* Free old addresses */
    if (auth_context->local_port)
        (void) krb5_free_address(context, auth_context->local_port);
    if (auth_context->remote_port)
        (void) krb5_free_address(context, auth_context->remote_port);

    retval = 0;
    if (local_port)
        retval = krb5_copy_addr(context,
                                local_port,
                                &auth_context->local_port);
    else
        auth_context->local_port = NULL;

    if (!retval && remote_port)
        retval = krb5_copy_addr(context,
                                remote_port,
                                &auth_context->remote_port);
    else
        auth_context->remote_port = NULL;

    return retval;
}
Ejemplo n.º 3
0
krb5_error_code KRB5_CALLCONV
krb5_auth_con_free(krb5_context context, krb5_auth_context auth_context)
{
    if (auth_context == NULL)
        return 0;
    if (auth_context->local_addr)
        krb5_free_address(context, auth_context->local_addr);
    if (auth_context->remote_addr)
        krb5_free_address(context, auth_context->remote_addr);
    if (auth_context->local_port)
        krb5_free_address(context, auth_context->local_port);
    if (auth_context->remote_port)
        krb5_free_address(context, auth_context->remote_port);
    if (auth_context->authentp)
        krb5_free_authenticator(context, auth_context->authentp);
    if (auth_context->key)
        krb5_k_free_key(context, auth_context->key);
    if (auth_context->send_subkey)
        krb5_k_free_key(context, auth_context->send_subkey);
    if (auth_context->recv_subkey)
        krb5_k_free_key(context, auth_context->recv_subkey);
    if (auth_context->rcache)
        krb5_rc_close(context, auth_context->rcache);
    if (auth_context->permitted_etypes)
        free(auth_context->permitted_etypes);
    if (auth_context->ad_context)
        krb5_authdata_context_free(context, auth_context->ad_context);
    free(auth_context);
    return 0;
}
Ejemplo n.º 4
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getaddrs(krb5_context context,
		       krb5_auth_context auth_context,
		       krb5_address **local_addr,
		       krb5_address **remote_addr)
{
    if(*local_addr)
	krb5_free_address (context, *local_addr);
    *local_addr = malloc (sizeof(**local_addr));
    if (*local_addr == NULL) {
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }
    krb5_copy_address(context,
		      auth_context->local_address,
		      *local_addr);

    if(*remote_addr)
	krb5_free_address (context, *remote_addr);
    *remote_addr = malloc (sizeof(**remote_addr));
    if (*remote_addr == NULL) {
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	krb5_free_address (context, *local_addr);
	*local_addr = NULL;
	return ENOMEM;
    }
    krb5_copy_address(context,
		      auth_context->remote_address,
		      *remote_addr);
    return 0;
}
Ejemplo n.º 5
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_auth_con_genaddrs(krb5_context context,
		       krb5_auth_context auth_context,
		       int fd, int flags)
{
    krb5_error_code ret;
    krb5_address local_k_address, remote_k_address;
    krb5_address *lptr = NULL, *rptr = NULL;
    struct sockaddr_storage ss_local, ss_remote;
    struct sockaddr *local  = (struct sockaddr *)&ss_local;
    struct sockaddr *remote = (struct sockaddr *)&ss_remote;
    socklen_t len;

    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
	if (auth_context->local_address == NULL) {
	    len = sizeof(ss_local);
	    if(getsockname(fd, local, &len) < 0) {
		ret = errno;
		krb5_set_error_message(context, ret,
				       "getsockname: %s",
				       strerror(ret));
		goto out;
	    }
	    ret = krb5_sockaddr2address (context, local, &local_k_address);
	    if(ret) goto out;
	    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
		krb5_sockaddr2port (context, local, &auth_context->local_port);
	    } else
		auth_context->local_port = 0;
	    lptr = &local_k_address;
	}
    }
    if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
	len = sizeof(ss_remote);
	if(getpeername(fd, remote, &len) < 0) {
	    ret = errno;
	    krb5_set_error_message(context, ret,
				   "getpeername: %s", strerror(ret));
	    goto out;
	}
	ret = krb5_sockaddr2address (context, remote, &remote_k_address);
	if(ret) goto out;
	if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
	    krb5_sockaddr2port (context, remote, &auth_context->remote_port);
	} else
	    auth_context->remote_port = 0;
	rptr = &remote_k_address;
    }
    ret = krb5_auth_con_setaddrs (context,
				  auth_context,
				  lptr,
				  rptr);
  out:
    if (lptr)
	krb5_free_address (context, lptr);
    if (rptr)
	krb5_free_address (context, rptr);
    return ret;

}
Ejemplo n.º 6
0
static OM_uint32
set_addresses (krb5_auth_context ac,
	       const gss_channel_bindings_t input_chan_bindings)	       
{
    /* Port numbers are expected to be in application_data.value, 
     * initator's port first */ 

    krb5_address initiator_addr, acceptor_addr;
    krb5_error_code kret;
       
    if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS
	|| input_chan_bindings->application_data.length !=
	2 * sizeof(ac->local_port))
	return 0;

    memset(&initiator_addr, 0, sizeof(initiator_addr));
    memset(&acceptor_addr, 0, sizeof(acceptor_addr));
       
    ac->local_port =
	*(int16_t *) input_chan_bindings->application_data.value;
       
    ac->remote_port =
	*((int16_t *) input_chan_bindings->application_data.value + 1);
       
    kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->acceptor_addrtype,
					 &input_chan_bindings->acceptor_address,
					 ac->remote_port,
					 &acceptor_addr);
    if (kret)
	return kret;
           
    kret = _gsskrb5i_address_to_krb5addr(input_chan_bindings->initiator_addrtype,
					 &input_chan_bindings->initiator_address,
					 ac->local_port,
					 &initiator_addr);
    if (kret) {
	krb5_free_address (_gsskrb5_context, &acceptor_addr);
	return kret;
    }
       
    kret = krb5_auth_con_setaddrs(_gsskrb5_context,
				  ac,
				  &initiator_addr,  /* local address */
				  &acceptor_addr);  /* remote address */
       
    krb5_free_address (_gsskrb5_context, &initiator_addr);
    krb5_free_address (_gsskrb5_context, &acceptor_addr);
       
#if 0
    free(input_chan_bindings->application_data.value);
    input_chan_bindings->application_data.value = NULL;
    input_chan_bindings->application_data.length = 0;
#endif

    return kret;
}
Ejemplo n.º 7
0
void KRB5_CALLCONV
krb5_free_priv_enc_part(krb5_context context, register krb5_priv_enc_part *val)
{
    if (val == NULL)
        return;
    free(val->user_data.data);
    krb5_free_address(context, val->r_address);
    krb5_free_address(context, val->s_address);
    free(val);
}
Ejemplo n.º 8
0
static int
arange_free (krb5_context context, krb5_address *addr)
{
    struct arange *a;
    a = addr->address.data;
    krb5_free_address(context, &a->low);
    krb5_free_address(context, &a->high);
    krb5_data_free(&addr->address);
    return 0;
}
Ejemplo n.º 9
0
void KRB5_CALLCONV
krb5_free_safe(krb5_context context, register krb5_safe *val)
{
    if (val == NULL)
        return;
    free(val->user_data.data);
    krb5_free_address(context, val->r_address);
    krb5_free_address(context, val->s_address);
    krb5_free_checksum(context, val->checksum);
    free(val);
}
Ejemplo n.º 10
0
Archivo: 524.c Proyecto: gojdic/samba
static krb5_error_code
set_address (krb5_context context,
	     krb5_kdc_configuration *config,
	     EncTicketPart *et,
	     struct sockaddr *addr,
	     const char *from)
{
    krb5_error_code ret;
    krb5_address *v4_addr;

    v4_addr = malloc (sizeof(*v4_addr));
    if (v4_addr == NULL)
	return ENOMEM;

    ret = krb5_sockaddr2address(context, addr, v4_addr);
    if(ret) {
	free (v4_addr);
	kdc_log(context, config, 0, "Failed to convert address (%s)", from);
	return ret;
    }
	
    if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) {
	kdc_log(context, config, 0, "Incorrect network address (%s)", from);
	krb5_free_address(context, v4_addr);
	free (v4_addr);
	return KRB5KRB_AP_ERR_BADADDR;
    }
    if(v4_addr->addr_type == KRB5_ADDRESS_INET) {
	/* we need to collapse the addresses in the ticket to a
	   single address; best guess is to use the address the
	   connection came from */
	
	if (et->caddr != NULL) {
	    free_HostAddresses(et->caddr);
	} else {
	    et->caddr = malloc (sizeof (*et->caddr));
	    if (et->caddr == NULL) {
		krb5_free_address(context, v4_addr);
		free(v4_addr);
		return ENOMEM;
	    }
	}
	et->caddr->val = v4_addr;
	et->caddr->len = 1;
    } else {
	krb5_free_address(context, v4_addr);
	free(v4_addr);
    }
    return 0;
}
Ejemplo n.º 11
0
static int
arange_copy (krb5_context context, const krb5_address *inaddr,
	     krb5_address *outaddr)
{
    krb5_error_code ret;
    struct arange *i, *o;

    outaddr->addr_type = KRB5_ADDRESS_ARANGE;
    ret = krb5_data_alloc(&outaddr->address, sizeof(*o));
    if(ret)
	return ret;
    i = inaddr->address.data;
    o = outaddr->address.data;
    ret = krb5_copy_address(context, &i->low, &o->low);
    if(ret) {
	krb5_data_free(&outaddr->address);
	return ret;
    }
    ret = krb5_copy_address(context, &i->high, &o->high);
    if(ret) {
	krb5_free_address(context, &o->low);
	krb5_data_free(&outaddr->address);
	return ret;
    }
    return 0;
}
Ejemplo n.º 12
0
static int
ipv4_mask_boundary(krb5_context context, const krb5_address *inaddr,
		   unsigned long len, krb5_address *low, krb5_address *high)
{
    unsigned long ia;
    uint32_t l, h, m = 0xffffffff;

    if (len > 32) {
	krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
			       N_("IPv4 prefix too large (%ld)", "len"), len);
	return KRB5_PROG_ATYPE_NOSUPP;
    }
    m = m << (32 - len);

    _krb5_get_int(inaddr->address.data, &ia, inaddr->address.length);

    l = ia & m;
    h = l | ~m;

    low->addr_type = KRB5_ADDRESS_INET;
    if(krb5_data_alloc(&low->address, 4) != 0)
	return -1;
    _krb5_put_int(low->address.data, l, low->address.length);

    high->addr_type = KRB5_ADDRESS_INET;
    if(krb5_data_alloc(&high->address, 4) != 0) {
	krb5_free_address(context, low);
	return -1;
    }
    _krb5_put_int(high->address.data, h, high->address.length);

    return 0;
}
Ejemplo n.º 13
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_free_addresses(krb5_context context,
		    krb5_addresses *addresses)
{
    int i;
    for(i = 0; i < addresses->len; i++)
	krb5_free_address(context, &addresses->val[i]);
    free(addresses->val);
    addresses->len = 0;
    addresses->val = NULL;
    return 0;
}
Ejemplo n.º 14
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_auth_con_setaddrs(krb5_context context,
		       krb5_auth_context auth_context,
		       krb5_address *local_addr,
		       krb5_address *remote_addr)
{
    if (local_addr) {
	if (auth_context->local_address)
	    krb5_free_address (context, auth_context->local_address);
	else
	    auth_context->local_address = malloc(sizeof(krb5_address));
	krb5_copy_address(context, local_addr, auth_context->local_address);
    }
    if (remote_addr) {
	if (auth_context->remote_address)
	    krb5_free_address (context, auth_context->remote_address);
	else
	    auth_context->remote_address = malloc(sizeof(krb5_address));
	krb5_copy_address(context, remote_addr, auth_context->remote_address);
    }
    return 0;
}
Ejemplo n.º 15
0
static int
ipv6_mask_boundary(krb5_context context, const krb5_address *inaddr,
		   unsigned long len, krb5_address *low, krb5_address *high)
{
    struct in6_addr addr, laddr, haddr;
    uint32_t m;
    int i, sub_len;

    if (len > 128) {
	krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
			       N_("IPv6 prefix too large (%ld)", "length"), len);
	return KRB5_PROG_ATYPE_NOSUPP;
    }

    if (inaddr->address.length != sizeof(addr)) {
	krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP,
			       N_("IPv6 addr bad length", ""));
	return KRB5_PROG_ATYPE_NOSUPP;
    }

    memcpy(&addr, inaddr->address.data, inaddr->address.length);

    for (i = 0; i < 16; i++) {
	sub_len = min(8, len);

	m = 0xff << (8 - sub_len);
	
	laddr.s6_addr[i] = addr.s6_addr[i] & m;
	haddr.s6_addr[i] = (addr.s6_addr[i] & m) | ~m;

	if (len > 8)
	    len -= 8;
	else
	    len = 0;
    }

    low->addr_type = KRB5_ADDRESS_INET6;
    if (krb5_data_alloc(&low->address, sizeof(laddr.s6_addr)) != 0)
	return -1;
    memcpy(low->address.data, laddr.s6_addr, sizeof(laddr.s6_addr));

    high->addr_type = KRB5_ADDRESS_INET6;
    if (krb5_data_alloc(&high->address, sizeof(haddr.s6_addr)) != 0) {
	krb5_free_address(context, low);
	return -1;
    }
    memcpy(high->address.data, haddr.s6_addr, sizeof(haddr.s6_addr));

    return 0;
}
Ejemplo n.º 16
0
void KRB5_CALLCONV
krb5_free_cred_enc_part(krb5_context context, register krb5_cred_enc_part *val)
{
    register krb5_cred_info **temp;

    if (val == NULL)
        return;
    krb5_free_address(context, val->r_address);
    val->r_address = 0;
    krb5_free_address(context, val->s_address);
    val->s_address = 0;

    if (val->ticket_info) {
        for (temp = val->ticket_info; *temp; temp++) {
            krb5_free_keyblock(context, (*temp)->session);
            krb5_free_principal(context, (*temp)->client);
            krb5_free_principal(context, (*temp)->server);
            krb5_free_addresses(context, (*temp)->caddrs);
            free(*temp);
        }
        free(val->ticket_info);
        val->ticket_info = 0;
    }
}
Ejemplo n.º 17
0
static int
spawn_child(krb5_context contextp, int *socks,
	    unsigned int num_socks, int this_sock)
{
    int e;
    size_t i;
    struct sockaddr_storage __ss;
    struct sockaddr *sa = (struct sockaddr *)&__ss;
    socklen_t sa_size = sizeof(__ss);
    krb5_socket_t s;
    pid_t pid;
    krb5_address addr;
    char buf[128];
    size_t buf_len;

    s = accept(socks[this_sock], sa, &sa_size);
    if(rk_IS_BAD_SOCKET(s)) {
	krb5_warn(contextp, rk_SOCK_ERRNO, "accept");
	return 1;
    }
    e = krb5_sockaddr2address(contextp, sa, &addr);
    if(e)
	krb5_warn(contextp, e, "krb5_sockaddr2address");
    else {
	e = krb5_print_address (&addr, buf, sizeof(buf),
				&buf_len);
	if(e)
	    krb5_warn(contextp, e, "krb5_print_address");
	else
	    krb5_warnx(contextp, "connection from %s", buf);
	krb5_free_address(contextp, &addr);
    }

    pid = fork();
    if(pid == 0) {
	for(i = 0; i < num_socks; i++)
	    rk_closesocket(socks[i]);
	dup2(s, STDIN_FILENO);
	dup2(s, STDOUT_FILENO);
	if(s != STDIN_FILENO && s != STDOUT_FILENO)
	    rk_closesocket(s);
	return 0;
    } else {
	rk_closesocket(s);
    }
    return 1;
}
Ejemplo n.º 18
0
static krb5_error_code
add_addrs(krb5_context context,
	  krb5_addresses *addr,
	  struct addrinfo *ai)
{
    krb5_error_code ret;
    unsigned n, i;
    void *tmp;
    struct addrinfo *a;

    n = 0;
    for (a = ai; a != NULL; a = a->ai_next)
	++n;

    tmp = realloc(addr->val, (addr->len + n) * sizeof(*addr->val));
    if (tmp == NULL) {
	krb5_set_error_string(context, "malloc: out of memory");
	ret = ENOMEM;
	goto fail;
    }
    addr->val = tmp;
    for (i = addr->len; i < (addr->len + n); ++i) {
	addr->val[i].addr_type = 0;
	krb5_data_zero(&addr->val[i].address);
    }
    i = addr->len;
    for (a = ai; a != NULL; a = a->ai_next) {
	krb5_address ad;

	ret = krb5_sockaddr2address (context, a->ai_addr, &ad);
	if (ret == 0) {
	    if (krb5_address_search(context, &ad, addr))
		krb5_free_address(context, &ad);
	    else
		addr->val[i++] = ad;
	}
	else if (ret == KRB5_PROG_ATYPE_NOSUPP)
	    krb5_clear_error_string (context);
	else
	    goto fail;
	addr->len = i;
    }
    return 0;
fail:
    krb5_free_addresses (context, addr);
    return ret;
}
Ejemplo n.º 19
0
krb5_boolean
_kdc_check_addresses(krb5_context context,
		     krb5_kdc_configuration *config,
		     HostAddresses *addresses, const struct sockaddr *from)
{
    krb5_error_code ret;
    krb5_address addr;
    krb5_boolean result;
    krb5_boolean only_netbios = TRUE;
    size_t i;

    if(config->check_ticket_addresses == 0)
	return TRUE;

    if(addresses == NULL)
	return config->allow_null_ticket_addresses;

    for (i = 0; i < addresses->len; ++i) {
	if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
	    only_netbios = FALSE;
	}
    }

    /* Windows sends it's netbios name, which I can only assume is
     * used for the 'allowed workstations' check.  This is painful,
     * but we still want to check IP addresses if they happen to be
     * present.
     */

    if(only_netbios)
	return config->allow_null_ticket_addresses;

    ret = krb5_sockaddr2address (context, from, &addr);
    if(ret)
	return FALSE;

    result = krb5_address_search(context, &addr, addresses);
    krb5_free_address (context, &addr);
    return result;
}
Ejemplo n.º 20
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_rd_cred(krb5_context context,
	     krb5_auth_context auth_context,
	     krb5_data *in_data,
	     krb5_creds ***ret_creds,
	     krb5_replay_data *outdata)
{
    krb5_error_code ret;
    size_t len;
    KRB_CRED cred;
    EncKrbCredPart enc_krb_cred_part;
    krb5_data enc_krb_cred_part_data;
    krb5_crypto crypto;
    int i;

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

    if ((auth_context->flags &
	 (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)) &&
	outdata == NULL)
	return KRB5_RC_REQUIRED; /* XXX better error, MIT returns this */

    *ret_creds = NULL;

    ret = decode_KRB_CRED(in_data->data, in_data->length,
			  &cred, &len);
    if(ret) {
	krb5_clear_error_message(context);
	return ret;
    }

    if (cred.pvno != 5) {
	ret = KRB5KRB_AP_ERR_BADVERSION;
	krb5_clear_error_message (context);
	goto out;
    }

    if (cred.msg_type != krb_cred) {
	ret = KRB5KRB_AP_ERR_MSG_TYPE;
	krb5_clear_error_message (context);
	goto out;
    }

    if (cred.enc_part.etype == ETYPE_NULL) {
	/* DK: MIT GSS-API Compatibility */
	enc_krb_cred_part_data.length = cred.enc_part.cipher.length;
	enc_krb_cred_part_data.data   = cred.enc_part.cipher.data;
    } else {
	/* Try both subkey and session key.
	 *
	 * RFC4120 claims we should use the session key, but Heimdal
	 * before 0.8 used the remote subkey if it was send in the
	 * auth_context.
	 */

	if (auth_context->remote_subkey) {
	    ret = krb5_crypto_init(context, auth_context->remote_subkey,
				   0, &crypto);
	    if (ret)
		goto out;

	    ret = krb5_decrypt_EncryptedData(context,
					     crypto,
					     KRB5_KU_KRB_CRED,
					     &cred.enc_part,
					     &enc_krb_cred_part_data);
	
	    krb5_crypto_destroy(context, crypto);
	}

	/*
	 * If there was not subkey, or we failed using subkey,
	 * retry using the session key
	 */
	if (auth_context->remote_subkey == NULL || ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	{

	    ret = krb5_crypto_init(context, auth_context->keyblock,
				   0, &crypto);

	    if (ret)
		goto out;
	
	    ret = krb5_decrypt_EncryptedData(context,
					     crypto,
					     KRB5_KU_KRB_CRED,
					     &cred.enc_part,
					     &enc_krb_cred_part_data);
	
	    krb5_crypto_destroy(context, crypto);
	}
	if (ret)
	    goto out;
    }

    ret = decode_EncKrbCredPart(enc_krb_cred_part_data.data,
				enc_krb_cred_part_data.length,
				&enc_krb_cred_part,
				&len);
    if (enc_krb_cred_part_data.data != cred.enc_part.cipher.data)
	krb5_data_free(&enc_krb_cred_part_data);
    if (ret) {
	krb5_set_error_message(context, ret,
			       N_("Failed to decode "
				  "encrypte credential part", ""));
	goto out;
    }

    /* check sender address */

    if (enc_krb_cred_part.s_address
	&& auth_context->remote_address
	&& auth_context->remote_port) {
	krb5_address *a;

	ret = krb5_make_addrport (context, &a,
				  auth_context->remote_address,
				  auth_context->remote_port);
	if (ret)
	    goto out;


	ret = compare_addrs(context, a, enc_krb_cred_part.s_address,
			    N_("sender address is wrong "
			       "in received creds", ""));
	krb5_free_address(context, a);
	free(a);
	if(ret)
	    goto out;
    }

    /* check receiver address */

    if (enc_krb_cred_part.r_address
	&& auth_context->local_address) {
	if(auth_context->local_port &&
	   enc_krb_cred_part.r_address->addr_type == KRB5_ADDRESS_ADDRPORT) {
	    krb5_address *a;
	    ret = krb5_make_addrport (context, &a,
				      auth_context->local_address,
				      auth_context->local_port);
	    if (ret)
		goto out;
	
	    ret = compare_addrs(context, a, enc_krb_cred_part.r_address,
				N_("receiver address is wrong "
				   "in received creds", ""));
	    krb5_free_address(context, a);
	    free(a);
	    if(ret)
		goto out;
	} else {
	    ret = compare_addrs(context, auth_context->local_address,
				enc_krb_cred_part.r_address,
				N_("receiver address is wrong "
				   "in received creds", ""));
	    if(ret)
		goto out;
	}
    }

    /* check timestamp */
    if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) {
	krb5_timestamp sec;

	krb5_timeofday (context, &sec);

	if (enc_krb_cred_part.timestamp == NULL ||
	    enc_krb_cred_part.usec      == NULL ||
	    abs(*enc_krb_cred_part.timestamp - sec)
	    > context->max_skew) {
	    krb5_clear_error_message (context);
	    ret = KRB5KRB_AP_ERR_SKEW;
	    goto out;
	}
    }

    if ((auth_context->flags &
	 (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE))) {
	/* if these fields are not present in the cred-part, silently
           return zero */
	memset(outdata, 0, sizeof(*outdata));
	if(enc_krb_cred_part.timestamp)
	    outdata->timestamp = *enc_krb_cred_part.timestamp;
	if(enc_krb_cred_part.usec)
	    outdata->usec = *enc_krb_cred_part.usec;
	if(enc_krb_cred_part.nonce)
	    outdata->seq = *enc_krb_cred_part.nonce;
    }

    /* Convert to NULL terminated list of creds */

    *ret_creds = calloc(enc_krb_cred_part.ticket_info.len + 1,
			sizeof(**ret_creds));

    if (*ret_creds == NULL) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret,
			       N_("malloc: out of memory", ""));
	goto out;
    }

    for (i = 0; i < enc_krb_cred_part.ticket_info.len; ++i) {
	KrbCredInfo *kci = &enc_krb_cred_part.ticket_info.val[i];
	krb5_creds *creds;

	creds = calloc(1, sizeof(*creds));
	if(creds == NULL) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret,
				   N_("malloc: out of memory", ""));
	    goto out;
	}

	ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length,
			   &cred.tickets.val[i], &len, ret);
	if (ret) {
	    free(creds);
	    goto out;
	}
	if(creds->ticket.length != len)
	    krb5_abortx(context, "internal error in ASN.1 encoder");
	copy_EncryptionKey (&kci->key, &creds->session);
	if (kci->prealm && kci->pname)
	    _krb5_principalname2krb5_principal (context,
						&creds->client,
						*kci->pname,
						*kci->prealm);
	if (kci->flags)
	    creds->flags.b = *kci->flags;
	if (kci->authtime)
	    creds->times.authtime = *kci->authtime;
	if (kci->starttime)
	    creds->times.starttime = *kci->starttime;
	if (kci->endtime)
	    creds->times.endtime = *kci->endtime;
	if (kci->renew_till)
	    creds->times.renew_till = *kci->renew_till;
	if (kci->srealm && kci->sname)
	    _krb5_principalname2krb5_principal (context,
						&creds->server,
						*kci->sname,
						*kci->srealm);
	if (kci->caddr)
	    krb5_copy_addresses (context,
				 kci->caddr,
				 &creds->addresses);
	
	(*ret_creds)[i] = creds;
	
    }
    (*ret_creds)[i] = NULL;

    free_KRB_CRED (&cred);
    free_EncKrbCredPart(&enc_krb_cred_part);

    return 0;

  out:
    free_EncKrbCredPart(&enc_krb_cred_part);
    free_KRB_CRED (&cred);
    if(*ret_creds) {
	for(i = 0; (*ret_creds)[i]; i++)
	    krb5_free_creds(context, (*ret_creds)[i]);
	free(*ret_creds);
	*ret_creds = NULL;
    }
    return ret;
}
Ejemplo n.º 21
0
static void
write_stats(krb5_context context, slave *slaves, u_int32_t current_version)
{
    char str[100];
    rtbl_t tbl;
    time_t t = time(NULL);
    FILE *fp;

    fp = fopen(slave_stats_file, "w");
    if (fp == NULL)
	return;

    krb5_format_time(context, t, str, sizeof(str), TRUE); 
    fprintf(fp, "Status for slaves, last updated: %s\n\n", str);

    fprintf(fp, "Master version: %lu\n\n", (unsigned long)current_version);

    tbl = rtbl_create();
    if (tbl == NULL) {
	fclose(fp);
	return;
    }

    rtbl_add_column(tbl, SLAVE_NAME, 0);
    rtbl_add_column(tbl, SLAVE_ADDRESS, 0);
    rtbl_add_column(tbl, SLAVE_VERSION, RTBL_ALIGN_RIGHT);
    rtbl_add_column(tbl, SLAVE_STATUS, 0);
    rtbl_add_column(tbl, SLAVE_SEEN, 0);

    rtbl_set_prefix(tbl, "  ");
    rtbl_set_column_prefix(tbl, SLAVE_NAME, "");

    while (slaves) {
	krb5_address addr;
	krb5_error_code ret;
	rtbl_add_column_entry(tbl, SLAVE_NAME, slaves->name);
	ret = krb5_sockaddr2address (context, 
				     (struct sockaddr*)&slaves->addr, &addr);
	if(ret == 0) {
	    krb5_print_address(&addr, str, sizeof(str), NULL);
	    krb5_free_address(context, &addr);
	    rtbl_add_column_entry(tbl, SLAVE_ADDRESS, str);
	} else
	    rtbl_add_column_entry(tbl, SLAVE_ADDRESS, "<unknown>");
	
	snprintf(str, sizeof(str), "%u", (unsigned)slaves->version);
	rtbl_add_column_entry(tbl, SLAVE_VERSION, str);

	if (slaves->flags & SLAVE_F_DEAD)
	    rtbl_add_column_entry(tbl, SLAVE_STATUS, "Down");
	else
	    rtbl_add_column_entry(tbl, SLAVE_STATUS, "Up");

	ret = krb5_format_time(context, slaves->seen, str, sizeof(str), TRUE); 
	rtbl_add_column_entry(tbl, SLAVE_SEEN, str);

	slaves = slaves->next;
    }

    rtbl_format(tbl, fp);
    rtbl_destroy(tbl);

    fclose(fp);
}
Ejemplo n.º 22
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.º 23
0
static int
arange_parse_addr (krb5_context context,
		   const char *address, krb5_address *addr)
{
    char buf[1024], *p;
    krb5_address low0, high0;
    struct arange *a;
    krb5_error_code ret;

    if(strncasecmp(address, "RANGE:", 6) != 0)
	return -1;

    address += 6;

    p = strrchr(address, '/');
    if (p) {
	krb5_addresses addrmask;
	char *q;
	long num;

	if (strlcpy(buf, address, sizeof(buf)) > sizeof(buf))
	    return -1;
	buf[p - address] = '\0';
	ret = krb5_parse_address(context, buf, &addrmask);
	if (ret)
	    return ret;
	if(addrmask.len != 1) {
	    krb5_free_addresses(context, &addrmask);
	    return -1;
	}
	
	address += p - address + 1;

	num = strtol(address, &q, 10);
	if (q == address || *q != '\0' || num < 0) {
	    krb5_free_addresses(context, &addrmask);
	    return -1;
	}

	ret = krb5_address_prefixlen_boundary(context, &addrmask.val[0], num,
					      &low0, &high0);
	krb5_free_addresses(context, &addrmask);
	if (ret)
	    return ret;

    } else {
	krb5_addresses low, high;
	
	strsep_copy(&address, "-", buf, sizeof(buf));
	ret = krb5_parse_address(context, buf, &low);
	if(ret)
	    return ret;
	if(low.len != 1) {
	    krb5_free_addresses(context, &low);
	    return -1;
	}
	
	strsep_copy(&address, "-", buf, sizeof(buf));
	ret = krb5_parse_address(context, buf, &high);
	if(ret) {
	    krb5_free_addresses(context, &low);
	    return ret;
	}
	
	if(high.len != 1 && high.val[0].addr_type != low.val[0].addr_type) {
	    krb5_free_addresses(context, &low);
	    krb5_free_addresses(context, &high);
	    return -1;
	}

	ret = krb5_copy_address(context, &high.val[0], &high0);
	if (ret == 0) {
	    ret = krb5_copy_address(context, &low.val[0], &low0);
	    if (ret)
		krb5_free_address(context, &high0);
	}
	krb5_free_addresses(context, &low);
	krb5_free_addresses(context, &high);
	if (ret)
	    return ret;
    }

    krb5_data_alloc(&addr->address, sizeof(*a));
    addr->addr_type = KRB5_ADDRESS_ARANGE;
    a = addr->address.data;

    if(krb5_address_order(context, &low0, &high0) < 0) {
	a->low = low0;
	a->high = high0;
    } else {
	a->low = high0;
	a->high = low0;
    }
    return 0;
}
Ejemplo n.º 24
0
static krb5_error_code
find_all_addresses (krb5_context context, krb5_addresses *res, int flags)
{
    struct sockaddr sa_zero;
    struct ifaddrs *ifa0, *ifa;
    krb5_error_code ret = ENXIO;
    unsigned int num, idx;
    krb5_addresses ignore_addresses;

    if (getifaddrs(&ifa0) == -1) {
	ret = errno;
	krb5_set_error_message(context, ret, "getifaddrs: %s", strerror(ret));
	return (ret);
    }

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

    /* First, count all the ifaddrs. */
    for (ifa = ifa0, num = 0; ifa != NULL; ifa = ifa->ifa_next, num++)
	/* nothing */;

    if (num == 0) {
	freeifaddrs(ifa0);
	krb5_set_error_message(context, ENXIO, N_("no addresses found", ""));
	return (ENXIO);
    }

    if (flags & EXTRA_ADDRESSES) {
	/* we'll remove the addresses we don't care about */
	ret = krb5_get_ignore_addresses(context, &ignore_addresses);
	if(ret)
	    return ret;
    }

    /* Allocate storage for them. */
    res->val = calloc(num, sizeof(*res->val));
    if (res->val == NULL) {
	if (flags & EXTRA_ADDRESSES)
	    krb5_free_addresses(context, &ignore_addresses);
	freeifaddrs(ifa0);
	krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
	return ENOMEM;
    }

    /* Now traverse the list. */
    for (ifa = ifa0, idx = 0; ifa != NULL; ifa = ifa->ifa_next) {
	if ((ifa->ifa_flags & IFF_UP) == 0)
	    continue;
	if (ifa->ifa_addr == NULL)
	    continue;
	if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
	    continue;
	if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
	    continue;
	if (krb5_sockaddr_is_loopback(ifa->ifa_addr) && (flags & LOOP) == 0)
	    /* We'll deal with the LOOP_IF_NONE case later. */
	    continue;

	ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]);
	if (ret) {
	    /*
	     * The most likely error here is going to be "Program
	     * lacks support for address type".  This is no big
	     * deal -- just continue, and we'll listen on the
	     * addresses who's type we *do* support.
	     */
	    continue;
	}
	/* possibly skip this address? */
	if((flags & EXTRA_ADDRESSES) &&
	   krb5_address_search(context, &res->val[idx], &ignore_addresses)) {
	    krb5_free_address(context, &res->val[idx]);
	    flags &= ~LOOP_IF_NONE; /* we actually found an address,
                                       so don't add any loop-back
                                       addresses */
	    continue;
	}

	idx++;
    }

    /*
     * If no addresses were found, and LOOP_IF_NONE is set, then find
     * the loopback addresses and add them to our list.
     */
    if ((flags & LOOP_IF_NONE) != 0 && idx == 0) {
	for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) {
	    if ((ifa->ifa_flags & IFF_UP) == 0)
		continue;
	    if (ifa->ifa_addr == NULL)
		continue;
	    if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0)
		continue;
	    if (krb5_sockaddr_uninteresting(ifa->ifa_addr))
		continue;
	    if (!krb5_sockaddr_is_loopback(ifa->ifa_addr))
		continue;
	    if ((ifa->ifa_flags & IFF_LOOPBACK) == 0)
		/* Presumably loopback addrs are only used on loopback ifs! */
		continue;
	    ret = krb5_sockaddr2address(context,
					ifa->ifa_addr, &res->val[idx]);
	    if (ret)
		continue; /* We don't consider this failure fatal */
	    if((flags & EXTRA_ADDRESSES) &&
	       krb5_address_search(context, &res->val[idx],
				   &ignore_addresses)) {
		krb5_free_address(context, &res->val[idx]);
		continue;
	    }
	    idx++;
	}
    }

    if (flags & EXTRA_ADDRESSES)
	krb5_free_addresses(context, &ignore_addresses);
    freeifaddrs(ifa0);
    if (ret) {
	free(res->val);
	res->val = NULL;
    } else
	res->len = idx;        /* Now a count. */
    return (ret);
}
Ejemplo n.º 25
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;
}
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_import_sec_context (
    OM_uint32 * minor_status,
    const gss_buffer_t interprocess_token,
    gss_ctx_id_t * context_handle
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_context context;
    krb5_error_code kret;
    krb5_storage *sp;
    krb5_auth_context ac;
    krb5_address local, remote;
    krb5_address *localp, *remotep;
    krb5_data data;
    gss_buffer_desc buffer;
    krb5_keyblock keyblock;
    int32_t flags, tmp;
    gsskrb5_ctx ctx;
    gss_name_t name;

    GSSAPI_KRB5_INIT (&context);

    *context_handle = GSS_C_NO_CONTEXT;

    localp = remotep = NULL;

    sp = krb5_storage_from_mem (interprocess_token->value,
				interprocess_token->length);
    if (sp == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    ctx = calloc(1, sizeof(*ctx));
    if (ctx == NULL) {
	*minor_status = ENOMEM;
	krb5_storage_free (sp);
	return GSS_S_FAILURE;
    }
    HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);

    kret = krb5_auth_con_init (context,
			       &ctx->auth_context);
    if (kret) {
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    /* flags */

    *minor_status = 0;

    if (krb5_ret_int32 (sp, &flags) != 0)
	goto failure;

    /* retrieve the auth context */

    ac = ctx->auth_context;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->flags = tmp;
    if (flags & SC_LOCAL_ADDRESS) {
	if (krb5_ret_address (sp, localp = &local) != 0)
	    goto failure;
    }

    if (flags & SC_REMOTE_ADDRESS) {
	if (krb5_ret_address (sp, remotep = &remote) != 0)
	    goto failure;
    }

    krb5_auth_con_setaddrs (context, ac, localp, remotep);
    if (localp)
	krb5_free_address (context, localp);
    if (remotep)
	krb5_free_address (context, remotep);
    localp = remotep = NULL;

    if (krb5_ret_int16 (sp, &ac->local_port) != 0)
	goto failure;

    if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
	goto failure;
    if (flags & SC_KEYBLOCK) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (flags & SC_LOCAL_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (flags & SC_REMOTE_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setremotesubkey (context, ac, &keyblock);
	krb5_free_keyblock_contents (context, &keyblock);
    }
    if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
	goto failure;
    if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
	goto failure;

    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->keytype = tmp;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->cksumtype = tmp;

    /* names */

    if (krb5_ret_data (sp, &data))
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
				&name);
    if (ret) {
	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
				    &name);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    ctx->source = (krb5_principal)name;
    krb5_data_free (&data);

    if (krb5_ret_data (sp, &data) != 0)
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
				&name);
    if (ret) {
	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
				    &name);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    ctx->target = (krb5_principal)name;
    krb5_data_free (&data);

    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->more_flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    ctx->endtime = tmp;

    ret = _gssapi_msg_order_import(minor_status, sp, &ctx->gk5c.order);
    if (ret)
        goto failure;

    krb5_storage_free (sp);

    _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);

    *context_handle = (gss_ctx_id_t)ctx;

    return GSS_S_COMPLETE;

failure:
    krb5_auth_con_free (context,
			ctx->auth_context);
    if (ctx->source != NULL)
	krb5_free_principal(context, ctx->source);
    if (ctx->target != NULL)
	krb5_free_principal(context, ctx->target);
    if (localp)
	krb5_free_address (context, localp);
    if (remotep)
	krb5_free_address (context, remotep);
    if(ctx->gk5c.order)
	_gssapi_msg_order_destroy(&ctx->gk5c.order);
    HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
    krb5_storage_free (sp);
    free (ctx);
    *context_handle = GSS_C_NO_CONTEXT;
    return ret;
}
Ejemplo n.º 27
0
static void
process (krb5_realm *realms,
         krb5_keytab keytab,
         int s,
         krb5_address *this_addr,
         struct sockaddr *sa,
         int sa_size,
         u_char *msg,
         int len)
{
    krb5_error_code ret;
    krb5_auth_context auth_context = NULL;
    krb5_data out_data;
    krb5_ticket *ticket;
    krb5_address other_addr;
    uint16_t version;

    memset(&other_addr, 0, sizeof(other_addr));
    krb5_data_zero (&out_data);

    ret = krb5_auth_con_init (context, &auth_context);
    if (ret) {
        krb5_warn (context, ret, "krb5_auth_con_init");
        return;
    }

    krb5_auth_con_setflags (context, auth_context,
                            KRB5_AUTH_CONTEXT_DO_SEQUENCE);

    ret = krb5_sockaddr2address (context, sa, &other_addr);
    if (ret) {
        krb5_warn (context, ret, "krb5_sockaddr2address");
        goto out;
    }

    ret = krb5_auth_con_setaddrs (context, auth_context, this_addr, NULL);
    if (ret) {
        krb5_warn (context, ret, "krb5_auth_con_setaddr(this)");
        goto out;
    }

    if (verify (&auth_context, realms, keytab, &ticket, &out_data,
                &version, s, sa, sa_size, msg, len, &other_addr) == 0)
    {
        /*
         * We always set the client_addr, to assume that the client
         * can ignore it if it choose to do so (just the server does
         * so for addressless tickets).
         */
        ret = krb5_auth_con_setaddrs (context, auth_context,
                                      this_addr, &other_addr);
        if (ret) {
            krb5_warn (context, ret, "krb5_auth_con_setaddr(other)");
            goto out;
        }

        change (auth_context,
                ticket->client,
                version,
                s,
                sa, sa_size,
                &out_data);
        memset (out_data.data, 0, out_data.length);
        krb5_free_ticket (context, ticket);
    }

out:
    krb5_free_address(context, &other_addr);
    krb5_data_free(&out_data);
    krb5_auth_con_free(context, auth_context);
}
Ejemplo n.º 28
0
static int
doit (krb5_keytab keytab, int port)
{
    krb5_error_code ret;
    int *sockets;
    int maxfd;
    krb5_realm *realms;
    krb5_addresses addrs;
    krb5_address *my_addrp;
    unsigned n, i;
    fd_set real_fdset;
    struct sockaddr_storage __ss;
    struct sockaddr *sa = (struct sockaddr *)&__ss;
#ifdef INETD_SUPPORT
    int fdz;
    int from_inetd;
    socklen_t fromlen;
    krb5_address my_addr;
    struct sockaddr_storage __local;
    struct sockaddr *localsa = (struct sockaddr *)&__local;
#endif

    ret = krb5_get_default_realms(context, &realms);
    if (ret)
        krb5_err (context, 1, ret, "krb5_get_default_realms");

#ifdef INETD_SUPPORT
    fromlen = sizeof __ss;
    from_inetd = (getsockname(0, sa, &fromlen) == 0);

    if (!from_inetd) {
#endif
        if (explicit_addresses.len) {
            addrs = explicit_addresses;
        } else {
            ret = krb5_get_all_server_addrs (context, &addrs);
            if (ret)
                krb5_err (context, 1, ret, "krb5_get_all_server_addrs");
        }
        n = addrs.len;

        sockets = malloc (n * sizeof(*sockets));
        if (sockets == NULL)
            krb5_errx (context, 1, "out of memory");
        maxfd = -1;
        FD_ZERO(&real_fdset);
        for (i = 0; i < n; ++i) {
            krb5_socklen_t sa_size = sizeof(__ss);

            krb5_addr2sockaddr (context, &addrs.val[i], sa, &sa_size, port);

            sockets[i] = socket (sa->sa_family, SOCK_DGRAM, 0);
            if (sockets[i] < 0)
                krb5_err (context, 1, errno, "socket");
            if (bind (sockets[i], sa, sa_size) < 0) {
                char str[128];
                size_t len;
                int save_errno = errno;

                ret = krb5_print_address (&addrs.val[i], str, sizeof(str), &len);
                if (ret)
                    strlcpy(str, "unknown address", sizeof(str));
                krb5_warn (context, save_errno, "bind(%s)", str);
                continue;
            }
            maxfd = max (maxfd, sockets[i]);
            if (maxfd >= FD_SETSIZE)
                krb5_errx (context, 1, "fd too large");
            FD_SET(sockets[i], &real_fdset);
        }
#ifdef INETD_SUPPORT
    } else {
        n = 1;
        maxfd = 0;
        fdz = 0;
        sockets = &fdz;
        FD_ZERO(&real_fdset);
        FD_SET(0, &real_fdset);
    }
#endif
    if (maxfd == -1)
        krb5_errx (context, 1, "No sockets!");

    while(exit_flag == 0) {
        krb5_ssize_t retx;
        fd_set fdset = real_fdset;

        retx = select (maxfd + 1, &fdset, NULL, NULL, NULL);
        if (retx < 0) {
            if (errno == EINTR)
                continue;
            else
                krb5_err (context, 1, errno, "select");
        }
        for (i = 0; i < n; ++i)
            if (FD_ISSET(sockets[i], &fdset)) {
                u_char buf[BUFSIZ];
                socklen_t addrlen = sizeof(__ss);

                retx = recvfrom(sockets[i], buf, sizeof(buf), 0,
                                sa, &addrlen);
                if (retx < 0) {
                    if(errno == EINTR)
                        break;
                    else
                        krb5_err (context, 1, errno, "recvfrom");
                }
#ifdef INETD_SUPPORT
                if (from_inetd) {
                    socklen_t loclen = sizeof(__local);
                    int ret2;

                    ret2 = get_local_addr(sa, addrlen, localsa, &loclen);
                    if (ret2 < 0)
                        krb5_errx (context, errno, "get_local_addr");
                    ret2 = krb5_sockaddr2address(context, localsa,
                                                 &my_addr);
                    if (ret2)
                        krb5_errx (context, ret2,
                                   "krb5_sockaddr2address");
                    my_addrp = &my_addr;
                } else
#endif
                    my_addrp = &addrs.val[i];

                process (realms, keytab, sockets[i],
                         my_addrp,
                         sa, addrlen,
                         buf, retx);
#ifdef INETD_SUPPORT
                if (from_inetd) {
                    krb5_free_address(context, &my_addr);
                }
#endif
            }
#ifdef INETD_SUPPORT
        if (from_inetd)
            break;
#endif
    }

    for (i = 0; i < n; ++i)
        close(sockets[i]);
    free(sockets);

#ifdef INETD_SUPPORT
    if (!from_inetd)
#endif
        krb5_free_addresses (context, &addrs);
    krb5_free_host_realm (context, realms);
    krb5_free_context (context);
    return 0;
}
Ejemplo n.º 29
0
OM_uint32
gss_import_sec_context (
    OM_uint32 * minor_status,
    const gss_buffer_t interprocess_token,
    gss_ctx_id_t * context_handle
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_error_code kret;
    krb5_storage *sp;
    krb5_auth_context ac;
    krb5_address local, remote;
    krb5_address *localp, *remotep;
    krb5_data data;
    gss_buffer_desc buffer;
    krb5_keyblock keyblock;
    int32_t tmp;
    int32_t flags;
    OM_uint32 minor;
    int is_cfx = 0;

    GSSAPI_KRB5_INIT ();

    localp = remotep = NULL;

    sp = krb5_storage_from_mem (interprocess_token->value,
				interprocess_token->length);
    if (sp == NULL) {
	*minor_status = ENOMEM;
	return GSS_S_FAILURE;
    }

    *context_handle = malloc(sizeof(**context_handle));
    if (*context_handle == NULL) {
	*minor_status = ENOMEM;
	krb5_storage_free (sp);
	return GSS_S_FAILURE;
    }
    memset (*context_handle, 0, sizeof(**context_handle));
    HEIMDAL_MUTEX_init(&(*context_handle)->ctx_id_mutex);

    kret = krb5_auth_con_init (gssapi_krb5_context,
			       &(*context_handle)->auth_context);
    if (kret) {
	gssapi_krb5_set_error_string ();
	*minor_status = kret;
	ret = GSS_S_FAILURE;
	goto failure;
    }

    /* flags */

    *minor_status = 0;

    if (krb5_ret_int32 (sp, &flags) != 0)
	goto failure;

    /* retrieve the auth context */

    ac = (*context_handle)->auth_context;
    krb5_ret_int32 (sp, &ac->flags);
    if (flags & SC_LOCAL_ADDRESS) {
	if (krb5_ret_address (sp, localp = &local) != 0)
	    goto failure;
    }

    if (flags & SC_REMOTE_ADDRESS) {
	if (krb5_ret_address (sp, remotep = &remote) != 0)
	    goto failure;
    }

    krb5_auth_con_setaddrs (gssapi_krb5_context, ac, localp, remotep);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    localp = remotep = NULL;

    if (krb5_ret_int16 (sp, &ac->local_port) != 0)
	goto failure;

    if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
	goto failure;
    if (flags & SC_KEYBLOCK) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_LOCAL_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setlocalsubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (flags & SC_REMOTE_SUBKEY) {
	if (krb5_ret_keyblock (sp, &keyblock) != 0)
	    goto failure;
	krb5_auth_con_setremotesubkey (gssapi_krb5_context, ac, &keyblock);
	krb5_free_keyblock_contents (gssapi_krb5_context, &keyblock);
    }
    if (krb5_ret_int32 (sp, &ac->local_seqnumber))
	goto failure;
    if (krb5_ret_int32 (sp, &ac->remote_seqnumber))
	goto failure;

    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->keytype = tmp;
    if (krb5_ret_int32 (sp, &tmp) != 0)
	goto failure;
    ac->cksumtype = tmp;

    /* names */

    if (krb5_ret_data (sp, &data))
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->source);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->source);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }
    krb5_data_free (&data);

    if (krb5_ret_data (sp, &data) != 0)
	goto failure;
    buffer.value  = data.data;
    buffer.length = data.length;

    ret = gss_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
			   &(*context_handle)->target);
    if (ret) {
	ret = gss_import_name (minor_status, &buffer, GSS_C_NO_OID,
			       &(*context_handle)->target);
	if (ret) {
	    krb5_data_free (&data);
	    goto failure;
	}
    }    
    krb5_data_free (&data);

    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->flags = tmp;
    if (krb5_ret_int32 (sp, &tmp))
	goto failure;
    (*context_handle)->more_flags = tmp;
    if (krb5_ret_int32 (sp, &tmp) == 0)
	(*context_handle)->lifetime = tmp;
    else
	(*context_handle)->lifetime = GSS_C_INDEFINITE;

    gsskrb5_is_cfx(*context_handle, &is_cfx);

    ret = _gssapi_msg_order_create(minor_status,
				   &(*context_handle)->order,
				   _gssapi_msg_order_f((*context_handle)->flags),
				   0, 0, is_cfx);
    if (ret)
	goto failure;

    krb5_storage_free (sp);
    return GSS_S_COMPLETE;

failure:
    krb5_auth_con_free (gssapi_krb5_context,
			(*context_handle)->auth_context);
    if ((*context_handle)->source != NULL)
	gss_release_name(&minor, &(*context_handle)->source);
    if ((*context_handle)->target != NULL)
	gss_release_name(&minor, &(*context_handle)->target);
    if (localp)
	krb5_free_address (gssapi_krb5_context, localp);
    if (remotep)
	krb5_free_address (gssapi_krb5_context, remotep);
    if((*context_handle)->order)
	_gssapi_msg_order_destroy(&(*context_handle)->order);
    HEIMDAL_MUTEX_destroy(&(*context_handle)->ctx_id_mutex);
    krb5_storage_free (sp);
    free (*context_handle);
    *context_handle = GSS_C_NO_CONTEXT;
    return ret;
}
Ejemplo n.º 30
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_parse_address(krb5_context context,
		   const char *string,
		   krb5_addresses *addresses)
{
    int i, n;
    struct addrinfo *ai, *a;
    int error;
    int save_errno;

    addresses->len = 0;
    addresses->val = NULL;

    for(i = 0; i < num_addrs; i++) {
	if(at[i].parse_addr) {
	    krb5_address addr;
	    if((*at[i].parse_addr)(context, string, &addr) == 0) {
		ALLOC_SEQ(addresses, 1);
		if (addresses->val == NULL) {
		    krb5_set_error_message(context, ENOMEM,
					   N_("malloc: out of memory", ""));
		    return ENOMEM;
		}
		addresses->val[0] = addr;
		return 0;
	    }
	}
    }

    error = getaddrinfo (string, NULL, NULL, &ai);
    if (error) {
	krb5_error_code ret2;
	save_errno = errno;
	ret2 = krb5_eai_to_heim_errno(error, save_errno);
	krb5_set_error_message (context, ret2, "%s: %s",
				string, gai_strerror(error));
	return ret2;
    }

    n = 0;
    for (a = ai; a != NULL; a = a->ai_next)
	++n;

    ALLOC_SEQ(addresses, n);
    if (addresses->val == NULL) {
	krb5_set_error_message(context, ENOMEM,
			       N_("malloc: out of memory", ""));
	freeaddrinfo(ai);
	return ENOMEM;
    }

    addresses->len = 0;
    for (a = ai, i = 0; a != NULL; a = a->ai_next) {
	if (krb5_sockaddr2address (context, ai->ai_addr, &addresses->val[i]))
	    continue;
	if(krb5_address_search(context, &addresses->val[i], addresses)) {
	    krb5_free_address(context, &addresses->val[i]);
	    continue;
	}
	i++;
	addresses->len = i;
    }
    freeaddrinfo (ai);
    return 0;
}