* auth_con.h auth_con.c Added for krb5_auth_con definition and
authorChris Provenzano <proven@mit.edu>
Fri, 10 Mar 1995 17:26:04 +0000 (17:26 +0000)
committerChris Provenzano <proven@mit.edu>
Fri, 10 Mar 1995 17:26:04 +0000 (17:26 +0000)
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

13 files changed:
src/lib/krb5/krb/ChangeLog
src/lib/krb5/krb/Makefile.in
src/lib/krb5/krb/auth_con.c [new file with mode: 0644]
src/lib/krb5/krb/auth_con.h [new file with mode: 0644]
src/lib/krb5/krb/mk_priv.c
src/lib/krb5/krb/mk_req.c
src/lib/krb5/krb/mk_req_ext.c
src/lib/krb5/krb/mk_safe.c
src/lib/krb5/krb/rd_priv.c
src/lib/krb5/krb/rd_rep.c
src/lib/krb5/krb/rd_safe.c
src/lib/krb5/krb/send_tgs.c
src/lib/krb5/krb/sendauth.c

index 2607654748d3f1a0188bee219f57d4936f45e174..6d3e670c54bebe2b58b5b2f02588414d8147d3b2 100644 (file)
@@ -1,3 +1,24 @@
+
+Fri Mar 10 10:58:59 1995  Chris Provenzano (proven@mit.edu)
+
+       * 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.
+
 Tue Mar  7 19:57:34 1995  Mark Eichin  <eichin@cygnus.com>
 
        * configure.in: take out ISODE_INCLUDE.
index c9556785d57d09dc8bf25b891db285226aa4e07a..429d2b9cda56561fd05c0407f3e47502d1d811e5 100644 (file)
@@ -8,6 +8,7 @@ LDFLAGS = -g
 OBJS=  addr_comp.$(OBJEXT)     \
        addr_order.$(OBJEXT)    \
        addr_srch.$(OBJEXT)     \
+       auth_con.$(OBJEXT)      \
        bld_pr_ext.$(OBJEXT)    \
        bld_princ.$(OBJEXT)     \
        chk_trans.$(OBJEXT)     \
@@ -73,6 +74,7 @@ OBJS= addr_comp.$(OBJEXT)     \
 SRCS=  $(srcdir)/addr_comp.c   \
        $(srcdir)/addr_order.c  \
        $(srcdir)/addr_srch.c   \
+       $(srcdir)/auth_con.c    \
        $(srcdir)/bld_pr_ext.c  \
        $(srcdir)/bld_princ.c   \
        $(srcdir)/chk_trans.c   \
