]> asedeno.scripts.mit.edu Git - 1ts-debian.git/commitdiff
done milestone 3; working on refactoring
authorkcr <kcr@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Wed, 11 Jun 2003 05:40:37 +0000 (05:40 +0000)
committerkcr <kcr@cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f>
Wed, 11 Jun 2003 05:40:37 +0000 (05:40 +0000)
git-svn-id: svn://svn.1ts.org/debian/branches/athena-update-branch@181 cbed1d16-5ef5-0310-b6a1-d4a37b08ba1f

12 files changed:
zephyr/TODO
zephyr/h/internal.h
zephyr/lib/Makefile.in
zephyr/lib/ZCkAuth.c
zephyr/lib/ZCkZAut.c
zephyr/lib/ZGetSender.c
zephyr/lib/ZInit.c
zephyr/lib/ZMkAuth.c
zephyr/lib/ZParseNot.c
zephyr/lib/Zinternal.c
zephyr/server/kstuff.c
zephyr/zhm/zhm_client.c

index 80b84804dbbafcea8e45d406f06739938295e961..c58e010f78526b374f48e2305a70e44517b16a18 100644 (file)
@@ -17,7 +17,7 @@ Milestone 3
          * client sends only new-style messages
 
 Milestone 3.5
-         * offer to Derrick.
+         * refactor checksumming code
 
 Milestone 4
          * server sends only newstyle messages, and can't brain dump the
@@ -38,6 +38,7 @@ Milestone 6.5
 
 Milestone 7
          * brain dump via krb5, encrypted
+         (optional) brain dump to/from file
 
 Milestone 8
          * bring sourceforge up to date
index 78f98cfa9d7b63b423e6496b1cdc7fd3172f13e6..9ec5e34b42f5f74ec4a4ea8fe5fe53aa2c5ef70b 100644 (file)
@@ -117,6 +117,30 @@ void Z_gettimeofday(struct _ZTimeval *ztv, struct timezone *tz);
 
 #ifdef HAVE_KRB5
 int ZGetCreds(krb5_creds **creds_out);
+int ZGetCredsRealm(krb5_creds **creds_out, char *realm);
+Code_t Z_Checksum(krb5_data *cksumbuf, krb5_keyblock *keyblock, krb5_cksumtype cksumtype, char **asn1_data, int *asn1_len);
+Code_t Z_ExtractEncCksum(krb5_keyblock *keyblock, krb5_enctype *enctype, krb5_cksumtype *cksumtype);
+int Z_krb5_verify_cksum(krb5_keyblock *keyblock, krb5_data *cksumbuf, krb5_cksumtype cksumtype, char *asn1_data, int asn1_len);
+
+#endif
+
+#ifdef HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+#define Z_keydata(keyblock)    ((keyblock)->contents)
+#define Z_keylen(keyblock)     ((keyblock)->length)
+#define Z_credskey(creds)      (&(creds)->keyblock)
+#else
+#define Z_keydata(keyblock)    ((keyblock)->keyvalue.data)
+#define Z_keylen(keyblock)     ((keyblock)->keyvalue.length)
+#define Z_credskey(creds)      (&(creds)->session)
 #endif
+
+#ifdef HAVE_KRB5_TICKET_ENC_PART2
+#define Z_tktprincp(tkt)       ((tkt)->enc_part2 != 0)
+#define Z_tktprinc(tkt)                ((tkt)->enc_part2->client)
+#else
+#define        Z_tktprincp(tkt)        ((tkt)->client != 0)
+#define Z_tktprinc(tkt)                ((tkt)->client)
+#endif
+
 #endif /* __INTERNAL_H__ */
 
index 1649a5e6e6b901e83375ee99dbc525ee0d82f5a1..9d291d7769bb3d6fe2e3015aeab3ce961787d001 100644 (file)
@@ -20,7 +20,7 @@ CC=@CC@
 INSTALL=@INSTALL@
 RANLIB=@RANLIB@
 FPIC=
-DEBUG=-O
+DEBUG=
 CPPFLAGS=@CPPFLAGS@
 CFLAGS=@CFLAGS@ ${DEBUG} ${FPIC}
 ALL_CFLAGS=${CFLAGS} -DSYSCONFDIR=\"${sysconfdir}\" -I${top_srcdir}/h \
index ed69a6a2a3ab8a84d49a7db32564fd3644ba9802..3e2dbf1007bcacd47630ba4d05d6cfd9c057c30d 100644 (file)
@@ -32,7 +32,8 @@ static char rcsid_ZCheckAuthentication_c[] =
 Code_t ZCheckAuthentication(notice, from)
     ZNotice_t *notice;
     struct sockaddr_in *from;
