diff options
Diffstat (limited to 'crypto/kerberosIV/lib/krb/sendauth.c')
-rw-r--r-- | crypto/kerberosIV/lib/krb/sendauth.c | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/crypto/kerberosIV/lib/krb/sendauth.c b/crypto/kerberosIV/lib/krb/sendauth.c new file mode 100644 index 000000000000..4240bcf98257 --- /dev/null +++ b/crypto/kerberosIV/lib/krb/sendauth.c @@ -0,0 +1,163 @@ +/* + Copyright (C) 1989 by the Massachusetts Institute of Technology + + Export of this software from the United States of America is assumed + to require a specific license from the United States Government. + It is the responsibility of any person or organization contemplating + export to obtain such a license before exporting. + +WITHIN THAT CONSTRAINT, permission to use, copy, modify, and +distribute this software and its documentation for any purpose and +without fee is hereby granted, provided that the above copyright +notice appear in all copies and that both that copyright notice and +this permission notice appear in supporting documentation, and that +the name of M.I.T. not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. M.I.T. makes no representations about the suitability of +this software for any purpose. It is provided "as is" without express +or implied warranty. + + */ + +#include "krb_locl.h" + +RCSID("$Id: sendauth.c,v 1.15 1997/04/18 14:11:36 joda Exp $"); + +/* + * krb_sendauth() transmits a ticket over a file descriptor for a + * desired service, instance, and realm, doing mutual authentication + * with the server if desired. + */ + +/* + * The first argument to krb_sendauth() contains a bitfield of + * options (the options are defined in "krb.h"): + * + * KOPT_DONT_CANON Don't canonicalize instance as a hostname. + * (If this option is not chosen, krb_get_phost() + * is called to canonicalize it.) + * + * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. + * A ticket must be supplied in the "ticket" + * argument. + * (If this option is not chosen, and there + * is no ticket for the given server in the + * ticket cache, one will be fetched using + * krb_mk_req() and returned in "ticket".) + * + * KOPT_DO_MUTUAL Do mutual authentication, requiring that the + * receiving server return the checksum+1 encrypted + * in the session key. The mutual authentication + * is done using krb_mk_priv() on the other side + * (see "recvauth.c") and krb_rd_priv() on this + * side. + * + * The "fd" argument is a file descriptor to write to the remote + * server on. The "ticket" argument is used to store the new ticket + * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is + * chosen, the ticket must be supplied in the "ticket" argument. + * The "service", "inst", and "realm" arguments identify the ticket. + * If "realm" is null, the local realm is used. + * + * The following arguments are only needed if the KOPT_DO_MUTUAL option + * is chosen: + * + * The "checksum" argument is a number that the server will add 1 to + * to authenticate itself back to the client; the "msg_data" argument + * holds the returned mutual-authentication message from the server + * (i.e., the checksum+1); the "cred" structure is used to hold the + * session key of the server, extracted from the ticket file, for use + * in decrypting the mutual authentication message from the server; + * and "schedule" holds the key schedule for that decryption. The + * the local and server addresses are given in "laddr" and "faddr". + * + * The application protocol version number (of up to KRB_SENDAUTH_VLEN + * characters) is passed in "version". + * + * If all goes well, KSUCCESS is returned, otherwise some error code. + * + * The format of the message sent to the server is: + * + * Size Variable Field + * ---- -------- ----- + * + * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol + * bytes version number + * + * KRB_SENDAUTH_VLEN version application protocol + * bytes version number + * + * 4 bytes ticket->length length of ticket + * + * ticket->length ticket->dat ticket itself + */ + +int +krb_sendauth(int32_t options, /* bit-pattern of options */ + int fd, /* file descriptor to write onto */ + KTEXT ticket, /* where to put ticket (return); or + * supplied in case of KOPT_DONT_MK_REQ */ + char *service, /* service name, instance, realm */ + char *instance, + char *realm, + u_int32_t checksum, /* checksum to include in request */ + MSG_DAT *msg_data, /* mutual auth MSG_DAT (return) */ + CREDENTIALS *cred, /* credentials (return) */ + struct des_ks_struct *schedule, /* key schedule (return) */ + struct sockaddr_in *laddr, /* local address */ + struct sockaddr_in *faddr, /* address of foreign host on fd */ + char *version) /* version string */ +{ + int ret; + KTEXT_ST buf; + char realrealm[REALM_SZ]; + + if (realm == NULL) { + ret = krb_get_lrealm (realrealm, 1); + if (ret != KSUCCESS) + return ret; + realm = realrealm; + } + ret = krb_mk_auth (options, ticket, service, instance, realm, checksum, + version, &buf); + if (ret != KSUCCESS) + return ret; + ret = krb_net_write(fd, buf.dat, buf.length); + if(ret < 0) + return -1; + + if (options & KOPT_DO_MUTUAL) { + char tmp[4]; + u_int32_t len; + char inst[INST_SZ]; + + ret = krb_net_read (fd, tmp, 4); + if (ret < 0) + return -1; + + krb_get_int (tmp, &len, 4, 0); + if (len == 0xFFFFFFFF || len > sizeof(buf.dat)) + return KFAILURE; + buf.length = len; + ret = krb_net_read (fd, buf.dat, len); + if (ret < 0) + return -1; + + if (options & KOPT_DONT_CANON) + strncpy (inst, instance, sizeof(inst)); + else + strncpy (inst, krb_get_phost(instance), sizeof(inst)); + + ret = krb_get_cred (service, inst, realm, cred); + if (ret != KSUCCESS) + return ret; + + des_key_sched(&cred->session, schedule); + + ret = krb_check_auth (&buf, checksum, msg_data, &cred->session, + schedule, laddr, faddr); + if (ret != KSUCCESS) + return ret; + } + return KSUCCESS; +} |