diff --git a/src/lib/krb5/krb/auth_con.c b/src/lib/krb5/krb/auth_con.c
new file mode 100644 (file)
index 0000000..571e38c
--- /dev/null
@@ -0,0 +1,132 @@
+
+#include "k5-int.h"
+#include "auth_con.h"
+
+krb5_error_code INTERFACE
+krb5_auth_con_init(context, auth_context)
+    krb5_context         context;
+    krb5_auth_context  ** auth_context;
+{
+    if (*auth_context = (krb5_auth_context *)malloc(sizeof(krb5_auth_context))){
+       memset(*auth_context, 0, sizeof(krb5_auth_context));
+
+       /* Default flags, do time not seq */
+       (*auth_context)->auth_context_flags = 
+         KRB5_AUTH_CONTEXT_DO_TIME |  KRB5_AUTH_CONN_INITIALIZED;
+
+       (*auth_context)->cksumtype = CKSUMTYPE_CRC32;
+       return 0;
+    }
+    return ENOMEM;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_free(context, auth_context)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+{
+    if (auth_context->authentp) 
+       krb5_free_authenticator(context, auth_context->authentp);
+    if (auth_context->keyblock) 
+       krb5_free_keyblock(context, auth_context->keyblock);
+    if (auth_context->local_subkey) 
+       krb5_free_keyblock(context, auth_context->local_subkey);
+    if (auth_context->remote_subkey) 
+       krb5_free_keyblock(context, auth_context->remote_subkey);
+    free(auth_context);
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_setaddrs(context, auth_context, local_addr, remote_addr)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_address       * local_addr;
+    krb5_address       * remote_addr;
+{
+    auth_context->remote_addr = remote_addr;
+    auth_context->local_addr = local_addr;
+    return 0;
+}
+
+/* XXX this call is a hack. Fixed when I do the servers. */
+krb5_error_code INTERFACE
+krb5_auth_con_setkey(context, auth_context, keyblock)
+    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_error_code INTERFACE
+krb5_auth_con_getlocalsubkey(context, auth_context, keyblock)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_keyblock      ** keyblock;            
+{
+    return(krb5_copy_keyblock(context, auth_context->local_subkey, keyblock));
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_setcksumtype(context, auth_context, cksumtype)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_cksumtype       cksumtype;            
+{
+    auth_context->cksumtype = cksumtype;
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_getlocalseqnumber(context, auth_context, seqnumber)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_int32         * seqnumber;            
+{
+    *seqnumber = auth_context->local_seq_number;
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_setivector(context, auth_context, ivector)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_pointer         ivector;
+{
+    auth_context->i_vector = ivector;
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_getivector(context, auth_context, ivector)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_pointer       * ivector;
+{
+    *ivector = auth_context->i_vector;
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_setflags(context, auth_context, flags)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_int32           flags;
+{
+    auth_context->auth_context_flags = flags;
+    return 0;
+}
+
+krb5_error_code INTERFACE
+krb5_auth_con_setrcache(context, auth_context, rcache)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    krb5_rcache                  rcache;
+{
+    auth_context->rcache = rcache;
+    return 0;
+}
+
diff --git a/src/lib/krb5/krb/auth_con.h b/src/lib/krb5/krb/auth_con.h
new file mode 100644 (file)
index 0000000..0cf2ed7
--- /dev/null
@@ -0,0 +1,27 @@
+
+#ifndef KRB5_AUTH_CONTEXT
+#define KRB5_AUTH_CONTEXT
+
+struct _krb5_auth_context {
+    krb5_address      *        remote_addr;
+    krb5_address      *        local_addr;
+    krb5_keyblock     * keyblock;
+    krb5_keyblock     * local_subkey;
+    krb5_keyblock     * remote_subkey;
+
+    krb5_int32         auth_context_flags;
+    krb5_int32         remote_seq_number;
+    krb5_int32         local_seq_number;
+    krb5_authenticator *authentp;              /* mk_req, rd_rep */
+    krb5_cksumtype     cksumtype;              /* mk_safe, ... */
+    krb5_pointer       i_vector;               /* mk_priv only */
+    krb5_rcache                rcache;
+};
+
+
+/* Internal auth_context_flags */
+#define KRB5_AUTH_CONN_INITIALIZED     0x00010000
+#define KRB5_AUTH_CONN_USED_W_MK_REQ   0x00020000
+#define KRB5_AUTH_CONN_USED_W_RD_REQ   0x00040000
+
+#endif
index c09a467de3e93a191f91d9701b23f360bb71b853..37cf62f9150c515ee618621a91d4f95245ce83cb 100644 (file)
  */
 
 #include "k5-int.h"
-
-/*
- Formats a KRB_PRIV message into outbuf.
-
- userdata is formatted as the user data in the message.
- etype specifies the encryption type; key specifies the key for the
- encryption; sender_addr and recv_addr specify the full addresses (host
- and port) of the sender and receiver.
-
- i_vector is used as an initialization vector for the encryption, and if
- non-NULL its contents are replaced with the last block of the encrypted
- data upon exit.
-
- The outbuf buffer storage is allocated, and should be freed by the
- caller when finished.
-
- returns system errors
-*/
-krb5_error_code INTERFACE
-krb5_mk_priv(context, userdata, etype, key, sender_addr, recv_addr,
-            seq_number, priv_flags, rcache, i_vector, outbuf)
-    krb5_context context;
-    const krb5_data * userdata;
-    const krb5_enctype etype;
-    const krb5_keyblock * key;
-    const krb5_address * sender_addr;
-    const krb5_address * recv_addr;
-    krb5_int32 seq_number;
-    krb5_int32 priv_flags;
-    krb5_rcache rcache;
-    krb5_pointer i_vector;
-    krb5_data * outbuf;
+#include "auth_con.h"
+
+static krb5_error_code
+krb5_mk_priv_basic(context, userdata, keyblock, replaydata, local_addr, 
+                  remote_addr, i_vector, outbuf)
+    krb5_context         context;
+    const krb5_data    * userdata;
+    const krb5_keyblock * keyblock;
+    krb5_replay_data   * replaydata;
+    krb5_address       * local_addr;
+    krb5_address       * remote_addr;
+    krb5_pointer         i_vector;
+    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_error_code    retval;
+    krb5_encrypt_block         eblock;
+    krb5_priv          privmsg;
+    krb5_priv_enc_part         privmsg_enc_part;
+    krb5_data          *scratch1, *scratch2;
 
-    if (!valid_etype(etype))
+    if (!valid_etype(keyblock->etype))
        return KRB5_PROG_ETYPE_NOSUPP;
-    privmsg.enc_part.etype = etype; 
+
     privmsg.enc_part.kvno = 0; /* XXX allow user-set? */
+    privmsg.enc_part.etype = keyblock->etype; 
 
     privmsg_enc_part.user_data = *userdata;
-    privmsg_enc_part.s_address = (krb5_address *)sender_addr;
-    if (recv_addr)
-       privmsg_enc_part.r_address = (krb5_address *)recv_addr;
-    else
-       privmsg_enc_part.r_address = 0;
-
-    if (!(priv_flags & KRB5_PRIV_NOTIME)) {
-       if (!rcache)
-           /* gotta provide an rcache in this case... */
-           return KRB5_RC_REQUIRED;
-       if (retval = krb5_us_timeofday(context, &privmsg_enc_part.timestamp,
-                                      &privmsg_enc_part.usec))
-           return retval;
-    } else
-       privmsg_enc_part.timestamp = 0, privmsg_enc_part.usec = 0;
-    if (priv_flags & KRB5_PRIV_DOSEQUENCE) {
-       privmsg_enc_part.seq_number = seq_number;
-    } else
-       privmsg_enc_part.seq_number = 0;
+    privmsg_enc_part.s_address = local_addr;
+    privmsg_enc_part.r_address = remote_addr;
 
-    /* start by encoding to-be-encrypted part of the message */
+    /* We should check too make sure one exists. */
+    privmsg_enc_part.timestamp  = replaydata->timestamp;
+    privmsg_enc_part.usec      = replaydata->usec;
+    privmsg_enc_part.seq_number = replaydata->seq;
 
-    if (retval = encode_krb5_enc_priv_part(&privmsg_enc_part, &scratch))
+    /* start by encoding to-be-encrypted part of the message */
+    if (retval = encode_krb5_enc_priv_part(&privmsg_enc_part, &scratch1))
        return retval;
 
-#define cleanup_scratch() { (void) memset(scratch->data, 0, scratch->length); krb5_free_data(context, scratch); }
-
     /* put together an eblock for this encryption */
-
-    krb5_use_cstype(context, &eblock, etype);
-    privmsg.enc_part.ciphertext.length = krb5_encrypt_size(scratch->length,
+    krb5_use_cstype(context, &eblock, keyblock->etype);
+    privmsg.enc_part.ciphertext.length = krb5_encrypt_size(scratch1->length,
                                                eblock.crypto_entry);
     /* add padding area, and zero it */
-    if (!(scratch->data = realloc(scratch->data,
+    if (!(scratch1->data = realloc(scratch1->data,
                                  privmsg.enc_part.ciphertext.length))) {
-       /* may destroy scratch->data */
-       krb5_xfree(scratch);
+       /* may destroy scratch1->data */
+       krb5_xfree(scratch1);
        return ENOMEM;
     }
-    memset(scratch->data + scratch->length, 0,
-         privmsg.enc_part.ciphertext.length - scratch->length);
+
+    memset(scratch1->data + scratch1->length, 0,
+         privmsg.enc_part.ciphertext.length - scratch1->length);
     if (!(privmsg.enc_part.ciphertext.data =
          malloc(privmsg.enc_part.ciphertext.length))) {
         retval = ENOMEM;
         goto clean_scratch;
     }
 
-#define cleanup_encpart() {\
-       (void) memset(privmsg.enc_part.ciphertext.data, 0, \
-            privmsg.enc_part.ciphertext.length); \
-       free(privmsg.enc_part.ciphertext.data); \
-       privmsg.enc_part.ciphertext.length = 0; \
-       privmsg.enc_part.ciphertext.data = 0;}
-
     /* do any necessary key pre-processing */
-    if (retval = krb5_process_key(context, &eblock, key)) {
+    if (retval = krb5_process_key(context, &eblock, keyblock)) 
         goto clean_encpart;
-    }
-
-#define cleanup_prockey() {(void) krb5_finish_key(context, &eblock);}
 
     /* call the encryption routine */
-    if (retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
+    if (retval = krb5_encrypt(context, (krb5_pointer) scratch1->data,
                              (krb5_pointer) privmsg.enc_part.ciphertext.data,
-                             scratch->length, &eblock,
+                             scratch1->length, &eblock,
                              i_vector)) {
-        goto clean_prockey;
+       krb5_finish_key(context, &eblock);
+        goto clean_encpart;
     }
 
-
     /* put last block into the i_vector */
     if (i_vector)
        memcpy(i_vector,
@@ -148,50 +105,106 @@ krb5_mk_priv(context, userdata, etype, key, sender_addr, recv_addr,
                eblock.crypto_entry->block_length),
               eblock.crypto_entry->block_length);
           
-    /* private message is now assembled-- do some cleanup */
-    cleanup_scratch();
-
-    if (retval = krb5_finish_key(context, &eblock)) {
-        cleanup_encpart();
-        return retval;
+    if (retval = encode_krb5_priv(&privmsg, &scratch2))  {
+       krb5_finish_key(context, &eblock);
+        goto clean_encpart;
     }
+
     /* encode private message */
-    if (retval = encode_krb5_priv(&privmsg, &scratch))  {
-        cleanup_encpart();
-       return retval;
+    if (retval = krb5_finish_key(context, &eblock))
+        goto clean_encpart;
+
+    *outbuf = *scratch2;
+    krb5_xfree(scratch2);
+    retval = 0;
+
+clean_encpart:
+    memset(privmsg.enc_part.ciphertext.data, 0, 
+          privmsg.enc_part.ciphertext.length); 
+    free(privmsg.enc_part.ciphertext.data); 
+    privmsg.enc_part.ciphertext.length = 0;
+    privmsg.enc_part.ciphertext.data = 0;
+
+clean_scratch:
+    memset(scratch1->data, 0, scratch1->length);
+    krb5_free_data(context, scratch1); 
+
+    return retval;
+}
+
+
+krb5_error_code INTERFACE
+krb5_mk_priv(context, auth_context, userdata, outbuf, outdata)
+    krb5_context       context;
+    krb5_auth_context *        auth_context;
+    const krb5_data   * userdata;
+    krb5_data         *        outbuf;
+    krb5_replay_data  * outdata;
+{
+    krb5_replay_data    replaydata;
+    krb5_error_code    retval;
+
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
+      (auth_context->rcache == NULL))
+       return KRB5_RC_REQUIRED;
+
+    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->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) {
+       if (retval = krb5_us_timeofday(context, &replaydata.timestamp,
+                                      &replaydata.usec))
+           return retval;
+       if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
+           outdata->timestamp = replaydata.timestamp;
+           outdata->usec = replaydata.usec;
+       }
     }
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
+       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) {
+       replaydata.seq = auth_context->local_seq_number;
+       if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) {
+           auth_context->local_seq_number++;
+       } else {
+           outdata->seq = replaydata.seq;
+       }
+    } 
+
+    if (retval = krb5_mk_priv_basic(context, userdata, auth_context->keyblock,
+      &replaydata, auth_context->local_addr, auth_context->remote_addr,
+      auth_context->i_vector, outbuf)) 
+       goto error;
 
-    cleanup_encpart();
-    if (!(priv_flags & KRB5_PRIV_NOTIME)) {
+    if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
        krb5_donot_replay replay;
 
-       if (retval = krb5_gen_replay_name(context, sender_addr, "_priv",
-                                         &replay.client)) {
-           cleanup_scratch();
-           return retval;
+       if (retval = krb5_gen_replay_name(context, auth_context->local_addr, 
+                                         "_priv", &replay.client)) {
+           krb5_xfree(outbuf);
+           goto error;
        }
 
        replay.server = "";             /* XXX */
-       replay.cusec = privmsg_enc_part.usec;
-       replay.ctime = privmsg_enc_part.timestamp;
-       if (retval = krb5_rc_store(context, rcache, &replay)) {
+       replay.cusec = replaydata.usec;
+       replay.ctime = replaydata.timestamp;
+       if (retval = krb5_rc_store(context, auth_context->rcache, &replay)) {
            /* should we really error out here? XXX */
-           cleanup_scratch();
-           krb5_xfree(replay.client);
-           return retval;
+           krb5_xfree(outbuf);
+           goto error;
        }
        krb5_xfree(replay.client);
     }
-    *outbuf = *scratch;
-    krb5_xfree(scratch);
+
     return 0;
 
- clean_prockey:
-    cleanup_prockey();
- clean_encpart:
-    cleanup_encpart();
- clean_scratch:
-    cleanup_scratch();
+error:
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
+      (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
+       auth_context->local_seq_number--;
 
     return retval;
 }
index 91a769e9314d88ac8c9f7ccafef21501be81d8b2..3d86741fc188e2185c3ea83dbf0165a3d69f22f1 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "k5-int.h"
+#include "auth_con.h"
 
 /*
  Formats a KRB_AP_REQ message into outbuf.
 extern krb5_flags krb5_kdc_default_options;
 
 krb5_error_code INTERFACE
-krb5_mk_req(context, server, ap_req_options, checksum, ccache, outbuf)
-    krb5_context context;
-    krb5_const_principal server;
-    const krb5_flags ap_req_options;
-    const krb5_checksum *checksum;
-    krb5_ccache ccache;
-    krb5_data *outbuf;
+krb5_mk_req(context, auth_context, ap_req_options, service, hostname, in_data,
+             ccache, outbuf)
+    krb5_context          context;
+    krb5_auth_context  ** auth_context;
+    const krb5_flags      ap_req_options;
+    char               * service;
+    char               * hostname;
+    krb5_data           * in_data;
+    krb5_ccache          ccache;
+    krb5_data          * outbuf;
 {
-    krb5_error_code retval;
-    krb5_creds * credsp;
-    krb5_creds creds;
+    krb5_error_code      retval;
+    krb5_principal       server;
+    krb5_creds                 * credsp;
+    krb5_creds                   creds;
+    char              ** realm;
 
-    /* obtain ticket & session key */
+    /* get realm */
+    if (retval = krb5_get_host_realm(context, hostname, &realm)) 
+       return retval;
 
+    /* build principal */
+    if (retval = krb5_build_principal(context, &server, strlen(realm[0]),
+                                     realm[0], service, hostname, NULL))
+       goto cleanup_realm;
+                                     
+    /* obtain ticket & session key */
     memset((char *)&creds, 0, sizeof(creds));
     if (retval = krb5_copy_principal(context, server, &creds.server))
-       goto errout;
+       goto cleanup_princ;
+
     if (retval = krb5_cc_get_principal(context, ccache, &creds.client))
-       goto errout;
-    /* creds.times.endtime = 0; -- memset 0 takes care of this
-                                  zero means "as long as possible" */
-    /* creds.keyblock.keytype = 0; -- as well as this.
-                                             zero means no session keytype
-                                     preference */
+       goto cleanup_creds;
 
     if (retval = krb5_get_credentials(context, krb5_kdc_default_options,
                                      ccache, &creds, &credsp))
-       goto errout;
+       goto cleanup_creds;
 
-    retval = krb5_mk_req_extended(context, ap_req_options, checksum,
-                                 0,    /* no sequence number */
-                                 0,    /* no sub-key */
-                                 credsp,
-                                 0,    /* We don't need the authenticator */
-                                 outbuf);
+    retval = krb5_mk_req_extended(context, auth_context, ap_req_options, 
+                                 in_data, credsp, outbuf);
 
-errout:
-    krb5_free_cred_contents(context, &creds);
     krb5_free_creds(context, credsp);
+
+cleanup_creds:
+    krb5_free_cred_contents(context, &creds);
+
+cleanup_princ:
+    krb5_free_principal(context, server);
+
+cleanup_realm:
+    krb5_free_host_realm(context, realm);
     return retval;
 }
index 38c287c19d3729d8a9741f7c7569632ae71173d0..d30382fb8a2d49bd986b2d3259b537657a183843 100644 (file)
@@ -24,7 +24,9 @@
  * krb5_mk_req_extended()
  */
 
+
 #include "k5-int.h"
+#include "auth_con.h"
 
 /*
  Formats a KRB_AP_REQ message into outbuf, with more complete options than
@@ -66,87 +68,123 @@ krb5_generate_authenticator PROTOTYPE((krb5_context,
                                       krb5_int32, krb5_authdata ** ));
 
 krb5_error_code INTERFACE
-krb5_mk_req_extended(context, ap_req_options, checksum, sequence, 
-                    newkey, in_creds, authentp, outbuf)
-    krb5_context context;
-    const krb5_flags ap_req_options;
-    const krb5_checksum *checksum;
-    krb5_int32 sequence;
-    krb5_keyblock **newkey;
-    krb5_creds *in_creds;
-    krb5_authenticator *authentp;
-    krb5_data *outbuf;
+krb5_mk_req_extended(context, auth_context, ap_req_options, in_data, in_creds,
+                    outbuf)
+    krb5_context         context;
+    krb5_auth_context  **auth_context;
+    const krb5_flags     ap_req_options;
+    krb5_data          * in_data;
+    krb5_creds                 * in_creds;
+    krb5_data          * outbuf;
 {
-    krb5_error_code retval;
+    krb5_error_code      retval;
+    krb5_checksum        checksum;
+    krb5_auth_context  * new_auth_context;
+
     krb5_ap_req request;
-    krb5_authenticator authent;
-    krb5_data *scratch;
-    krb5_enctype etype;
+    krb5_data *scratch = 0;
     krb5_encrypt_block eblock;
     krb5_data *toutbuf;
-    int cleanup_key = 0;
 
-    request.ticket = 0;
     request.authenticator.ciphertext.data = 0;
-    if (newkey)
-       *newkey = 0;
-    scratch = 0;
+    request.ap_options = ap_req_options;
+    request.ticket = 0;
     
-    if ((ap_req_options & AP_OPTS_USE_SESSION_KEY) &&
-       !in_creds->ticket.length)
-       return(KRB5_NO_TKT_SUPPLIED);
-
     if (!in_creds->ticket.length) 
        return(KRB5_NO_TKT_SUPPLIED);
 
-/*     if (retval = krb5_get_credentials(context, kdc_options,
-                                         ccache, in_creds, out_creds)) */
-
     /* we need a native ticket */
     if (retval = decode_krb5_ticket(&(in_creds)->ticket, &request.ticket))
        return(retval);
     
     /* verify a valid etype is available */
-    etype = request.ticket->enc_part.etype;
-
-    if (!valid_etype(etype)) {
+    if (!valid_etype(request.ticket->enc_part.etype)) {
        retval = KRB5_PROG_ETYPE_NOSUPP;
        goto cleanup;
     }
 
-    request.ap_options = ap_req_options;
-    if (newkey) {
+    /* generate auth_context if needed */
+    if (*auth_context == NULL) {
+       if (retval = krb5_auth_con_init(context, &new_auth_context))
+           goto cleanup;
+       *auth_context = new_auth_context;
+    }
+
+    /* set auth context keyblock */
+    if (retval = krb5_copy_keyblock(context, &in_creds->keyblock, 
+                                   &((*auth_context)->keyblock))) 
+       goto cleanup;
+
+    /* generate seq number if needed */
+    if ((((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE)
+     || ((*auth_context)->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE))
+      && ((*auth_context)->local_seq_number == 0)) 
+       if (retval = krb5_generate_seq_number(context, &in_creds->keyblock,
+                                    &(*auth_context)->local_seq_number))
+           goto cleanup;
+       
+
+    /* generate subkey if needed */
+    if ((ap_req_options & AP_OPTS_USE_SUBKEY)&&(!(*auth_context)->local_subkey))
        if (retval = krb5_generate_subkey(context, &(in_creds)->keyblock, 
-                                         newkey))
+                                         &(*auth_context)->local_subkey))
            goto cleanup;
+
+
+    /* Generate checksum, XXX What should the seed be? */
+    if ((checksum.contents = (krb5_octet *)malloc(krb5_checksum_size(
+                                         context, CKSUMTYPE_CRC32))) == NULL) {
+       retval = ENOMEM;
+       goto cleanup;
+    }
+
+    if (in_data == NULL) {
+       if (retval = krb5_calculate_checksum(context, 
+                                            (*auth_context)->cksumtype, 
+                                            0, 0, 0, 0, &checksum))
+           goto cleanup_cksum;
+    } else 
+        if ((*auth_context)->cksumtype == 0x8003) {
+           /* XXX Special hack for GSSAPI */
+           checksum.checksum_type = 0x8003;
+           checksum.length = in_data->length;
+           checksum.contents = in_data->data;
+        } else 
+           if (retval = krb5_calculate_checksum(context, 
+                                                (*auth_context)->cksumtype, 
+                                                in_data->data, in_data->length,
+                                                0, 0, &checksum))
+               goto cleanup_cksum;
+
+    /* Generate authenticator */
+    if (((*auth_context)->authentp = (krb5_authenticator *)malloc(sizeof(
+                                       krb5_authenticator))) == NULL) {
+       retval = ENOMEM;
+       goto cleanup_cksum;
     }
 
-    if (retval = krb5_generate_authenticator(context, &authent, 
-                                            (in_creds)->client, checksum,
-                                            newkey ? *newkey : 0, sequence, 
+    if (retval = krb5_generate_authenticator(context, (*auth_context)->authentp,
+                                            (in_creds)->client, &checksum,
+                                            (*auth_context)->local_subkey,
+                                            (*auth_context)->local_seq_number,
                                             (in_creds)->authdata))
-       goto cleanup;
+       goto cleanup_cksum;
        
     /* encode the authenticator */
-    retval = encode_krb5_authenticator(&authent, &scratch);
-    if (retval)
-       goto cleanup;
+    if (retval = encode_krb5_authenticator((*auth_context)->authentp, &scratch))
+       goto cleanup_cksum;
     
     /* Null out these fields, to prevent pointer sharing problems;
      * they were supplied by the caller
      */
-    authent.client = NULL;
-    authent.checksum = NULL;
-    authent.authorization_data = NULL;
-    if (authentp)
-           *authentp = authent;
-    else
-           krb5_free_authenticator_contents(context, &authent);
+    (*auth_context)->authentp->client = NULL;
+    (*auth_context)->authentp->checksum = NULL;
+    (*auth_context)->authentp->authorization_data = NULL;
 
     /* put together an eblock for this encryption */
 
-    krb5_use_cstype(context, &eblock, etype);
-    request.authenticator.etype = etype;
+    krb5_use_cstype(context, &eblock, request.ticket->enc_part.etype);
+    request.authenticator.etype = request.ticket->enc_part.etype;
     request.authenticator.kvno = 0;
     request.authenticator.ciphertext.length =
        krb5_encrypt_size(scratch->length, eblock.crypto_entry);
@@ -155,39 +193,40 @@ krb5_mk_req_extended(context, ap_req_options, checksum, sequence,
                                  request.authenticator.ciphertext.length))) {
        /* may destroy scratch->data */
        retval = ENOMEM;
-       goto cleanup;
+       goto cleanup_cksum;
     }
     memset(scratch->data + scratch->length, 0,
          request.authenticator.ciphertext.length - scratch->length);
     if (!(request.authenticator.ciphertext.data =
          malloc(request.authenticator.ciphertext.length))) {
        retval = ENOMEM;
-       goto cleanup;
+       goto cleanup_cksum;
     }
 
     /* do any necessary key pre-processing */
     if (retval = krb5_process_key(context, &eblock, &(in_creds)->keyblock))
        goto cleanup;
 
-    cleanup_key++;
-
     /* call the encryption routine */
     if (retval = krb5_encrypt(context, (krb5_pointer) scratch->data,
                              (krb5_pointer) request.authenticator.ciphertext.data,
-                             scratch->length, &eblock, 0))
-       goto cleanup;
+                             scratch->length, &eblock, 0)) {
+        krb5_finish_key(context, &eblock);
+       goto cleanup_cksum;
+    }
 
     if (retval = krb5_finish_key(context, &eblock))
-       goto cleanup;
-    cleanup_key = 0;
+       goto cleanup_cksum;
     
-    retval = encode_krb5_ap_req(&request, &toutbuf);
-    if (retval)
-       goto cleanup;
+    if (retval = encode_krb5_ap_req(&request, &toutbuf))
+       goto cleanup_cksum;
     
     *outbuf = *toutbuf;
     krb5_xfree(toutbuf);
 
+cleanup_cksum:
+    free(checksum.contents);
+
 cleanup:
     if (request.ticket)
        krb5_free_ticket(context, request.ticket);
@@ -196,16 +235,11 @@ cleanup:
                      request.authenticator.ciphertext.length);
        free(request.authenticator.ciphertext.data);
     }
-    if (retval && newkey && *newkey)
-       krb5_free_keyblock(context, *newkey);
     if (scratch) {
        memset(scratch->data, 0, scratch->length);
         krb5_xfree(scratch->data);
        krb5_xfree(scratch);
     }
-    if (cleanup_key)
-       krb5_finish_key(context, &eblock);
-
     return retval;
 }
 
index 2832dd882160a2116d0d5e1517c65fb8b6ad4903..905e8a1e42d7aeb139c3ea3b5e9cc682dbf5a79a 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "k5-int.h"
+#include "auth_con.h"
 
 /*
  Formats a KRB_SAFE message into outbuf.
 
  returns system errors
 */
-krb5_error_code INTERFACE
-krb5_mk_safe(context, userdata, sumtype, key, sender_addr, recv_addr,
-            seq_number, safe_flags, rcache, outbuf)
-    krb5_context context;
-    const krb5_data * userdata;
-    const krb5_cksumtype sumtype;
-    const krb5_keyblock * key;
-    const krb5_address * sender_addr;
-    const krb5_address * recv_addr;
-    krb5_int32 seq_number;
-    krb5_int32 safe_flags;
-    krb5_rcache rcache;
-    krb5_data * outbuf;
+static krb5_error_code
+krb5_mk_safe_basic(context, userdata, keyblock, replaydata, local_addr,
+                  remote_addr, sumtype, outbuf)
+    krb5_context         context;
+    const krb5_data    * userdata;
+    const krb5_keyblock * keyblock;
+    krb5_replay_data    * replaydata;
+    const krb5_address         * local_addr;
+    const krb5_address         * remote_addr;
+    const krb5_cksumtype  sumtype;
+    krb5_data          * outbuf;
 {
     krb5_error_code retval;
     krb5_safe safemsg;
     krb5_octet zero_octet = 0;
     krb5_checksum safe_checksum;
-    krb5_data *scratch;
+    krb5_data *scratch1, *scratch2;
 
     if (!valid_cksumtype(sumtype))
        return KRB5_PROG_SUMTYPE_NOSUPP;
@@ -67,86 +66,128 @@ krb5_mk_safe(context, userdata, sumtype, key, sender_addr, recv_addr,
        return KRB5KRB_AP_ERR_INAPP_CKSUM;
 
     safemsg.user_data = *userdata;
-    safemsg.s_address = (krb5_address *)sender_addr;
-    if (recv_addr)
-       safemsg.r_address = (krb5_address *)recv_addr;
-    else
-       safemsg.r_address = 0;
-
-    if (!(safe_flags & KRB5_SAFE_NOTIME)) {
-       if (!rcache)
-           /* gotta provide an rcache in this case... */
-           return KRB5_RC_REQUIRED;
-       if (retval = krb5_us_timeofday(context, &safemsg.timestamp, &safemsg.usec))
-           return retval;
-    } else
-       safemsg.timestamp = 0, safemsg.usec = 0;
-    if (safe_flags & KRB5_SAFE_DOSEQUENCE) {
-       safemsg.seq_number = seq_number;
-     } else
-        safemsg.seq_number = 0;
-    
-    /* to do the checksum stuff, we need to encode the message with a
-       zero-length zero-type checksum, then checksum the encoding, then
-       re-encode with the 
-       checksum. */
+    safemsg.s_address = local_addr;
+    safemsg.r_address = remote_addr;
+
+    /* We should check too make sure one exists. */
+    safemsg.timestamp  = replaydata->timestamp;
+    safemsg.usec       = replaydata->usec;
+    safemsg.seq_number = replaydata->seq;
+
+    /* 
+     * To do the checksum stuff, we need to encode the message with a
+     * zero-length zero-type checksum, then checksum the encoding, then
+     * re-encode with the checksum. 
+     */
 
-    safe_checksum.checksum_type = 0;
     safe_checksum.length = 0;
+    safe_checksum.checksum_type = 0;
     safe_checksum.contents = &zero_octet;
 
     safemsg.checksum = &safe_checksum;
 
-    if (retval = encode_krb5_safe(&safemsg, &scratch))
+    if (retval = encode_krb5_safe(&safemsg, &scratch1))
        return retval;
 
-#define clean_scratch() {(void) memset((char *)scratch->data, 0,\
-                                      scratch->length); \
-                         krb5_free_data(context, scratch);}
-                        
     if (!(safe_checksum.contents =
          (krb5_octet *) malloc(krb5_checksum_size(context, sumtype)))) {
-       clean_scratch();
-       return ENOMEM;
+       retval = ENOMEM;
+       goto cleanup_scratch;
     }
-    if (retval = krb5_calculate_checksum(context, sumtype, scratch->data,
-                                        scratch->length,
-                                        (krb5_pointer) key->contents,
-                                        key->length, &safe_checksum)) {
-       krb5_xfree(safe_checksum.contents);
-       clean_scratch();
-       return retval;
+    if (retval = krb5_calculate_checksum(context, sumtype, scratch1->data,
+                                        scratch1->length,
+                                        (krb5_pointer) keyblock->contents,
+                                        keyblock->length, &safe_checksum)) {
+       goto cleanup_checksum;
     }
     safemsg.checksum = &safe_checksum;
-    clean_scratch();
-    if (retval = encode_krb5_safe(&safemsg, &scratch)) {
-       krb5_xfree(safe_checksum.contents);
-       return retval;
+    if (retval = encode_krb5_safe(&safemsg, &scratch2)) {
+       goto cleanup_checksum;
     }
+    *outbuf = *scratch2;
+    krb5_xfree(scratch2);
+    retval = 0;
+
+cleanup_checksum:
     krb5_xfree(safe_checksum.contents);
-    if (!(safe_flags & KRB5_SAFE_NOTIME)) {
-       krb5_donot_replay replay;
 
-       if (retval = krb5_gen_replay_name(context, sender_addr, "_safe",
-                                         &replay.client)) {
-           clean_scratch();
+cleanup_scratch:
+    memset((char *)scratch1->data, 0, scratch1->length); 
+    krb5_free_data(context, scratch1);
+    return retval;
+}
+
+krb5_error_code INTERFACE
+krb5_mk_safe(context, auth_context, userdata, outbuf, outdata)
+    krb5_context       context;
+    krb5_auth_context *        auth_context;
+    const krb5_data   * userdata;
+    krb5_data         *        outbuf;
+    krb5_replay_data  * outdata;
+{
+    krb5_replay_data    replaydata;
+    krb5_error_code    retval;
+
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) &&
+      (auth_context->rcache == NULL))
+       return KRB5_RC_REQUIRED;
+
+    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->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME)) {
+       if (retval = krb5_us_timeofday(context, &replaydata.timestamp,
+                                      &replaydata.usec))
            return retval;
+       if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_TIME) {
+           outdata->timestamp = replaydata.timestamp;
+           outdata->usec = replaydata.usec;
+       }
+    }
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
+       (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) {
+       replaydata.seq = auth_context->local_seq_number++;
+       if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE) {
+           outdata->seq = replaydata.seq;
+       }
+    } 
+
+    if (retval = krb5_mk_safe_basic(context, userdata, auth_context->keyblock,
+      &replaydata, auth_context->local_addr, auth_context->remote_addr,
+      auth_context->cksumtype, outbuf)) 
+       goto error;
+
+    if (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_TIME) {
+       krb5_donot_replay replay;
+
+       if (retval = krb5_gen_replay_name(context, auth_context->local_addr, 
+                                         "_safe", &replay.client)) {
+           krb5_xfree(outbuf);
+           goto error;
        }
 
        replay.server = "";             /* XXX */
-       replay.cusec = safemsg.usec;
-       replay.ctime = safemsg.timestamp;
-       if (retval = krb5_rc_store(context, rcache, &replay)) {
+       replay.cusec = replaydata.usec;
+       replay.ctime = replaydata.timestamp;
+       if (retval = krb5_rc_store(context, auth_context->rcache, &replay)) {
            /* should we really error out here? XXX */
-           clean_scratch();
-           krb5_xfree(replay.client);
-           return retval;
+           krb5_xfree(outbuf);
+           goto error;
        }
        krb5_xfree(replay.client);
     }
-    *outbuf = *scratch;
-    krb5_xfree(scratch);
 
     return 0;
+
+error:
+    if ((auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) ||
+      (auth_context->auth_context_flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE)) 
+       auth_context->local_seq_number--;
+
+    return retval;
 }
 
index f00440f9db80c13c0daf3a25e76ebbfdf52c1c4a..3aa6bd2659ff8bcefb2cf8da6b6e20c3100f06ec 100644 (file)
@@ -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, &currenttime)) {
-           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, &currenttime)) 
+           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;
+
 }
 
