#include "krb5_locl.h"
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_init(krb5_context context,
krb5_auth_context *auth_context)
{
krb5_auth_context p;
ALLOC(p, 1);
if(!p) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
return ENOMEM;
}
memset(p, 0, sizeof(*p));
ALLOC(p->authenticator, 1);
if (!p->authenticator) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
free(p);
return ENOMEM;
}
memset (p->authenticator, 0, sizeof(*p->authenticator));
p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
p->local_address = NULL;
p->remote_address = NULL;
p->local_port = 0;
p->remote_port = 0;
p->keytype = KRB5_ENCTYPE_NULL;
p->cksumtype = CKSUMTYPE_NONE;
p->auth_data = NULL;
p->pfs = NULL;
*auth_context = p;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_free(krb5_context context,
krb5_auth_context auth_context)
{
if (auth_context != NULL) {
krb5_free_authenticator(context, &auth_context->authenticator);
if(auth_context->local_address){
free_HostAddress(auth_context->local_address);
free(auth_context->local_address);
}
if(auth_context->remote_address){
free_HostAddress(auth_context->remote_address);
free(auth_context->remote_address);
}
krb5_free_keyblock(context, auth_context->keyblock);
krb5_free_keyblock(context, auth_context->remote_subkey);
krb5_free_keyblock(context, auth_context->local_subkey);
if (auth_context->auth_data) {
free_AuthorizationData(auth_context->auth_data);
free(auth_context->auth_data);
}
if (auth_context->pfs)
_krb5_auth_con_free_pfs(context, auth_context);
memset(auth_context, 0, sizeof(*auth_context));
free (auth_context);
}
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setflags(krb5_context context,
krb5_auth_context auth_context,
int32_t flags)
{
auth_context->flags = flags;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getflags(krb5_context context,
krb5_auth_context auth_context,
int32_t *flags)
{
*flags = auth_context->flags;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_addflags(krb5_context context,
krb5_auth_context auth_context,
int32_t addflags,
int32_t *flags)
{
if (flags)
*flags = auth_context->flags;
auth_context->flags |= addflags;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_removeflags(krb5_context context,
krb5_auth_context auth_context,
int32_t removeflags,
int32_t *flags)
{
if (flags)
*flags = auth_context->flags;
auth_context->flags &= ~removeflags;
return 0;
}
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_auth_con_clear(krb5_context context,
krb5_auth_context auth_context,
unsigned int flags)
{
if ((flags & KRB5_AUTH_CONTEXT_CLEAR_LOCAL_ADDR) && auth_context->local_address) {
krb5_free_address(context, auth_context->local_address);
free(auth_context->local_address);
auth_context->local_address = NULL;
}
if ((flags & KRB5_AUTH_CONTEXT_CLEAR_REMOTE_ADDR) && auth_context->remote_address) {
krb5_free_address(context, auth_context->remote_address);
free(auth_context->remote_address);
auth_context->remote_address = NULL;
}
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
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
if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL)
return ENOMEM;
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
if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL)
return ENOMEM;
krb5_copy_address(context, remote_addr, auth_context->remote_address);
}
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_genaddrs(krb5_context context,
krb5_auth_context auth_context,
krb5_socket_t 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(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) {
char buf[128];
ret = rk_SOCK_ERRNO;
rk_strerror_r(ret, buf, sizeof(buf));
krb5_set_error_message(context, ret, "getsockname: %s", buf);
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(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) {
char buf[128];
ret = rk_SOCK_ERRNO;
rk_strerror_r(ret, buf, sizeof(buf));
krb5_set_error_message(context, ret, "getpeername: %s", buf);
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;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setaddrs_from_fd (krb5_context context,
krb5_auth_context auth_context,
void *p_fd)
{
krb5_socket_t fd = *(krb5_socket_t *)p_fd;
int flags = 0;
if(auth_context->local_address == NULL)
flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
if(auth_context->remote_address == NULL)
flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
}
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;
}
static krb5_error_code
copy_key(krb5_context context,
krb5_keyblock *in,
krb5_keyblock **out)
{
if(in)
return krb5_copy_keyblock(context, in, out);
*out = NULL;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock **keyblock)
{
return copy_key(context, auth_context->keyblock, keyblock);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getlocalsubkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock **keyblock)
{
return copy_key(context, auth_context->local_subkey, keyblock);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getremotesubkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock **keyblock)
{
return copy_key(context, auth_context->remote_subkey, keyblock);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock *keyblock)
{
if(auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
return copy_key(context, keyblock, &auth_context->keyblock);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setlocalsubkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock *keyblock)
{
if(auth_context->local_subkey)
krb5_free_keyblock(context, auth_context->local_subkey);
return copy_key(context, keyblock, &auth_context->local_subkey);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_generatelocalsubkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock *key)
{
krb5_error_code ret;
krb5_keyblock *subkey;
ret = krb5_generate_subkey_extended (context, key,
(krb5_enctype)auth_context->keytype,
&subkey);
if(ret)
return ret;
if(auth_context->local_subkey)
krb5_free_keyblock(context, auth_context->local_subkey);
auth_context->local_subkey = subkey;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setremotesubkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock *keyblock)
{
if(auth_context->remote_subkey)
krb5_free_keyblock(context, auth_context->remote_subkey);
return copy_key(context, keyblock, &auth_context->remote_subkey);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setcksumtype(krb5_context context,
krb5_auth_context auth_context,
krb5_cksumtype cksumtype)
{
auth_context->cksumtype = cksumtype;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getcksumtype(krb5_context context,
krb5_auth_context auth_context,
krb5_cksumtype *cksumtype)
{
*cksumtype = auth_context->cksumtype;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setkeytype (krb5_context context,
krb5_auth_context auth_context,
krb5_keytype keytype)
{
auth_context->keytype = keytype;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getkeytype (krb5_context context,
krb5_auth_context auth_context,
krb5_keytype *keytype)
{
*keytype = auth_context->keytype;
return 0;
}
#if 0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setenctype(krb5_context context,
krb5_auth_context auth_context,
krb5_enctype etype)
{
if(auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
ALLOC(auth_context->keyblock, 1);
if(auth_context->keyblock == NULL)
return ENOMEM;
auth_context->keyblock->keytype = etype;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getenctype(krb5_context context,
krb5_auth_context auth_context,
krb5_enctype *etype)
{
krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
}
#endif
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getlocalseqnumber(krb5_context context,
krb5_auth_context auth_context,
int32_t *seqnumber)
{
*seqnumber = auth_context->local_seqnumber;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setlocalseqnumber (krb5_context context,
krb5_auth_context auth_context,
int32_t seqnumber)
{
auth_context->local_seqnumber = seqnumber;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getremoteseqnumber(krb5_context context,
krb5_auth_context auth_context,
int32_t *seqnumber)
{
*seqnumber = auth_context->remote_seqnumber;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setremoteseqnumber (krb5_context context,
krb5_auth_context auth_context,
int32_t seqnumber)
{
auth_context->remote_seqnumber = seqnumber;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getauthenticator(krb5_context context,
krb5_auth_context auth_context,
krb5_authenticator *authenticator)
{
*authenticator = malloc(sizeof(**authenticator));
if (*authenticator == NULL) {
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
return ENOMEM;
}
return copy_Authenticator(auth_context->authenticator,
*authenticator);
}
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
krb5_free_authenticator(krb5_context context,
krb5_authenticator *authenticator)
{
if (authenticator) {
free_Authenticator (*authenticator);
memset(*authenticator, 0, sizeof(**authenticator));
free (*authenticator);
*authenticator = NULL;
}
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setuserkey(krb5_context context,
krb5_auth_context auth_context,
krb5_keyblock *keyblock)
{
if(auth_context->keyblock)
krb5_free_keyblock(context, auth_context->keyblock);
return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_getrcache(krb5_context context,
krb5_auth_context auth_context,
krb5_rcache *rcache)
{
*rcache = auth_context->rcache;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setrcache(krb5_context context,
krb5_auth_context auth_context,
krb5_rcache rcache)
{
auth_context->rcache = rcache;
return 0;
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_add_AuthorizationData(krb5_context context,
krb5_auth_context auth_context,
int type,
krb5_data *data)
{
AuthorizationDataElement el;
if (auth_context->auth_data == NULL) {
auth_context->auth_data = calloc(1, sizeof(*auth_context->auth_data));
if (auth_context->auth_data == NULL)
return krb5_enomem(context);
}
el.ad_type = type;
el.ad_data.data = data->data;
el.ad_data.length = data->length;
return add_AuthorizationData(auth_context->auth_data, &el);
}
#if 0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_initivector(krb5_context context,
krb5_auth_context auth_context)
{
krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
}
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_auth_con_setivector(krb5_context context,
krb5_auth_context auth_context,
krb5_pointer ivector)
{
krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
}
#endif