diff options
author | Chris Provenzano <proven@mit.edu> | 1995-03-10 17:26:04 +0000 |
---|---|---|
committer | Chris Provenzano <proven@mit.edu> | 1995-03-10 17:26:04 +0000 |
commit | b2f49b74f53d6deafc39fc0069de3e249a383b13 (patch) | |
tree | 339c5c75b96c433c666183d92478c11ccc42d669 /src/lib/krb5/krb/rd_priv.c | |
parent | 84ea6e41500ad94dd417841b307d142d7055e056 (diff) | |
download | krb5-b2f49b74f53d6deafc39fc0069de3e249a383b13.tar.gz krb5-b2f49b74f53d6deafc39fc0069de3e249a383b13.tar.xz krb5-b2f49b74f53d6deafc39fc0069de3e249a383b13.zip |
* auth_con.h auth_con.c Added for krb5_auth_con definition and
support routines.
* mk_req.c (krb5_mk_req())
* mk_req_ext.c (krb5_mk_req_extended())
* rd_rep.c (krb5_rd_rep())
* sendauth.c (krb5_sendauth())
* mk_priv.c (krb5_mk_priv())
* mk_safe.c (krb5_mk_safe())
* rd_priv.c (krb5_rd_priv())
* rd_safe.c (krb5_rd_safe())
Added a krb5_auth_context argument and eliminated many of
the other arguments because they are included in the
krb5_auth_context structure.
* send_tgs.c (krb5_send_tgs()) Eliminate call to krb5_mk_req_extended(),
which does far more than krb5_send_tgs() needs.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5099 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5/krb/rd_priv.c')
-rw-r--r-- | src/lib/krb5/krb/rd_priv.c | 267 |
1 files changed, 143 insertions, 124 deletions
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c index f00440f9db..3aa6bd2659 100644 --- a/src/lib/krb5/krb/rd_priv.c +++ b/src/lib/krb5/krb/rd_priv.c @@ -25,6 +25,7 @@ */ #include "k5-int.h" +#include "auth_con.h" extern krb5_deltat krb5_clockskew; #define in_clock_skew(date) (labs((date)-currenttime) < krb5_clockskew) @@ -36,7 +37,7 @@ data in *outbuf. key specifies the key to be used for decryption of the message. -sender_addr and recv_addr specify the full +remote_addr and local_addr specify the full addresses (host and port) of the sender and receiver. outbuf points to allocated storage which the caller should @@ -50,75 +51,59 @@ Returns system errors, integrity errors. */ -krb5_error_code INTERFACE -krb5_rd_priv(context, inbuf, key, sender_addr, recv_addr, seq_number, - priv_flags, i_vector, rcache, outbuf) - krb5_context context; - const krb5_data * inbuf; - const krb5_keyblock * key; - const krb5_address * sender_addr; - const krb5_address * recv_addr; - krb5_int32 seq_number; - krb5_int32 priv_flags; - krb5_pointer i_vector; - krb5_rcache rcache; - krb5_data * outbuf; +static krb5_error_code +krb5_rd_priv_basic(context, inbuf, keyblock, local_addr, remote_addr, + i_vector, replaydata, outbuf) + krb5_context context; + const krb5_data * inbuf; + const krb5_keyblock * keyblock; + const krb5_address * local_addr; + const krb5_address * remote_addr; + krb5_pointer i_vector; + krb5_replay_data * replaydata; + krb5_data * outbuf; { - krb5_error_code retval; - krb5_encrypt_block eblock; - krb5_priv *privmsg; - krb5_priv_enc_part *privmsg_enc_part; - krb5_data scratch; - krb5_timestamp currenttime; + krb5_error_code retval; + krb5_priv * privmsg; + krb5_data scratch; + krb5_encrypt_block eblock; + krb5_priv_enc_part * privmsg_enc_part; if (!krb5_is_krb_priv(inbuf)) return KRB5KRB_AP_ERR_MSG_TYPE; + /* decode private message */ - if (retval = decode_krb5_priv(inbuf, &privmsg)) { + if (retval = decode_krb5_priv(inbuf, &privmsg)) return retval; - } -#define cleanup_privmsg() {(void)krb5_xfree(privmsg->enc_part.ciphertext.data); (void)krb5_xfree(privmsg);} if (!valid_etype(privmsg->enc_part.etype)) { - cleanup_privmsg(); - return KRB5_PROG_ETYPE_NOSUPP; + retval = KRB5_PROG_ETYPE_NOSUPP; + goto cleanup_privmsg; } /* put together an eblock for this decryption */ - krb5_use_cstype(context, &eblock, privmsg->enc_part.etype); scratch.length = privmsg->enc_part.ciphertext.length; if (!(scratch.data = malloc(scratch.length))) { - cleanup_privmsg(); - return ENOMEM; + retval = ENOMEM; + goto cleanup_privmsg; } -#define cleanup_scratch() {(void)memset(scratch.data, 0, scratch.length); (void)krb5_xfree(scratch.data);} - /* do any necessary key pre-processing */ - if (retval = krb5_process_key(context, &eblock, key)) { - cleanup_privmsg(); - cleanup_scratch(); - return retval; - } - -#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);} + if (retval = krb5_process_key(context, &eblock, keyblock)) + goto cleanup_scratch; /* call the decryption routine */ - if (retval = krb5_decrypt(context, (krb5_pointer) privmsg->enc_part.ciphertext.data, + if (retval = krb5_decrypt(context, + (krb5_pointer) privmsg->enc_part.ciphertext.data, (krb5_pointer) scratch.data, - scratch.length, &eblock, - i_vector)) { - cleanup_privmsg(); - cleanup_scratch(); - cleanup_prockey(); - return retval; + scratch.length, &eblock, i_vector)) { + krb5_finish_key(context, &eblock); + goto cleanup_scratch; } - /* if i_vector is set, fill it in with the last block of the encrypted - input */ - /* put last block into the i_vector */ + /* if i_vector is set, put last block into the i_vector */ if (i_vector) memcpy(i_vector, privmsg->enc_part.ciphertext.data + @@ -126,106 +111,140 @@ krb5_rd_priv(context, inbuf, key, sender_addr, recv_addr, seq_number, eblock.crypto_entry->block_length), eblock.crypto_entry->block_length); - /* private message is now decrypted -- do some cleanup */ - - cleanup_privmsg(); - - if (retval = krb5_finish_key(context, &eblock)) { - cleanup_scratch(); - return retval; - } + if (retval = krb5_finish_key(context, &eblock)) + goto cleanup_scratch; /* now decode the decrypted stuff */ - if (retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part)) { - cleanup_scratch(); - return retval; - } - cleanup_scratch(); + if (retval = decode_krb5_enc_priv_part(&scratch, &privmsg_enc_part)) + goto cleanup_scratch; -#define cleanup_data() {(void)memset(privmsg_enc_part->user_data.data,0,privmsg_enc_part->user_data.length); (void)krb5_xfree(privmsg_enc_part->user_data.data);} -#define cleanup_mesg() {(void)krb5_xfree(privmsg_enc_part);} - - if (!(priv_flags & KRB5_PRIV_NOTIME)) { - krb5_donot_replay replay; - - if (retval = krb5_timeofday(context, ¤ttime)) { - cleanup_data(); - cleanup_mesg(); - return retval; - } - if (!in_clock_skew(privmsg_enc_part->timestamp)) { - cleanup_data(); - cleanup_mesg(); - return KRB5KRB_AP_ERR_SKEW; - } - if (!rcache) { - /* gotta provide an rcache in this case... */ - cleanup_data(); - cleanup_mesg(); - return KRB5_RC_REQUIRED; - } - if (retval = krb5_gen_replay_name(context, sender_addr, "_priv", - &replay.client)) { - cleanup_data(); - cleanup_mesg(); - return retval; - } - replay.server = ""; /* XXX */ - replay.cusec = privmsg_enc_part->usec; - replay.ctime = privmsg_enc_part->timestamp; - if (retval = krb5_rc_store(context, rcache, &replay)) { - krb5_xfree(replay.client); - cleanup_data(); - cleanup_mesg(); - return retval; - } - krb5_xfree(replay.client); - } - - if (priv_flags & KRB5_PRIV_DOSEQUENCE) - if (privmsg_enc_part->seq_number != seq_number) { - cleanup_data(); - cleanup_mesg(); - return KRB5KRB_AP_ERR_BADORDER; - } - - if (!krb5_address_compare(context, sender_addr, privmsg_enc_part->s_address)) { - cleanup_data(); - cleanup_mesg(); - return KRB5KRB_AP_ERR_BADADDR; + if (!krb5_address_compare(context,remote_addr,privmsg_enc_part->s_address)){ + retval = KRB5KRB_AP_ERR_BADADDR; + goto cleanup_data; } if (privmsg_enc_part->r_address) { - if (recv_addr) { - if (!krb5_address_compare(context, recv_addr, + if (local_addr) { + if (!krb5_address_compare(context, local_addr, privmsg_enc_part->r_address)) { - cleanup_data(); - cleanup_mesg(); - return KRB5KRB_AP_ERR_BADADDR; + retval = KRB5KRB_AP_ERR_BADADDR; + goto cleanup_data; } } else { krb5_address **our_addrs; if (retval = krb5_os_localaddr(&our_addrs)) { - cleanup_data(); - cleanup_mesg(); - return retval; + goto cleanup_data; } if (!krb5_address_search(context, privmsg_enc_part->r_address, our_addrs)) { krb5_free_addresses(context, our_addrs); - cleanup_data(); - cleanup_mesg(); - return KRB5KRB_AP_ERR_BADADDR; + retval = KRB5KRB_AP_ERR_BADADDR; + goto cleanup_data; } krb5_free_addresses(context, our_addrs); } } - /* everything is ok - return data to the user */ + replaydata->timestamp = privmsg_enc_part->timestamp; + replaydata->usec = privmsg_enc_part->usec; + replaydata->seq = privmsg_enc_part->seq_number; + /* everything is ok - return data to the user */ *outbuf = privmsg_enc_part->user_data; - cleanup_mesg(); + retval = 0; + +cleanup_data:; + if (retval) { + memset(privmsg_enc_part->user_data.data, 0, + privmsg_enc_part->user_data.length); + krb5_xfree(privmsg_enc_part->user_data.data); + } + krb5_xfree(privmsg_enc_part); + +cleanup_scratch:; + memset(scratch.data, 0, scratch.length); + krb5_xfree(scratch.data); + +cleanup_privmsg:; + krb5_xfree(privmsg->enc_part.ciphertext.data); + krb5_xfree(privmsg); + + return retval; +} + +krb5_error_code INTERFACE +krb5_rd_priv(context, auth_context, inbuf, outbuf, outdata) + krb5_context context; + krb5_auth_context * auth_context; + const krb5_data * inbuf; + krb5_data * outbuf; + krb5_replay_data * outdata; +{ + krb5_error_code retval; + krb5_replay_data replaydata; + + if (((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) || + (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && + (outdata == NULL)) + /* Need a better error */ + return KRB5_RC_REQUIRED; + + if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) && + (auth_context->rcache == NULL)) + return KRB5_RC_REQUIRED; + + if (retval = krb5_rd_priv_basic(context, inbuf, auth_context->keyblock, + auth_context->local_addr, auth_context->remote_addr, + auth_context->i_vector, &replaydata, outbuf)) + return retval; + + if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) { + krb5_donot_replay replay; + krb5_timestamp currenttime; + + if (retval = krb5_timeofday(context, ¤ttime)) + goto error; + + if (!in_clock_skew(replaydata.timestamp)) { + retval = KRB5KRB_AP_ERR_SKEW; + goto error; + } + + if (retval = krb5_gen_replay_name(context, auth_context->remote_addr, + "_priv", &replay.client)) + goto error; + + replay.server = ""; /* XXX */ + replay.cusec = replaydata.usec; + replay.ctime = replaydata.timestamp; + if (retval = krb5_rc_store(context, auth_context->rcache, &replay)) { + krb5_xfree(replay.client); + goto error; + } + krb5_xfree(replay.client); + } + + if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { + if (auth_context->remote_seq_number != replaydata.seq) { + retval = KRB5KRB_AP_ERR_BADORDER; + goto error; + } + auth_context->remote_seq_number++; + } + + if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) || + (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) { + outdata->timestamp = replaydata.timestamp; + outdata->usec = replaydata.usec; + outdata->seq = replaydata.seq; + } + + /* everything is ok - return data to the user */ return 0; +error:; + krb5_xfree(outbuf->data); + return retval; + } |