index e933b1dfc5810d24b8babac1252ae49930cf39ea..1dd981611682479203c0dce3f10e390f7050f0b6 100644 (file)
@@ -25,6 +25,7 @@
  */
 
 #include "k5-int.h"
+#include "auth_con.h"
 
 /*
  *  Parses a KRB_AP_REP message, returning its contents.
  */
 
 krb5_error_code INTERFACE
-krb5_rd_rep(context, inbuf, kblock, repl)
-    krb5_context context;
-    const krb5_data *inbuf;
-    const krb5_keyblock *kblock;
+krb5_rd_rep(context, auth_context, inbuf, repl)
+    krb5_context         context;
+    krb5_auth_context  * auth_context;
+    const krb5_data    * inbuf;
     krb5_ap_rep_enc_part **repl;
 {
     krb5_error_code retval;
@@ -52,9 +53,6 @@ krb5_rd_rep(context, inbuf, kblock, repl)
     if (!krb5_is_ap_rep(inbuf))
        return KRB5KRB_AP_ERR_MSG_TYPE;
 
-    if (!valid_keytype(kblock->keytype))
-       return KRB5_PROG_KEYTYPE_NOSUPP;
-    
     /* decode it */
 
     if (retval = decode_krb5_ap_rep(inbuf, &reply))
@@ -75,33 +73,46 @@ krb5_rd_rep(context, inbuf, kblock, repl)
     }
 
     /* do any necessary key pre-processing */