-{      
+{
+#if 0
 #if defined(HAVE_KRB4) || defined(HAVE_KRB5)
     int result;
     ZChecksum_t our_checksum;
@@ -81,4 +82,7 @@ Code_t ZCheckAuthentication(notice, from)
 #else
     return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
 #endif
+#else
+    ZCheckZcodeAuthentication(notice, from);
+#endif
 } 
index c0f962850b3ac4d2b1f8b15e1a0629499670a1e0..66fe7ce6fca34742d6db3097c52f1610eac15c5e 100644 (file)
@@ -48,101 +48,32 @@ Code_t ZCheckZcodeAuthentication(notice, from)
 #ifdef HAVE_KRB5
     {
         krb5_error_code result;
-        krb5_ccache ccache;
-        krb5_creds creds_in, *creds;
+        krb5_creds *creds;
         krb5_keyblock *keyblock;
         krb5_enctype enctype;
         krb5_cksumtype cksumtype;
         krb5_data cksumbuf;
-#if HAVE_KRB5_C_MAKE_CHECKSUM
-        krb5_checksum checksum;
-        krb5_boolean valid;
-#else
-        krb5_crypto cryptctx;
-        Checksum checksum;
-        size_t xlen;
-#endif
+       int valid;
         char *cksum0_base, *cksum1_base, *cksum2_base;
         char *svcinst, *x, *y;
         char *asn1_data, *key_data;
         int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len;
-        /* Get a pointer to the default ccache.  We don't need to free this. */
-        result = krb5_cc_default(Z_krb5_ctx, &ccache);
-        if (result)
-            return (ZAUTH_NO);
-
-        /* GRRR.  There's no allocator or constructor for krb5_creds */
-        /* GRRR.  It would be nice if this API were documented at all */
-        memset(&creds_in, 0, sizeof(creds_in));
-
-       result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
-       if (result) {
-           krb5_cc_close(Z_krb5_ctx, ccache);
-           return(result);
-       }
 
-        /* construct the service principal */
-       result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
-                                     strlen(__Zephyr_realm),
-                                     __Zephyr_realm,
-                                     SERVER_KRB5_SERVICE, SERVER_INSTANCE, 0);
-        if (result) {
-           krb5_free_cred_contents(Z_krb5_ctx, &creds_in);
-           krb5_cc_close(Z_krb5_ctx, ccache);
-            return (ZAUTH_NO);
-       }
-        /* HOLDING: creds_in.server */
-
-        /* look up or get the credentials we need */
-        result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
-                                      &creds_in, &creds);
-        krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
-       krb5_cc_close(Z_krb5_ctx, ccache);
+       result = ZGetCreds(&creds);
 
         if (result)
             return (ZAUTH_NO);
         /* HOLDING: creds */
 
         /* Figure out what checksum type to use */
-#if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
-        keyblock = &creds->keyblock;
-        key_data = keyblock->contents;
-        key_len  = keyblock->length;
-        enctype  = keyblock->enctype;
-        result = Z_krb5_lookup_cksumtype(enctype, &cksumtype);
+       keyblock = Z_credskey(creds);
+       key_data = Z_keydata(keyblock);
+       key_len = Z_keylen(keyblock);
+       result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
         if (result) {
            krb5_free_creds(Z_krb5_ctx, creds);
            return (ZAUTH_FAILED);
         }
-#else
-        keyblock = &creds->session;
-        key_data = keyblock->keyvalue.data;
-        key_len  = keyblock->keyvalue.length;
-       {
-           unsigned int len;  
-           ENCTYPE *val;  
-           int i = 0;  
-  
-           result  = krb5_keytype_to_enctypes(Z_krb5_ctx, keyblock->keytype,  
-                                              &len, &val);  
-           if (result) {  
-               krb5_free_creds(Z_krb5_ctx, creds);
-               return (ZAUTH_FAILED);
-           }  
-  
-           do {  
-               if (i == len) break; 
-               result = Z_krb5_lookup_cksumtype(val[i], &cksumtype);  
-               i++; 
-           } while (result != 0);  
-           if (result) {  
-               krb5_free_creds(Z_krb5_ctx, creds);
-               return (ZAUTH_FAILED);
-           }  
-           enctype = val[i-1];  
-       }  
-#endif
         /* HOLDING: creds */
 
         /* Assemble the things to be checksummed */
@@ -232,48 +163,16 @@ Code_t ZCheckZcodeAuthentication(notice, from)
         }
         /* HOLDING: creds, asn1_data, cksumbuf.data */
 
-#if HAVE_KRB5_C_MAKE_CHECKSUM
-        /* Verify the checksum -- MIT crypto API */
-        memset(&checksum, 0, sizeof(checksum));
-        checksum.length = asn1_len;
-        checksum.contents = asn1_data;
-       checksum.checksum_type = cksumtype;
-        result = krb5_c_verify_checksum(Z_krb5_ctx,
-                                        keyblock, Z_KEYUSAGE_SRV_CKSUM,
-                                        &cksumbuf, &checksum, &valid);
+       valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
+
         free(asn1_data);
         krb5_free_creds(Z_krb5_ctx, creds);
         free(cksumbuf.data);
-        if (!result && valid)
-            return (ZAUTH_YES);
-        else
-            return (ZAUTH_FAILED);
-#else
-       checksum.checksum.length = asn1_len;
-       checksum.checksum.data = asn1_data;
-       checksum.cksumtype = cksumtype;
-       /* HOLDING: creds, asn1_data, cksumbuf.data */
 
-        result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
-        krb5_free_creds(Z_krb5_ctx, creds);
-        if (result) {
-           free(asn1_data);
-            free(cksumbuf.data);
-            return result;
-        }
-        /* HOLDING: cryptctx, checksum, cksumbuf.data */
-        result = krb5_verify_checksum(Z_krb5_ctx, cryptctx,
-                                      Z_KEYUSAGE_SRV_CKSUM,
-                                      cksumbuf.data, cksumbuf.length,
-                                      &checksum);
-        krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
-       free(asn1_data);
-        free(cksumbuf.data);
-        if (result)
-            return (ZAUTH_FAILED);
-        else
-            return (ZAUTH_YES);
-#endif
+       if (valid)
+         return ZAUTH_YES;
+       else
+         return ZAUTH_FAILED;
     }
 #endif /* HAVE_KRB5 */
     return (notice->z_auth ? ZAUTH_YES : ZAUTH_NO);
