[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Request for Comments on Proposed Patch



Summary:

I reported earlier that the Transarc Windows AFS client sends a  
non-standard authentication request (that resembles a Kerberos 4 auth  
request) which Heimdal ignores.

I think I know enough about that strange packet to propose a fix  
(attached).  I may have missed something.  Maybe you don't think we  
know enough.  One could argue the correct fix is to make the kdc return  
an "Unknown protocol version" error rather than silently drop the  
packet.

Any thoughts?


What I know:

The Transarc Windows clients, starting sometime after 3.6 2.5 began  
sending modified Kerb4 request packets.  The expected first two bytes  
are replaced with a different 10 bytes, but the remainder of the packet  
is the same.

Transarc's initial response to a query about the strange packet is that  
they don't think they've changed anything from standard Kerb 4.  ;-)

Transarc version 3.6 2.45 (and several close relatives) will send a  
standard Kerb 4 request if the response to the modified one is an  
"Unknown protocol version" error.

Our Transarc kaserver returns a standard Kerb 4 auth reply to the  
Transarc auth request, which works.


What I believe:

Transarc did something to the auth request after the OpenAFS split.   
Probably intentionally.  Probably with thoughts that it was an  
improvement (or possibly something they might use to discourage  
dependence on Open Source).

Of those ten bytes that are different: the third through 10'th seem to  
vary slowly, are the size of a single-DES code block, and are probably  
something encrypted.  The first two seem to always be 0x63 (99 decimal)  
and 0x03.  The 0x03 byte is what would be expected for that byte in a  
normal K4 auth request.

Since the Transarc client falls back to a standard K4 request without  
the extra 8 bytes I think it's safe to ignore them.

I'm guessing the "Unknown . . ." error message is what the MIT servers  
will return when presented with the Transarc request.  Heimdal fails  
because it doesn't answer at all.  (I discovered the fallback behavior  
of the Transarc client testing with an earlier, broken version of this  
patch.  ;-)

For those that don't read C: the following patch makes Heimdal treat 99  
(Transarc) the same as 4 (Kerb4) in the first byte of a received  
request.  Then it skips over the mystery extra 8 bytes as the packet is  
decoded.
---------------------------------
*** kerberos4.c.orig    Fri Sep 17 10:04:58 2004
--- kerberos4.c Fri Sep 17 17:26:51 2004
***************
*** 51,57 ****
   int
   maybe_version4(unsigned char *buf, int len)
   {
!     return len > 0 && *buf == 4;
   }

   static void
--- 51,59 ----
   int
   maybe_version4(unsigned char *buf, int len)
   {
!     return len > 0 && (*buf == 4 || *buf == 99);
!     /*  4 is the first byte of standard Kerberos 4 messages.           
*/
!     /* 99 is the first byte of Transarc Windows Kerb 4 messages.       
*/
   }

   static void
***************
*** 128,133 ****
--- 130,136 ----
       hdb_entry *client = NULL, *server = NULL;
       Key *ckey, *skey;
       int8_t pvno;
+     int32_t discard;
       int8_t msg_type;
       int lsb;
       char *name = NULL, *inst = NULL, *realm = NULL;
***************
*** 146,152 ****

       sp = krb5_storage_from_mem(buf, len);
       RCHECK(krb5_ret_int8(sp, &pvno), out);
!     if(pvno != 4){
         kdc_log(0, "Protocol version mismatch (krb4) (%d)", pvno);
         make_err_reply(reply, KDC_PKT_VER, NULL);
         goto out;
--- 149,155 ----

       sp = krb5_storage_from_mem(buf, len);
       RCHECK(krb5_ret_int8(sp, &pvno), out);
!     if(pvno != 4 && pvno != 99){
         kdc_log(0, "Protocol version mismatch (krb4) (%d)", pvno);
         make_err_reply(reply, KDC_PKT_VER, NULL);
         goto out;
***************
*** 154,159 ****
--- 157,166 ----
       RCHECK(krb5_ret_int8(sp, &msg_type), out);
       lsb = msg_type & 1;
       msg_type &= ~1;
+     if(pvno == 99){   /* Skip over unknown Transarc addition. */
+       RCHECK(krb5_ret_int32(sp, &discard), out);
+       RCHECK(krb5_ret_int32(sp, &discard), out);
+     }
       switch(msg_type){
       case AUTH_MSG_KDC_REQUEST:
         RCHECK(krb5_ret_stringz(sp, &name), out1);
------------------------------------------------------------------------ 
----
The opinions expressed in this message are mine,
not those of Caltech, JPL, NASA, or the US Government.
Henry.B.Hotz@jpl.nasa.gov, or hbhotz@oxy.edu