-    if (retval = krb5_process_key(context, &eblock, kblock)) {
-    errout:
-       free(scratch.data);
-       krb5_free_ap_rep(context, reply);
-       return(retval);
+    if (retval = krb5_process_key(context, &eblock, auth_context->keyblock)) {
+       goto errout;
     }
 
     /* call the encryption routine */
-    if (retval = krb5_decrypt(context, (krb5_pointer) reply->enc_part.ciphertext.data,
+    if (retval = krb5_decrypt(context, 
+                             (krb5_pointer) reply->enc_part.ciphertext.data,
                              (krb5_pointer) scratch.data,
                              scratch.length, &eblock, 0)) {
        (void) krb5_finish_key(context, &eblock);
        goto errout;
     }
-#define clean_scratch() {memset(scratch.data, 0, scratch.length); \
-free(scratch.data);}
+
     /* finished with the top-level encoding of the ap_rep */
-    krb5_free_ap_rep(context, reply);
-    if (retval = krb5_finish_key(context, &eblock)) {
+    if (retval = krb5_finish_key(context, &eblock)) 
+       goto clean_scratch;
 
-       clean_scratch();
-       return retval;
-    }
-    /*  now decode the decrypted stuff */
+    /* now decode the decrypted stuff */
     retval = decode_krb5_ap_rep_enc_part(&scratch, repl);
-    clean_scratch();
-    if ((*repl)->subkey)
+
+    /* Check reply fields */
+    if (((*repl)->ctime != auth_context->authentp->ctime) ||
+      ((*repl)->cusec != auth_context->authentp->cusec)) {
+       retval = KRB5_SENDAUTH_MUTUAL_FAILED;
+       goto clean_scratch;
+    }
+
+    /* Set auth subkey */
+    if ((*repl)->subkey) {
        (*repl)->subkey->etype = reply->enc_part.etype;
+       auth_context->remote_subkey = (*repl)->subkey;
+    }
+
+    /* Get remote sequence number */
+    auth_context->remote_seq_number = (*repl)->seq_number;
+
+clean_scratch:
+    memset(scratch.data, 0, scratch.length); 
+errout:
+    krb5_free_ap_rep(context, reply);
+    free(scratch.data);
     return retval;
 }
index 68c264bc8e5e7dc26766d1f14cd4d5740e045aa2..f97ca201b537744928cc267d5a33798ab9fd74b5 100644 (file)
@@ -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)
@@ -42,21 +43,19 @@ extern krb5_deltat krb5_clockskew;
 
  returns system errors, integrity errors
  */