index bd8a62bd8578abd136357cded78b152409eab26e..2a75354851ef04509991d796d5f3b459b7c91334 100644 (file)
@@ -76,7 +76,7 @@ char *ZGetSender()
     pw = getpwuid((int) getuid());
     if (!pw)
        return ("unknown");
-    sender = malloc(strlen(pw->pw_name) + strlen(__Zephyr_realm));
+    sender = malloc(strlen(pw->pw_name) + strlen(__Zephyr_realm) + 2);
     if (sender)
       (void) sprintf(sender, "%s@%s", pw->pw_name, __Zephyr_realm);
     return (sender);
index fe820facc05a4c66e3be1bddc7d18a75cb320167..024e2b29a291846728ddd9bf133553cc9cf03fab 100644 (file)
@@ -126,8 +126,11 @@ Code_t ZInitialize()
       strcpy(__Zephyr_realm, krealms[0]);
       krb5_free_host_realm(Z_krb5_ctx, krealms);
     } else {
+      char *p; /* XXX define this somewhere portable */
       /* XXX check ticket file here */
-      code = krb5_get_default_realm(Z_krb5_ctx, __Zephyr_realm);
+      code = krb5_get_default_realm(Z_krb5_ctx, &p);
+      strcpy(__Zephyr_realm, p);
+      krb5_free_default_realm(Z_krb5_ctx, p);
       if (code)
        return code;
     }
index bf17695f54eb6c8fbf1c4e5c132701b3e339358b..2a8b8da5888d66f636b6fe0ba368efeca607dcea 100644 (file)
@@ -34,6 +34,9 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
     int buffer_len;
     int *len;
 {
+#if 1
+    return ZMakeZcodeAuthentication(notice, buffer, buffer_len, len/*?XXX*/);
+#else
 #if defined(HAVE_KRB4) || defined(HAVE_KRB5)
     int result;
     time_t now;
@@ -113,6 +116,7 @@ Code_t ZMakeAuthentication(notice, buffer, buffer_len, len)
     notice->z_ascii_authent = "";
     return (Z_FormatRawHeader(notice, buffer, buffer_len, len, NULL, NULL));
 #endif
+#endif
 }
 
 Code_t ZMakeZcodeAuthentication(notice, buffer, buffer_len, phdr_len)
@@ -135,21 +139,13 @@ Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
 {
 #ifdef HAVE_KRB5
     krb5_error_code result;
-    krb5_ccache ccache;
-    krb5_creds creds_in, *creds;
+    krb5_creds *creds;
     krb5_keyblock *keyblock;
     krb5_enctype enctype;
     krb5_cksumtype cksumtype;
     krb5_auth_context authctx;
     krb5_data *authent;
     krb5_data cksumbuf;
-#if HAVE_KRB5_C_MAKE_CHECKSUM
-    krb5_checksum checksum;
-#else
-    krb5_crypto cryptctx;
-    Checksum checksum;
-    size_t xlen;
-#endif
     char *svcinst, *x, *y;
     char *cksum_start, *cstart, *cend, *asn1_data;
     int plain_len;   /* length of part not to be checksummed */
@@ -158,79 +154,18 @@ Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
     int cksum1_len;  /* length of part after checksum */
     int i, zcode_len, asn1_len;
     
-    /* Get a pointer to the default ccache.  We don't need to free this. */
-    result = krb5_cc_default(Z_krb5_ctx, &ccache);
-    if (result)
-       return result;
-    
-    /* GRRR.  There's no allocator or constructor for krb5_creds */
-    /* GRRR.  It would be nice if this API were documented at all */
-    memset(&creds_in, 0, sizeof(creds_in));
-
-    result = krb5_cc_get_principal(Z_krb5_ctx, ccache, &creds_in.client);
-    if (result) {
-      krb5_cc_close(Z_krb5_ctx, ccache);
-      return(result);
-    }
-
-    /* construct the service principal */
-    result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
-                                 strlen(realm),
-                                 realm,
-                                 SERVER_KRB5_SERVICE, SERVER_INSTANCE, 0);
-    if (result) {
-        krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
-       krb5_cc_close(Z_krb5_ctx, ccache);
-       return result;
-    }
-    /* HOLDING: creds_in.server, ccache */
-    
-    /* look up or get the credentials we need */
-    result = krb5_get_credentials(Z_krb5_ctx, 0 /* flags */, ccache,
-                                 &creds_in, &creds);
-    krb5_cc_close(Z_krb5_ctx, ccache);
-    krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* hope this is OK */
+    result = ZGetCredsRealm(&creds, realm);
     if (result)
        return result;
     /* HOLDING: creds */
     
     /* Figure out what checksum type to use */
-#if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
-    keyblock = &creds->keyblock;
-    enctype  = keyblock->enctype;
-
-    result = Z_krb5_lookup_cksumtype(enctype, &cksumtype);
+    keyblock = Z_credskey(creds);
+    result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
     if (result) {
        krb5_free_creds(Z_krb5_ctx, creds);
        return result;
     }