-krb5_error_code INTERFACE
-krb5_rd_safe(context, inbuf, key, sender_addr, recv_addr, seq_number, 
-            safe_flags, 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 safe_flags;
-    krb5_rcache rcache;
-    krb5_data *outbuf;
+static krb5_error_code
+krb5_rd_safe_basic(context, inbuf, keyblock, recv_addr, sender_addr, 
+                  replaydata, outbuf)
+    krb5_context          context;
+    const krb5_data     * inbuf;
+    const krb5_keyblock * keyblock;
+    const krb5_address  * recv_addr;
+    const krb5_address  * sender_addr;
+    krb5_replay_data    * replaydata; 
+    krb5_data           * outbuf;
 {
-    krb5_error_code retval;
-    krb5_safe *message;
+    krb5_error_code      retval;
+    krb5_safe          * message;
     krb5_checksum our_cksum, *his_cksum;
     krb5_octet zero_octet = 0;
     krb5_data *scratch;
@@ -68,79 +67,37 @@ krb5_rd_safe(context, inbuf, key, sender_addr, recv_addr, seq_number,
     if (retval = decode_krb5_safe(inbuf, &message))
        return retval;
 
-#define cleanup() krb5_free_safe(context, message)
-
     if (!valid_cksumtype(message->checksum->checksum_type)) {
-       cleanup();
-       return KRB5_PROG_SUMTYPE_NOSUPP;
+       retval = KRB5_PROG_SUMTYPE_NOSUPP;
+       goto cleanup;
     }
     if (!is_coll_proof_cksum(message->checksum->checksum_type) ||
        !is_keyed_cksum(message->checksum->checksum_type)) {
-       cleanup();
-       return KRB5KRB_AP_ERR_INAPP_CKSUM;
-    }
-
-    if (!(safe_flags & KRB5_SAFE_NOTIME)) {
-       krb5_donot_replay replay;
-
-       if (retval = krb5_timeofday(context, &currenttime)) {
-           cleanup();
-           return retval;
-       }
-       /* in_clock_skew #defined above */
-       if (!in_clock_skew(message->timestamp)) {
-           cleanup();
-           return KRB5KRB_AP_ERR_SKEW;
-       }
-       if (!rcache) {
-           /* gotta provide an rcache in this case... */
-           cleanup();
-           return KRB5_RC_REQUIRED;
-       }
-       if (retval = krb5_gen_replay_name(context, sender_addr, "_safe",
-                                         &replay.client)) {
-           cleanup();
-           return retval;
-       }
-       replay.server = "";             /* XXX */
-       replay.cusec = message->usec;
-       replay.ctime = message->timestamp;
-       if (retval = krb5_rc_store(context, rcache, &replay)) {
-           krb5_xfree(replay.client);
-           cleanup();
-           return retval;
-       }
-       krb5_xfree(replay.client);
+       retval = KRB5KRB_AP_ERR_INAPP_CKSUM;
+       goto cleanup;
     }
 
-    if (safe_flags & KRB5_SAFE_DOSEQUENCE)
-       if (message->seq_number != seq_number) {
-           cleanup();
-           return KRB5KRB_AP_ERR_BADORDER;
-       }
-
     if (!krb5_address_compare(context, sender_addr, message->s_address)) {
-       cleanup();
-       return KRB5KRB_AP_ERR_BADADDR;
+       retval = KRB5KRB_AP_ERR_BADADDR;
+       goto cleanup;
     }
 
     if (message->r_address) {
        if (recv_addr) {
            if (!krb5_address_compare(context, recv_addr, message->r_address)) {
-               cleanup();
-               return KRB5KRB_AP_ERR_BADADDR;
+               retval = KRB5KRB_AP_ERR_BADADDR;
+               goto cleanup;
            }
        } else {
            krb5_address **our_addrs;
        
-           if (retval = krb5_os_localaddr( &our_addrs)) {
-               cleanup();
-               return retval;
-           }
+           if (retval = krb5_os_localaddr( &our_addrs)) 
+               goto cleanup;
+           
            if (!krb5_address_search(context, message->r_address, our_addrs)) {
                krb5_free_addresses(context, our_addrs);
-               cleanup();
-               return KRB5KRB_AP_ERR_BADADDR;
+               retval = KRB5KRB_AP_ERR_BADADDR;
+               goto cleanup;
            }
            krb5_free_addresses(context, our_addrs);
        }
@@ -152,56 +109,131 @@ krb5_rd_safe(context, inbuf, key, sender_addr, recv_addr, seq_number,
      */
     his_cksum = message->checksum;
 
-    our_cksum.checksum_type = 0;
     our_cksum.length = 0;
+    our_cksum.checksum_type = 0;
     our_cksum.contents = &zero_octet;
 
     message->checksum = &our_cksum;
 
-    if (retval = encode_krb5_safe(message, &scratch)) {
-       message->checksum = his_cksum;
-       cleanup();
-       return retval;
-    }
+    if (retval = encode_krb5_safe(message, &scratch)) 
+       goto cleanup;
+
     message->checksum = his_cksum;
                         
     if (!(our_cksum.contents = (krb5_octet *)
          malloc(krb5_checksum_size(context, his_cksum->checksum_type)))) {
-       cleanup();
-       return ENOMEM;
+       retval = ENOMEM;
+       goto cleanup;
     }
 
-#undef cleanup
-#define cleanup() {krb5_free_safe(context, message); krb5_xfree(our_cksum.contents);}
-
     retval = krb5_calculate_checksum(context, his_cksum->checksum_type,
                                     scratch->data, scratch->length,
-                                    (krb5_pointer) key->contents,
-                                    key->length, &our_cksum);
+                                    (krb5_pointer) keyblock->contents,
+                                    keyblock->length, &our_cksum);
     (void) memset((char *)scratch->data, 0, scratch->length);
     krb5_free_data(context, scratch);
     
     if (retval) {
-       cleanup();
-       return retval;
+       goto cleanup_cksum;
     }
 
     if (our_cksum.length != his_cksum->length ||
        memcmp((char *)our_cksum.contents, (char *)his_cksum->contents,
               our_cksum.length)) {
-       cleanup();
-       return KRB5KRB_AP_ERR_MODIFIED;
+       retval = KRB5KRB_AP_ERR_MODIFIED;
+       goto cleanup_cksum;
     }
 
+    replaydata->timestamp = message->timestamp;
+    replaydata->usec = message->usec;
+    replaydata->seq = message->seq_number;
+
     *outbuf = message->user_data;
+    message->user_data.data = NULL;
 
-    krb5_xfree(our_cksum.contents);
-    if (message->s_address)
-       krb5_free_address(context, message->s_address);
-    if (message->r_address)
-       krb5_free_address(context, message->r_address);
     krb5_free_checksum(context, his_cksum);
-    krb5_xfree(message);
+    return 0;
 
+cleanup_cksum:
+    krb5_xfree(our_cksum.contents);
+
+cleanup:
+    krb5_free_safe(context, message);
+    return retval;
+}
+
+krb5_error_code INTERFACE
+krb5_rd_safe(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_safe_basic(context, inbuf, auth_context->keyblock,
+      auth_context->local_addr, auth_context->remote_addr,
+      auth_context->cksumtype, &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, &currenttime)) 
+           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, 
+                                         "_safe", &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;
+       }
+    }
+
+    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;
+
 }
+
index 9eb08668eee6079915b7aad589db2a393689cf70..f093c488e5ffbaf2f387fa374081318688114315 100644 (file)
 
  returns system errors
  */
+
+static krb5_error_code 
+krb5_send_tgs_basic(context, in_data, sumtype, in_cred, outbuf)
+    krb5_context          context;
+    krb5_data           * in_data;
+    const krb5_cksumtype  sumtype;
+    krb5_creds          * in_cred;
+    krb5_data           * outbuf;
+{   
+    krb5_error_code       retval;
+    krb5_checksum         checksum;
+    krb5_authenticator           authent;
+    krb5_ap_req          request;
+    krb5_encrypt_block           eblock;
+    krb5_data          * scratch;
+    krb5_data           * toutbuf;
+
+    /* Generate checksum */
+    if ((checksum.contents = 
+      (krb5_octet *)malloc(krb5_checksum_size(context, sumtype))) == NULL) 
+        return(ENOMEM);
+
+    if (retval = krb5_calculate_checksum(context, sumtype,
+                                      in_data->data, in_data->length,
+                                     (krb5_pointer) in_cred->keyblock.contents,
+                                     in_cred->keyblock.length, &checksum)) {
+        free(checksum.contents);
+       return(retval);
+    }
+
+    /* gen authenticator */
+    authent.subkey = 0;
+    authent.seq_number = 0;
+    authent.checksum = &checksum;
+    authent.client = in_cred->client;
+    authent.authorization_data = in_cred->authdata;
+    if (retval = krb5_us_timeofday(context, &authent.ctime, &authent.cusec)) {
+        free(checksum.contents);
+       return(retval);
+    }
+
+    /* encode the authenticator */
+    if (retval = encode_krb5_authenticator(&authent, &scratch)) {
+        free(checksum.contents);
+       return(retval);
+    }
+
+    free(checksum.contents);
+
+    request.authenticator.ciphertext.data = 0;
+    request.authenticator.kvno = 0;
+    request.ap_options = 0;
+    request.ticket = 0;
+
+    if (retval = decode_krb5_ticket(&(in_cred)->ticket, &request.ticket))
+       /* Cleanup scratch and scratch data */
+        goto cleanup_data;
+
+    /* put together an eblock for this encryption */
+    krb5_use_cstype(context, &eblock, request.ticket->enc_part.etype);
+    request.authenticator.etype = request.ticket->enc_part.etype;
+    request.authenticator.ciphertext.length =
+        krb5_encrypt_size(scratch->length, eblock.crypto_entry);
+
+    /* add padding area, and zero it */
+    if (!(scratch->data = realloc(scratch->data,
+                                  request.authenticator.ciphertext.length))) {
+        /* may destroy scratch->data */ 
+        krb5_free_ticket(context, request.ticket);
+        retval = ENOMEM;
+        goto cleanup_scratch;
+    }
+    memset(scratch->data + scratch->length, 0,
+          request.authenticator.ciphertext.length - scratch->length);
+
+    if (!(request.authenticator.ciphertext.data =
+          malloc(request.authenticator.ciphertext.length))) {
+        retval = ENOMEM;
+        goto cleanup_ticket;
+    }
+
+    /* do any necessary key pre-processing */
+    if (retval = krb5_process_key(context, &eblock, &(in_cred)->keyblock))
+        goto cleanup;
+
+    /* call the encryption routine */ 
+    if (retval=krb5_encrypt(context, (krb5_pointer) scratch->data,
+                            (krb5_pointer)request.authenticator.ciphertext.data,
+                            scratch->length, &eblock, 0)) {
+        krb5_finish_key(context, &eblock);
+        goto cleanup;
+    }
+    
+    if (retval = krb5_finish_key(context, &eblock))
+        goto cleanup;
+
+    retval = encode_krb5_ap_req(&request, &toutbuf);
+    *outbuf = *toutbuf;
+    krb5_xfree(toutbuf);
+
+cleanup:
+    memset(request.authenticator.ciphertext.data, 0,
+           request.authenticator.ciphertext.length);
+    free(request.authenticator.ciphertext.data);
+
+cleanup_ticket:
+    krb5_free_ticket(context, request.ticket);
+
+cleanup_data:
+    memset(scratch->data, 0, scratch->length);
+    free(scratch->data);
+
+cleanup_scratch:
+    free(scratch);
+
+    return retval;
+}
+
 krb5_error_code INTERFACE
 krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
              authorization_data, padata, second_ticket, in_cred, rep)