-#else
-    keyblock = &creds->session;
-    {
-       unsigned int len;
-       ENCTYPE *val;
-       int i = 0;
-
-       result  = krb5_keytype_to_enctypes(Z_krb5_ctx, keyblock->keytype,
-                                           &len, &val);
-       if (result) {
-           krb5_free_creds(Z_krb5_ctx, creds); 
-           return result;
-       }
-
-       do {
-           if (i == len) break;
-           result = Z_krb5_lookup_cksumtype(val[i], &cksumtype);
-           i++;
-       } while (result != 0);
-
-       if (result) {
-           krb5_free_creds(Z_krb5_ctx, creds); 
-           return result;
-       }
-       enctype = val[i-1];
-    }
-#endif
     /* HOLDING: creds */
     
     /* Create the authenticator */
@@ -239,7 +174,7 @@ Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
        krb5_free_creds(Z_krb5_ctx, creds);
        return (result);
     }
-
+       
     authent = (krb5_data *)malloc(sizeof(krb5_data));
 
     /* HOLDING: creds, authctx */
@@ -300,43 +235,14 @@ Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
     memcpy(cksumbuf.data + cksum0_len, cend, cksum1_len);
     memcpy(cksumbuf.data + cksum0_len + cksum1_len,
           notice->z_message, notice->z_message_len);
-    
-#if HAVE_KRB5_C_MAKE_CHECKSUM
-    /* Create the checksum -- MIT crypto API */
-    result = krb5_c_make_checksum(Z_krb5_ctx, cksumtype,
-                                 keyblock, Z_KEYUSAGE_CLT_CKSUM,
-                                 &cksumbuf, &checksum);
-    krb5_free_creds(Z_krb5_ctx, creds);
-    if (result) {
-       free(cksumbuf.data);
-       return result;
-    }
-    /* HOLDING: cksumbuf.data, checksum */
 
-    asn1_data = checksum.contents;
-    asn1_len = checksum.length;
-#else
-    /* Create the checksum -- heimdal crypto API */
-    result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
+    /* compute the checksum */
+    result = Z_Checksum(&cksumbuf, keyblock, cksumtype, &asn1_data, &asn1_len);
     krb5_free_creds(Z_krb5_ctx, creds);
     if (result) {
        free(cksumbuf.data);
        return result;
     }
-    /* HOLDING: cksumbuf.data, cryptctx */
-    result = krb5_create_checksum(Z_krb5_ctx, cryptctx,
-                                 Z_KEYUSAGE_CLT_CKSUM, cksumtype,
-                                 cksumbuf.data, cksumbuf.length,
-                                 &checksum);
-    krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
-    if (result) {
-       free(cksumbuf.data);
-       return result;
-    }
-    asn1_len = checksum.checksum.length;
-    asn1_data = checksum.checksum.data;
-    /* HOLDING: cksumbuf.data, checksum */
-#endif
     
     /* 
      * OK....  we can zcode to a space starting at 'cstart',
@@ -356,17 +262,18 @@ Code_t ZMakeZcodeRealmAuthentication(notice, buffer, buffer_len, phdr_len,
     /* free stuff up, and then return the result from the last call */
 
     free(cksumbuf.data);