@@ -63,7 +181,6 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
 {
     krb5_error_code retval;
     krb5_kdc_req tgsreq;
-    krb5_checksum ap_checksum;
     krb5_data *scratch, scratch2;
     krb5_ticket *sec_ticket = 0;
     krb5_ticket *sec_ticket_arr[2];
@@ -167,39 +284,15 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     if (retval = encode_krb5_kdc_req_body(&tgsreq, &scratch))
        goto send_tgs_error_2;
 
-    if (!(ap_checksum.contents = (krb5_octet *)
-         malloc(krb5_checksum_size(context, sumtype)))) {
-       krb5_free_data(context, scratch);
-       retval = ENOMEM;
-       goto send_tgs_error_2;
-    }
-
-    if (retval = krb5_calculate_checksum(context, sumtype, scratch->data,
-                                        scratch->length,
-                                (krb5_pointer) in_cred->keyblock.contents,
-                                        in_cred->keyblock.length,
-                                        &ap_checksum)) {
-       krb5_free_data(context, scratch);
-       goto send_tgs_error_3;
-    }
-    /* done with body */
-    krb5_free_data(context, scratch);
-
-    /* attach ap_req to the tgsreq */
-
     /*
      * Get an ap_req.
      */
-    if (retval = krb5_mk_req_extended (context,
-                                      0L /* no ap options */,
-                                      &ap_checksum,
-                                      0, /* no initial sequence */
-                                      0, /* no new key */
-                                      in_cred,
-                                      0, /* don't need authenticator */
-                                      &scratch2)) {
-       goto send_tgs_error_3;
+    if (retval = krb5_send_tgs_basic(context, scratch, sumtype,
+                                    in_cred, &scratch2)) {
+        krb5_free_data(context, scratch);
+       goto send_tgs_error_2;
     }
+    krb5_free_data(context, scratch);
 
     ap_req_padata.pa_type = KRB5_PADATA_AP_REQ;
     ap_req_padata.length = scratch2.length;
@@ -214,7 +307,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
        if (!combined_padata) {
            krb5_xfree(ap_req_padata.contents);
            retval = ENOMEM;
-           goto send_tgs_error_3;
+           goto send_tgs_error_2;
        }
        combined_padata[0] = &ap_req_padata;
        for (i = 1, counter = padata; *counter; counter++, i++)
@@ -225,7 +318,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
        if (!combined_padata) {
            krb5_xfree(ap_req_padata.contents);
            retval = ENOMEM;
-           goto send_tgs_error_3;
+           goto send_tgs_error_2;
        }
        combined_padata[0] = &ap_req_padata;
        combined_padata[1] = 0;
@@ -236,7 +329,7 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
     if (retval = encode_krb5_tgs_req(&tgsreq, &scratch)) {
        krb5_xfree(ap_req_padata.contents);
        krb5_xfree(combined_padata);
-       goto send_tgs_error_3;
+       goto send_tgs_error_2;
     }
     krb5_xfree(ap_req_padata.contents);
     krb5_xfree(combined_padata);
@@ -254,9 +347,6 @@ krb5_send_tgs(context, kdcoptions, timestruct, etypes, sumtype, sname, addrs,
            rep->message_type = KRB5_ERROR;
     }
 
-send_tgs_error_3:;
-    krb5_xfree(ap_checksum.contents);
-
 send_tgs_error_2:;
     if (sec_ticket) 
        krb5_free_ticket(context, sec_ticket);
index 4964cc7f3d993dd1a72f8b9e5a248b303b7b75d6..e71a749704c9f2f3ca72906acfbee485f2b744b5 100644 (file)
  */
 
 #define NEED_SOCKETS
+
 #include "k5-int.h"
 #include "com_err.h"
+#include "auth_con.h"
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
@@ -38,28 +40,27 @@ extern krb5_flags   krb5_kdc_default_options;
 static char *sendauth_version = "KRB5_SENDAUTH_V1.0";
 
 krb5_error_code INTERFACE
-krb5_sendauth(context,
+krb5_sendauth(context, auth_context,
              /* IN */
-             fd, appl_version, client, server, ap_req_options, checksump,
+             fd, appl_version, client, server, ap_req_options, in_data,
              in_creds,
              /* IN/OUT */
              ccache,
              /* OUT */
-             sequence, newkey, error, rep_result, out_creds)
-       krb5_context context;
-       krb5_pointer    fd;
-       char    *appl_version;
-       krb5_principal  client;
-       krb5_principal  server;
-       krb5_flags      ap_req_options;
-       krb5_int32      *sequence;
-       krb5_keyblock   **newkey;
-       krb5_checksum   *checksump;
-       krb5_creds      *in_creds;
-       krb5_ccache     ccache;
-       krb5_error      **error;
-       krb5_ap_rep_enc_part    **rep_result;
-       krb5_creds      **out_creds;
+             error, rep_result, out_creds)
+       krb5_context              context;
+       krb5_auth_context      ** auth_context;
+       krb5_pointer              fd;
+       char                    * appl_version;
+       krb5_principal            client;
+       krb5_principal            server;
+       krb5_flags                ap_req_options;
+       krb5_data               * in_data;
+       krb5_creds              * in_creds;
+       krb5_ccache               ccache;
+       krb5_error             ** error;
+       krb5_ap_rep_enc_part   ** rep_result;
+       krb5_creds             ** out_creds;
 {
        krb5_flags              kdc_options = krb5_kdc_default_options;
        krb5_octet              result;
@@ -67,7 +68,6 @@ krb5_sendauth(context,
        krb5_creds *            credsp = NULL;
        krb5_creds *            credspout = NULL;
        krb5_error_code         retval = 0;
-       krb5_authenticator      authent;
        krb5_data               inbuf, outbuf;
        int                     len;
        krb5_ccache             use_ccache = 0;
@@ -90,14 +90,14 @@ krb5_sendauth(context,
         * Now, read back a byte: 0 means no error, 1 means bad sendauth
         * version, 2 means bad application version
         */
-       if ((len = krb5_net_read(context, *((int *) fd), (char *)&result, 1)) != 1)
-               return((len < 0) ? errno : ECONNABORTED);
-       if (result == 1)
-               return(KRB5_SENDAUTH_BADAUTHVERS);
-       else if (result == 2)
-               return(KRB5_SENDAUTH_BADAPPLVERS);
-       else if (result != 0)
-               return(KRB5_SENDAUTH_BADRESPONSE);
+    if ((len = krb5_net_read(context, *((int *) fd), (char *)&result, 1)) != 1)
+       return((len < 0) ? errno : ECONNABORTED);
+    if (result == 1)
+       return(KRB5_SENDAUTH_BADAUTHVERS);
+    else if (result == 2)
+       return(KRB5_SENDAUTH_BADAPPLVERS);
+    else if (result != 0)
+       return(KRB5_SENDAUTH_BADRESPONSE);
        /*
         * We're finished with the initial negotiations; let's get and
         * send over the authentication header.  (The AP_REQ message)
@@ -108,7 +108,6 @@ krb5_sendauth(context,
         * credentials cache.
         */
        memset((char *)&creds, 0, sizeof(creds));
-       memset((char *)&authent, 0, sizeof(authent));
 
        /*
         * See if we need to access the credentials cache
@@ -148,21 +147,9 @@ krb5_sendauth(context,
            credsp = in_creds;
        }
 
-       /*
-        * Generate a random sequence number
-        */
-       if (sequence &&
-           (retval = krb5_generate_seq_number(context, &credsp->keyblock,
-                                              sequence))) 
-           goto error_return;
-
-       /*
-        * OK, get the authentication header!
-        */
-       if (retval = krb5_mk_req_extended(context, ap_req_options, checksump,
-                                         sequence ? *sequence : 0, newkey,
-                                         credsp, &authent, &outbuf))
-           goto error_return;
+    if (retval = krb5_mk_req_extended(context, auth_context, ap_req_options,
+                                     in_data, credsp, &outbuf))
+       goto error_return;
 
        /*
         * First write the length of the AP_REQ message, then write
@@ -189,8 +176,8 @@ krb5_sendauth(context,
                        goto error_return;
                    }
                }
-               krb5_xfree(inbuf.data);
                retval = KRB5_SENDAUTH_REJECTED;
+               krb5_xfree(inbuf.data);
                goto error_return;
        }
        
@@ -204,16 +191,14 @@ krb5_sendauth(context,
            if (retval = krb5_read_message(context, fd, &inbuf))
                goto error_return;
 
-           retval = krb5_rd_rep(context, &inbuf, &credsp->keyblock, &repl);
-           krb5_xfree(inbuf.data);
-           if (retval || ((repl->ctime != authent.ctime) ||
-                          (repl->cusec != authent.cusec)))
-               retval = KRB5_SENDAUTH_MUTUAL_FAILED;
-           if (retval) {
+           if (retval = krb5_rd_rep(context, *auth_context, &inbuf, &repl)) {
                if (repl)
                    krb5_free_ap_rep_enc_part(context, repl);
+               krb5_xfree(inbuf.data);
                goto error_return;
            }
+
+           krb5_xfree(inbuf.data);
            /*
             * If the user wants to look at the AP_REP message,
             * copy it for him
@@ -227,13 +212,13 @@ krb5_sendauth(context,
        if (out_creds) {
                *out_creds = credsp;
        }
+
 error_return:
-       if (credspout)
-               krb5_free_creds(context, credspout); 
-       if (!ccache && use_ccache)
-               krb5_cc_close(context, use_ccache);
-       krb5_free_authenticator_contents(context, &authent);
-       return(retval);
+    if (credspout)
+       krb5_free_creds(context, credspout); 
+    if (!ccache && use_ccache)
+       krb5_cc_close(context, use_ccache);
+    return(retval);
 }