-#if HAVE_KRB5_C_MAKE_CHECKSUM
-    krb5_free_checksum_contents(Z_krb5_ctx, &checksum);
-#else
-    free_Checksum(&checksum);
-#endif
+    free(asn1_data);
+
     return (result);
 #endif /* HAVE_KRB5 */
 }
 
 #ifdef HAVE_KRB5
 int ZGetCreds(krb5_creds **creds_out) {
+  return ZGetCredsRealm(creds_out, __Zephyr_realm);
+}
+
+int ZGetCredsRealm(krb5_creds **creds_out, char *realm) {
   krb5_creds creds_in;
   krb5_ccache ccache; /* XXX make this a global or static?*/
   int result;
@@ -377,7 +284,8 @@ int ZGetCreds(krb5_creds **creds_out) {
 
   memset((char *)&creds_in, 0, sizeof(creds_in));
   result = krb5_build_principal(Z_krb5_ctx, &creds_in.server,
-                            strlen(__Zephyr_realm), __Zephyr_realm,
+                               strlen(realm),
+                               realm,
                                SERVER_SERVICE, SERVER_INSTANCE, 0);
   if (result) {
     krb5_cc_close(Z_krb5_ctx, ccache);
@@ -391,15 +299,12 @@ int ZGetCreds(krb5_creds **creds_out) {
     return result;
   }
   
-  creds_in.times.endtime = 0;
-  creds_in.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
+  creds_in.keyblock.enctype = ENCTYPE_DES_CBC_CRC; /* XXX? */
   
   result = krb5_get_credentials(Z_krb5_ctx, 0, ccache, &creds_in, creds_out);
   krb5_cc_close(Z_krb5_ctx, ccache);
   krb5_free_cred_contents(Z_krb5_ctx, &creds_in); /* I also hope this is ok */
 
   return result;
-  
-  
 }
 #endif
index 8cdc05155000a2aec989c14f516fe6924b8f2fba..1714674ed62b936f26d00fc22ab4063796e3c5d7 100644 (file)
@@ -212,11 +212,7 @@ Code_t ZParseNotice(buffer, len, notice)
     if (numfields && ptr < end) {
       notice->z_ascii_checksum = ptr;
 
-#ifdef xZCODE_K4SUM 
-      if (ZReadZcode32(ptr, end-ptr, &temp) == ZERR_BADFIELD) 
-#else
       if (ZReadAscii32(ptr, end-ptr, &temp) == ZERR_BADFIELD)
-#endif
        notice->z_checksum = 0;
       else
        notice->z_checksum = temp;
index ee1d5eeff93b3710be7167c34817f72d6732c4f0..015564b0f28a71f9e60a56745c7d22ab701db945 100644 (file)
@@ -1042,7 +1042,7 @@ Code_t Z_FormatRawHeader(notice, buffer, buffer_len, len, cstart, cend)
     if (cstart)
        *cstart = ptr;
     if (ZMakeAscii32(ptr, end-ptr, notice->z_checksum) == ZERR_FIELDLEN)
-       return (ZERR_HEADERLEN);
+        return (ZERR_HEADERLEN);
     ptr += strlen(ptr)+1;
     if (cend)
        *cend = ptr;
@@ -1295,3 +1295,140 @@ void ZSetDebug(proc, arg)
 }
 #endif /* Z_DEBUG */
 
+#ifdef HAVE_KRB5
+Code_t Z_Checksum(krb5_data *cksumbuf, krb5_keyblock *keyblock, krb5_cksumtype cksumtype, char **asn1_data, int *asn1_len) {
+    krb5_error_code result;
+    char *data;
+    int len;
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+    krb5_checksum checksum;
+#else
+    Checksum checksum;
+    krb5_crypto cryptctx;
+#endif
+    
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+    /* Create the checksum -- MIT crypto API */
+    result = krb5_c_make_checksum(Z_krb5_ctx, cksumtype,
+                                 keyblock, Z_KEYUSAGE_CLT_CKSUM,
+                                 cksumbuf, &checksum);
+    if (result)
+       return result;
+    /* HOLDING: checksum */
+
+    data = checksum.contents;
+    len = checksum.length;
+#else
+    /* Create the checksum -- heimdal crypto API */
+    result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
+    if (result)
+       return result;
+
+    /* HOLDING: cryptctx */
+    result = krb5_create_checksum(Z_krb5_ctx, cryptctx,
+                                 Z_KEYUSAGE_CLT_CKSUM, cksumtype,
+                                 cksumbuf->data, cksumbuf->length,
+                                 &checksum);
+    krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
+    if (result)
+       return result;
+
+    len = checksum.checksum.length;
+    data = checksum.checksum.data;
+    /* HOLDING: checksum */
+#endif
+
+    *asn1_data = malloc(len);
+    if (*asn1_data == NULL)
+       return errno;
+    memcpy(*asn1_data, data, len);
+    *asn1_len = len;
+
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+    krb5_free_checksum_contents(Z_krb5_ctx, &checksum);
+#else
+    free_Checksum(&checksum);
+#endif
+
+    return 0;
+}
+
+Code_t
+Z_ExtractEncCksum(krb5_keyblock *keyblock, krb5_enctype *enctype, krb5_cksumtype *cksumtype) {
+#if HAVE_KRB5_CREDS_KEYBLOCK_ENCTYPE
+    *enctype  = keyblock->enctype; 
+    return Z_krb5_lookup_cksumtype(*enctype, cksumtype); 
+#else 
+    unsigned int len; 
+    ENCTYPE *val; 
+    int i = 0; 
+    result = krb5_keytype_to_enctypes(Z_krb5_ctx, keyblock->keytype, 
+                                     &len, &val); 
+    if (result)
+      return result;
+    
+    do { 
+      if (i == len) break;
+      result = Z_krb5_lookup_cksumtype(val[i], cksumtype); 
+      i++;
+    } while (result != 0); 
+    
+    if (result)
+      return result;
+
+    *enctype = val[i-1]; 
+#endif
+    return 0;
+}
+#endif
+
+#ifdef HAVE_KRB5
+/* returns 0 if invalid or losing, 1 if valid, *sigh* */
+int
+Z_krb5_verify_cksum(krb5_keyblock *keyblock, krb5_data *cksumbuf, krb5_cksumtype cksumtype, char *asn1_data, int asn1_len) {
+    krb5_error_code result;
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+    krb5_checksum checksum;
+    krb5_boolean valid;
+#else
+    krb5_crypto cryptctx;
+    Checksum checksum;
+    size_t xlen;
+#endif
+
+    memset(&checksum, 0, sizeof(checksum));
+#if HAVE_KRB5_C_MAKE_CHECKSUM
+    /* Verify the checksum -- MIT crypto API */
+    checksum.length = asn1_len;
+    checksum.contents = asn1_data;
+    checksum.checksum_type = cksumtype;
+    result = krb5_c_verify_checksum(Z_krb5_ctx,
+                                   keyblock, Z_KEYUSAGE_SRV_CKSUM,
+                                   cksumbuf, &checksum, &valid);
+    if (!result && valid)
+       return 1;
+    else
+       return 0;
+#else
+    checksum.checksum.length = asn1_len;
+    checksum.checksum.data = asn1_data;
+    checksum.cksumtype = cksumtype;
+
+    result = krb5_crypto_init(Z_krb5_ctx, keyblock, enctype, &cryptctx);
+    if (result)
+       return result;
+    
+    /* HOLDING: cryptctx */
+    result = krb5_verify_checksum(Z_krb5_ctx, cryptctx,
+                                 Z_KEYUSAGE_SRV_CKSUM,
+                                 cksumbuf.data, cksumbuf.length,
+                                 &checksum);
+    krb5_crypto_destroy(Z_krb5_ctx, cryptctx);
+    if (result)
+       return 0;
+    else
+       return 1;
+#endif
+}
+#endif
index 423d5bd02eca7204de322eaabbff7864ccc44be9..1fa9b501e9e8f32d2a0afa02a35b1dbb707db643 100644 (file)
@@ -43,9 +43,6 @@ struct hash_entry {
 
 Hash_entry *hashtab[HASHTAB_SIZE];
 
-static int hash_ticket __P((unsigned char *, int));
-static void add_session_key __P((KTEXT, C_Block, char *, time_t));
-static int find_session_key __P((KTEXT, C_Block, char *));
 static ZChecksum_t compute_checksum __P((ZNotice_t *, C_Block));
 static ZChecksum_t compute_rlm_checksum __P((ZNotice_t *, C_Block));
 
@@ -510,10 +507,294 @@ ZCheckRealmAuthentication(notice, from, realm)
 #endif
 }
 
+Code_t
+ZCheckAuthentication(notice, from)
+    ZNotice_t *notice;
+    struct sockaddr_in *from;
+{       
+#ifdef HAVE_KRB5
+    char *authbuf;
+    krb5_principal princ;
+    krb5_data packet;
+    krb5_ticket *tkt;
+    char *name;
+    krb5_error_code result;
+    krb5_principal server;
+    krb5_keytab keytabid = 0;
+    krb5_auth_context authctx;
+    krb5_keyblock *keyblock; 
+    krb5_enctype enctype; 
+    krb5_cksumtype cksumtype; 
+    krb5_data cksumbuf;
+    int valid;
+    char *cksum0_base, *cksum1_base, *cksum2_base; 
+    char *svcinst, *x, *y; 
+    char *asn1_data, *key_data; 
+    int asn1_len, key_len, cksum0_len, cksum1_len, cksum2_len; 
+#ifdef KRB5_AUTH_CON_GETAUTHENTICATOR_TAKES_DOUBLE_POINTER
+    krb5_authenticator *authenticator;
+#define KRB5AUTHENT authenticator
+#else
+    krb5_authenticator authenticator;
+#define KRB5AUTHENT &authenticator
+#endif
+    int len;
+
+    if (!notice->z_auth)
+        return ZAUTH_NO;
+
+    /* Check for bogus authentication data length. */
+    if (notice->z_authent_len <= 1)
+        return ZAUTH_FAILED;
+
+#ifdef HAVE_KRB4
+    if (notice->z_ascii_authent[0] != 'Z')
+      return ZCheckAuthentication4(notice, from);
+#endif
+    
+    len = strlen(notice->z_ascii_authent)+1;
+    authbuf=malloc(len);
+
+    /* Read in the authentication data. */
+    if (ZReadZcode(notice->z_ascii_authent, 
+                   authbuf,
+                   len, &len) == ZERR_BADFIELD) {
+        return ZAUTH_FAILED;
+    }
+
+    packet.length = len;
+    packet.data = authbuf;
+
+    result = krb5_kt_resolve(Z_krb5_ctx, 
+                        keytab_file, &keytabid);
+    if (result) {
+      free(authbuf);
+      return (result);
+    }
+
+    /* HOLDING: authbuf, keytabid */
+    /* Create the auth context */
+    result = krb5_auth_con_init(Z_krb5_ctx, &authctx);
+    if (result) {
+        krb5_kt_close(Z_krb5_ctx, keytabid);
+        free(authbuf);
+        return (result);
+    }
+
+    /* HOLDING: authbuf, authctx */
+    result = krb5_build_principal(Z_krb5_ctx, &server, strlen(__Zephyr_realm), 
+                                 __Zephyr_realm, SERVER_SERVICE, 
+                                 SERVER_INSTANCE, NULL);
+    if (!result) {
+        result = krb5_rd_req(Z_krb5_ctx, &authctx, &packet, server, 
+                             keytabid, 0, &tkt);
+       krb5_free_principal(Z_krb5_ctx, server);
+    }
+    krb5_kt_close(Z_krb5_ctx, keytabid);
+
+    if (result) {
+      if (result == KRB5KRB_AP_ERR_REPEAT)
+       syslog(LOG_DEBUG, "k5 auth failed: %s", error_message(result));
+      else
+        syslog(LOG_WARNING,"k5 auth failed: %s", error_message(result));
+        free(authbuf);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        return ZAUTH_FAILED;
+    }
+
+    /* HOLDING: authbuf, authctx, tkt */
+
+    if (tkt == 0 || !Z_tktprincp(tkt)) {
+       if (tkt) krb5_free_ticket(Z_krb5_ctx, tkt);
+       free(authbuf);
+       krb5_auth_con_free(Z_krb5_ctx, authctx);
+       return ZAUTH_FAILED;
+    }
+    princ = Z_tktprinc(tkt);
+
+    if (princ == 0) {
+        krb5_free_ticket(Z_krb5_ctx, tkt);
+        free(authbuf);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        return ZAUTH_FAILED;
+    }
+
+    /* HOLDING: authbuf, authctx, tkt */
+    result = krb5_unparse_name(Z_krb5_ctx, princ, &name);
+    if (result) {
+        syslog(LOG_WARNING, "k5 unparse_name failed: %s",
+               error_message(result));
+        free(authbuf);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        krb5_free_ticket(Z_krb5_ctx, tkt);
+        return ZAUTH_FAILED;
+    }
+
+    krb5_free_ticket(Z_krb5_ctx, tkt);
+
+    /* HOLDING: authbuf, authctx, name */
+    if (strcmp(name, notice->z_sender)) {
+        syslog(LOG_WARNING, "k5 name mismatch: '%s' vs '%s'",
+               name, notice->z_sender);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        free(name);
+        free(authbuf);
+        return ZAUTH_FAILED;
+    }
+    free(name);
+    free(authbuf);
+
+    /* HOLDING: authctx */
+    /* Get an authenticator so we can get the keyblock */
+    result = krb5_auth_con_getauthenticator (Z_krb5_ctx, authctx,
+                                            &authenticator);
+    if(result) {
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        return result;
+    }
+
+    /* HOLDING: authctx, authenticator */
+    result = krb5_auth_con_getkey(Z_krb5_ctx, authctx, &keyblock);
+    if (result) {
+      krb5_auth_con_free(Z_krb5_ctx, authctx);
+      krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+      return (ZAUTH_FAILED);
+    }
+    
+    /* HOLDING: authctx, authenticator, keyblock */
+    /* Figure out what checksum type to use */
+    key_data = Z_keydata(keyblock);
+    key_len = Z_keylen(keyblock);
+    result = Z_ExtractEncCksum(keyblock, &enctype, &cksumtype);
+    if (result) { 
+        krb5_free_keyblock(Z_krb5_ctx, keyblock);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+        return (ZAUTH_FAILED); 
+    } 
+    /* HOLDING: authctx, authenticator, keyblock */
+
+    memcpy(__Zephyr_session, key_data, sizeof(C_Block)); /* XXX */
+    /* Assemble the things to be checksummed */ 
+    /* first part is from start of packet through z_default_format: 
+     * - z_version 
+     * - z_num_other_fields 
+     * - z_kind 
+     * - z_uid 
+     * - z_port 
+     * - z_auth 
+     * - z_authent_len 
+     * - z_ascii_authent 
+     * - z_class 
+     * - z_class_inst 
+     * - z_opcode 
+     * - z_sender 
+     * - z_recipient 
+     * - z_default_format 
+     */ 
+    cksum0_base = notice->z_packet; 
+    x           = notice->z_default_format; 
+    cksum0_len  = x + strlen(x) + 1 - cksum0_base; 
+    /* second part is from z_multinotice through other fields: 
+     * - z_multinotice 
+     * - z_multiuid 
+     * - z_other_fields[] 
+     */ 
+    cksum1_base = notice->z_multinotice; 
+    if (notice->z_num_other_fields) 
+        x = notice->z_other_fields[notice->z_num_other_fields]; 
+    else 
+        x = cksum1_base + strlen(cksum1_base) + 1; /* multiuid */ 
+    cksum1_len  = x + strlen(x) + 1 - cksum1_base; 
+    /* last part is the message body */ 
+    cksum2_base = notice->z_message; 
+    cksum2_len  = notice->z_message_len; 
+    if ((!notice->z_ascii_checksum || *notice->z_ascii_checksum != 'Z') && 
+        key_len == 8 && 
+        (enctype == ENCTYPE_DES_CBC_CRC || 
+         enctype == ENCTYPE_DES_CBC_MD4 || 
+         enctype == ENCTYPE_DES_CBC_MD5)) { 
+      /* try old-format checksum (covers cksum0 only) */ 
+      ZChecksum_t our_checksum; 
+      our_checksum = compute_checksum(notice, key_data);
+      
+      krb5_free_keyblock(Z_krb5_ctx, keyblock);
+      krb5_auth_con_free(Z_krb5_ctx, authctx);
+      krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+
+      if (our_checksum == notice->z_checksum)
+       return ZAUTH_YES; 
+      else
+       return ZAUTH_FAILED;
+    } 
+
+    /* HOLDING: authctx, authenticator */
+    cksumbuf.length = cksum0_len + cksum1_len + cksum2_len; 
+    cksumbuf.data = malloc(cksumbuf.length); 
+    if (!cksumbuf.data) { 
+        krb5_free_keyblock(Z_krb5_ctx, keyblock);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+        return ZAUTH_NO; 
+    } 
+    /* HOLDING: authctx, authenticator, cksumbuf.data */ 
+    memcpy(cksumbuf.data, cksum0_base, cksum0_len); 
+    memcpy(cksumbuf.data + cksum0_len, cksum1_base, cksum1_len); 
+    memcpy(cksumbuf.data + cksum0_len + cksum1_len, 
+           cksum2_base, cksum2_len); 
+    /* decode zcoded checksum */ 
+    /* The encoded form is always longer than the original */ 
+    asn1_len = strlen(notice->z_ascii_checksum) + 1; 
+    asn1_data = malloc(asn1_len); 
+    if (!asn1_data) { 
+        krb5_free_keyblock(Z_krb5_ctx, keyblock);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+        free(cksumbuf.data); 
+        return ZAUTH_FAILED; 
+    } 
+    /* HOLDING: authctx, authenticator, cksumbuf.data, asn1_data */ 
+    result = ZReadZcode(notice->z_ascii_checksum, 
+                        asn1_data, asn1_len, &asn1_len); 
+    if (result != ZERR_NONE) { 
+        krb5_free_keyblock(Z_krb5_ctx, keyblock);
+        krb5_auth_con_free(Z_krb5_ctx, authctx);
+        krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+        free(asn1_data); 
+        free(cksumbuf.data); 
+        return ZAUTH_FAILED; 
+    } 
+    /* HOLDING: asn1_data, cksumbuf.data, authctx, authenticator */ 
+
+    valid = Z_krb5_verify_cksum(keyblock, &cksumbuf, cksumtype, asn1_data, asn1_len);
+
+    free(asn1_data); 
+    krb5_auth_con_free(Z_krb5_ctx, authctx);
+    krb5_free_authenticator(Z_krb5_ctx, KRB5AUTHENT);
+    krb5_free_keyblock(Z_krb5_ctx, keyblock);
+    free(cksumbuf.data); 
+    
+    if (valid) 
+        return (ZAUTH_YES); 
+    else 
+        return (ZAUTH_FAILED); 
+#else
+    return (notice->z_auth) ? ZAUTH_YES : ZAUTH_NO;
+#endif
+}
+
 #undef KRB5AUTHENT
 
 Code_t
-ZCheckAuthentication(notice, from)
+ZCheckAuthentication4(notice, from)
     ZNotice_t *notice;
     struct sockaddr_in *from;
 {      
@@ -542,29 +823,6 @@ ZCheckAuthentication(notice, from)
     }
     authent.length = notice->z_authent_len;
 
-#if 0
-    /* Copy the ticket out of the authentication data. */
-    if (krb_find_ticket(&authent, &ticket) != RD_AP_OK)
-       return ZAUTH_FAILED;
-
-    /* Try to do a fast check against the cryptographic checksum. */
-    if (find_session_key(&ticket, session_key, srcprincipal) >= 0) {
-       if (strcmp(srcprincipal, notice->z_sender) != 0)
-           return ZAUTH_FAILED;
-       if (notice->z_time.tv_sec - NOW > CLOCK_SKEW)
-           return ZAUTH_FAILED;
-       checksum = compute_checksum(notice, session_key);
-
-        /* If checksum matches, packet is authentic.  If not, we might
-        * have an outdated session key, so keep going the slow way.
-        */
-       if (checksum == notice->z_checksum) {
-           memcpy(__Zephyr_session, session_key, sizeof(C_Block));
-           return ZAUTH_YES;
-       }
-    }
-#endif
-
     strcpy(instance, SERVER_INSTANCE);
 
     /* We don't have the session key cached; do it the long way. */
@@ -589,13 +847,6 @@ ZCheckAuthentication(notice, from)
     if (checksum != notice->z_checksum)
        return ZAUTH_FAILED;
 
-#if 0
-    /* Record the session key, expiry time, and source principal in the
-     * hash table, so we can do a fast check next time. */
-    add_session_key(&ticket, dat.session, srcprincipal,
-                   (time_t)(dat.time_sec + dat.life * 5 * 60));
-#endif
-
     return ZAUTH_YES;
 
 #else /* !HAVE_KRB4 */
@@ -605,75 +856,6 @@ ZCheckAuthentication(notice, from)
 
 
 #ifdef HAVE_KRB4
-
-static int hash_ticket(p, len)
-    unsigned char *p;
-    int len;
-{
-    unsigned long hashval = 0, g;
-
-    for (; len > 0; p++, len--) {
-       hashval = (hashval << 4) + *p;
-       g = hashval & 0xf0000000;
-       if (g) {
-           hashval ^= g >> 24;
-           hashval ^= g;
-       }
-    }
-    return hashval % HASHTAB_SIZE;
-}
-
-static void add_session_key(ticket, session_key, srcprincipal, expires)
-    KTEXT ticket;
-    C_Block session_key;
-    char *srcprincipal;
-    time_t expires;
-{
-    Hash_entry *entry;
-    int hashval;
-
-    /* If we can't allocate memory for the hash table entry, just forget
-     * about it. */
-    entry = (Hash_entry *) malloc(sizeof(Hash_entry) - 1 + ticket->length);
-    if (!entry)
-       return;
-
-    /* Initialize the new entry. */
-    memcpy(entry->session_key, session_key, sizeof(entry->session_key));
-    strcpy(entry->srcprincipal, srcprincipal);
-    entry->expires = expires;
-    entry->ticket_len = ticket->length;
-    memcpy(entry->ticket, ticket->dat, ticket->length * sizeof(unsigned char));
-
-    /* Insert the new entry in the hash table. */
-    hashval = hash_ticket(ticket->dat, ticket->length);
-    entry->next = hashtab[hashval];
-    hashtab[hashval] = entry;
-}
-
-static int find_session_key(ticket, key, srcprincipal)
-    KTEXT ticket;
-    C_Block key;
-    char *srcprincipal;
-{
-    unsigned char *dat;
-    int hashval, len;
-    Hash_entry *entry;
-
-    dat = ticket->dat;
-    len = ticket->length;
-    hashval = hash_ticket(dat, len);
-
-    for (entry = hashtab[hashval]; entry; entry = entry->next) {
-       if (entry->ticket_len == len && memcmp(entry->ticket, dat, len) == 0) {
-           memcpy(key, entry->session_key, sizeof(entry->session_key));
-           strcpy(srcprincipal, entry->srcprincipal);
-           return 0;
-       }
-    }
-    return -1;
-}
-
 static ZChecksum_t compute_checksum(notice, session_key)
     ZNotice_t *notice;
     C_Block session_key;
index d8879808a7833aeb7da888d7d5fd13781520f628..4eeeb39f5e32d34aa7c63918dc20e11469813799 100644 (file)
@@ -74,7 +74,7 @@ void transmission_tower(notice, packet, pak_len)
            Zperr(ret);
            com_err("hm", ret, "setting destination");
        }
-       if ((ret = send_outgoing(notice)) != ZERR_NONE) {
+       if ((ret = ZSendPacket(packet, pak_len, 0)) != ZERR_NONE) {
            Zperr(ret);
            com_err("hm", ret, "while sending raw notice");
        }