Merge branch 'rxkad-kdf-master' into HEAD
authorSimon Wilkinson <sxw@your-file-system.com>
Wed, 24 Jul 2013 14:55:26 +0000 (15:55 +0100)
committerSimon Wilkinson <sxw@your-file-system.com>
Wed, 24 Jul 2013 14:55:26 +0000 (15:55 +0100)
Merge the current OpenAFS master branch with the branch on which
OpenAFS-SA-2013-003 and OpenAFS-SA-2013-004 were developed.

66 files changed:
Makefile.in
doc/man-pages/pod8/asetkey.pod
src/WINNT/afsd/NTMakefile
src/WINNT/afsd/afskfw.c
src/WINNT/afssvrmgr/NTMakefile
src/WINNT/aklog/NTMakefile
src/WINNT/aklog/aklog.c
src/WINNT/client_creds/NTMakefile
src/WINNT/install/wix/feature.wxi
src/WINNT/install/wix/files.wxi
src/WINNT/install/wix/platform.wxi
src/WINNT/netidmgr_plugin/NTMakefile
src/WINNT/netidmgr_plugin/afsfuncs.c
src/aklog/aklog.c
src/aklog/asetkey.c
src/aklog/klog.c
src/auth/Makefile.in
src/auth/NTMakefile
src/auth/authcon.c
src/auth/cellconfig.p.h
src/bozo/Makefile.in
src/bozo/NTMakefile
src/bucoord/Makefile.in
src/bucoord/NTMakefile
src/budb/Makefile.in
src/budb/NTMakefile
src/butc/Makefile.in
src/butc/NTMakefile
src/crypto/hcrypto/afshcrypto.def
src/crypto/hcrypto/libafshcrypto.map
src/crypto/rfc3961/rfc3961.h
src/finale/Makefile.in
src/fsprobe/Makefile.in
src/gtx/Makefile.in
src/kauth/Makefile.in
src/kauth/NTMakefile
src/kauth/test/NTMakefile
src/libafsrpc/Makefile.in
src/libafsrpc/NTMakefile
src/libafsrpc/afsrpc.def
src/libafsrpc/libafsrpc.la.sym
src/log/Makefile.in
src/ptserver/Makefile.in
src/ptserver/NTMakefile
src/rxkad/Makefile.in
src/rxkad/liboafs_rxkad.la.sym
src/rxkad/private_data.h
src/rxkad/rxkad.p.h
src/rxkad/rxkad_prototypes.h
src/rxkad/rxkad_server.c
src/rxkad/ticket5.c
src/scout/Makefile.in
src/sgistuff/Makefile.in
src/tbutc/NTMakefile
src/tests/Makefile.in
src/tptserver/NTMakefile
src/tsm41/Makefile.in
src/update/Makefile.in
src/update/NTMakefile
src/uss/Makefile.in
src/venus/Makefile.in
src/viced/NTMakefile
src/vlserver/Makefile.in
src/vlserver/NTMakefile
src/volser/Makefile.in
src/volser/NTMakefile

index d919375..b001336 100644 (file)
@@ -216,7 +216,7 @@ afs: config export comerr afs_depinstall
 sys: cmd comerr afs hcrypto rx rxstat fsint sys_depinstall
        +${COMPILE_PART1} sys ${COMPILE_PART2}
 
-rxkad: cmd comerr hcrypto rx rxkad_depinstall
+rxkad: cmd comerr hcrypto rfc3961 rx rxkad_depinstall
        +${COMPILE_PART1} rxkad ${COMPILE_PART2}
 
 auth: cmd comerr hcrypto lwp rx rxkad audit sys auth_depinstall
index 71c4274..3dd3d28 100644 (file)
@@ -11,6 +11,10 @@ B<asetkey> add <I<kvno>> <I<keyfile>> <I<principal>>
 
 B<asetkey> add <I<kvno>> <I<key>>
 
+B<asetkey> add <I<type>> <I<kvno>> <I<subtype>> <I<key>>
+
+B<asetkey> add <I<type>> <I<kvno>> <I<subtype>> <I<keyfile>> <I<princ>>
+
 B<asetkey> delete <I<kvno>>
 
 B<asetkey> list
@@ -20,8 +24,8 @@ B<asetkey> list
 
 =head1 DESCRIPTION
 
-The B<asetkey> command is used to add a key to an AFS KeyFile from a
-Kerberos keytab.  It is similar to B<bos addkey> except that it must be
+The B<asetkey> command is used to add a key to an AFS KeyFile or KeyFileExt
+from a Kerberos keytab.  It is similar to B<bos addkey> except that it must be
 run locally on the system where the KeyFile is located and it takes the
 new key from the command line or a Kerberos 5 keytab rather than prompting
 for the password.
@@ -51,8 +55,9 @@ KeyFile to all other systems.
 
 =head1 CAUTIONS
 
-AFS currently only supports des-cbc-crc:v4 Kerberos keys.  Make sure, when
-creating the keytab with C<ktadd>, you pass C<-e des-cbc-crc:v4> to force
+Historically, AFS only supported des-cbc-crc:v4 Kerberos keys.  In environments
+which have not been upgraded to use the rxkad-k5 extension, when
+creating the keytab with C<ktadd>, you must pass C<-e des-cbc-crc:v4> to force
 the encryption type.  Otherwise, AFS authentication may not work.
 
 As soon as a new keytab is created with C<ktadd>, new AFS service tickets
@@ -65,14 +70,36 @@ work properly.
 
 All of the KeyFile entries must match the key in the Kerberos KDC, but
 each time C<ktadd> is run, it creates a new key.  Either the Update Server
-must be used to distribute the KeyFile to all servers or the same keytab
-must be used with B<asetkey> on each server.
+or some other mechanism must be used to distribute the KeyFile to all servers,
+or the same keytab must be used with B<asetkey> on each server.
 
 =head1 EXAMPLES
 
-The following commands create a new keytab for the principal C<afs> and
-then import the key into the KeyFile.  Note the kvno in the output from
-C<ktadd>.
+In a cell which is using the rxkad-k5 extension, the following commands
+create a new keytab for the principal C<afs/I<cell name>> and then import
+its keys into the KeyFileExt.  Note the kvno in the output from C<ktadd>.
+The values 18, 17, and 16 are the assigned numbers corresponding to the
+kerberos enctypes in the keytab.  These numbers can be determined from your
+system's krb5 headers.
+
+    % kadmin
+    Authenticating as principal kaduk/admin@ZONE.MIT.EDU with password.
+    Password for kaduk/admin@ZONE.MIT.EDU:
+    kadmin:  ktadd -k /tmp/afs.keytab afs/disarray.mit.edu
+    Entry for principal afs/disarray.mit.edu with kvno 4, encryption type
+    aes256-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/afs.keytab.
+    Entry for principal afs/disarray.mit.edu with kvno 4, encryption type
+    aes128-cts-hmac-sha1-96 added to keytab WRFILE:/tmp/afs.keytab.
+    Entry for principal afs/disarray.mit.edu with kvno 4, encryption type
+    des3-cbc-sha1 added to keytab WRFILE:/tmp/afs.keytab.
+    kadmin:  exit
+    % asetkey add rxkad_krb5 4 18 /tmp/afs.keytab afs/disarray.mit.edu
+    % asetkey add rxkad_krb5 4 17 /tmp/afs.keytab afs/disarray.mit.edu
+    % asetkey add rxkad_krb5 4 16 /tmp/afs.keytab afs/disarray.mit.edu
+
+In a cell which is <B<not>> using the rxkad-k5 extension, the following
+commands create a new keytab for the principal C<afs> and then import the
+key into the KeyFile.  Note the kvno in the output from C<ktadd>.
 
     % kadmin
     Authenticating as principal rra/admin@stanford.edu with password.
index 1c7bb0a..11b9204 100644 (file)
@@ -335,6 +335,7 @@ LOGON_DLLLIBS =\
     $(DESTDIR)\lib\afs\afsutil.lib \
     $(DESTDIR)\lib\opr.lib \
     $(DESTDIR)\lib\afsroken.lib \
+    $(DESTDIR)\lib\afsrpc.lib \
     $(LANAHELPERLIB) \
     $(AFSKFWLIB)
 
@@ -421,7 +422,8 @@ EXELIBS = \
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 EXELIBS2 = \
         $(DESTDIR)\lib\afsrpc.lib \
index c37804a..636b58b 100644 (file)
@@ -2631,8 +2631,6 @@ KFW_AFS_klog(
 
     increds.client = client_principal;
     increds.times.endtime = 0;
-    /* Ask for DES since that is what V4 understands */
-    increds.session.keytype = ENCTYPE_DES_CBC_CRC;
 
     /* ALWAYS first try service/cell@CLIENT_REALM */
     if (code = krb5_build_principal(context, &increds.server,
@@ -2740,9 +2738,9 @@ KFW_AFS_klog(
     atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
     atoken.startTime = k5creds->times.starttime;
     atoken.endTime = k5creds->times.endtime;
-    memcpy(&atoken.sessionKey,
-            k5creds->session.keyvalue.data,
-            k5creds->session.keyvalue.length);
+    if (tkt_DeriveDesKey(k5creds->session.keytype, k5creds->session.keyvalue.data,
+                        k5creds->session.keyvalue.length, &atoken.sessionKey))
+       goto cleanup;
     atoken.ticketLen = k5creds->ticket.length;
     memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen);
 
index c279ae5..ced9882 100644 (file)
@@ -103,7 +103,8 @@ EXELIBS = \
        $(DESTDIR)\lib\afs\TaAfsAppLib.lib \
         $(DESTDIR)\lib\afs\afsutil.lib \
        $(DESTDIR)\lib\opr.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrpc.lib
 
 ############################################################################
 
index 79da73f..c8d4293 100644 (file)
@@ -38,7 +38,8 @@ EXELIBS = \
         $(DESTDIR)\lib\afsrpc.lib \
         $(DESTDIR)\lib\afsauthent.lib \
        $(DESTDIR)\lib\opr.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrpc.lib
 
 OTHERLIBS = dnsapi.lib mpr.lib
 
index 9044899..55a7ccc 100644 (file)
@@ -512,7 +512,8 @@ static int get_v5cred(krb5_context context,
     increds.client = client_principal;
     increds.times.endtime = 0;
        /* Ask for DES since that is what V4 understands */
-    increds.session.keytype = ENCTYPE_DES_CBC_CRC;
+    if (c != NULL)
+       increds.keyblock.enctype = ENCTYPE_DES_CBC_CRC;
 
     r = krb5_get_credentials(context, 0, _krb425_ccache, &increds, creds);
     if (r) {
@@ -1001,7 +1002,12 @@ static int auth_to_cell(krb5_context context, char *cell, char *realm)
         atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
         atoken.startTime = v5cred->times.starttime;
         atoken.endTime = v5cred->times.endtime;
-        memcpy(&atoken.sessionKey, v5cred->session.keyvalue.data, v5cred->session.keyvalue.length);
+       if (tkt_DeriveDesKey(v5cred->session.keytype,
+                            v5cred->session.keyvalue.data,
+                            v5cred->session.keyvalue.length, &atoken.sessionKey)) {
+           status = AKLOG_MISC;
+           goto done;
+       }
         atoken.ticketLen = v5cred->ticket.length;
         memcpy(atoken.ticket, v5cred->ticket.data, atoken.ticketLen);
     } else {
index 030cb25..74a43a9 100644 (file)
@@ -73,7 +73,8 @@ EXELIBS = \
         $(DESTDIR)\lib\afs\afscom_err.lib \
         $(DESTDIR)\lib\afs\afsutil.lib \
        $(DESTDIR)\lib\opr.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrpc.lib
 
 ############################################################################
 #
index 65ef74f..e1a583d 100644 (file)
                 <ComponentRef Id="cmf_afsclientadmin_DLL" />
                 <ComponentRef Id="cmf_afsvosadmin_DLL" />
                 <ComponentRef Id="cmf_afsrpc_DLL" />
+                <ComponentRef Id="cmf_afsrfc3961_DLL" />
                 <ComponentRef Id="cmf_afshcrypto_DLL" />
                 <ComponentRef Id="cmf_afsroken_DLL" />
                 <ComponentRef Id="cmf_afsauthent2_DLL" />
                 <ComponentRef Id="cmf_afsadminutil_DLL" />
 
                 <ComponentRef Id="cmf_afsrpc_DLL" />
+                <ComponentRef Id="cmf_afsrfc3961_DLL" />
                 <ComponentRef Id="cmf_afshcrypto_DLL" />
                 <ComponentRef Id="cmf_afsroken_DLL" />
                 <ComponentRef Id="cmf_afsauthent2_DLL" />
                 <ComponentRef Id="cmf_afsvosadmin_DLL" />
                 <ComponentRef Id="cmf_afsadminutil_DLL" />
                 <ComponentRef Id="cmf_afsrpc_DLL" />
+                <ComponentRef Id="cmf_afsrfc3961_DLL" />
                 <ComponentRef Id="cmf_afshcrypto_DLL" />
                 <ComponentRef Id="cmf_afsroken_DLL" />
                 <ComponentRef Id="cmf_afsauthent2_DLL" />
                <ComponentRef Id="cmp_CommonDir" />
 
                 <ComponentRef Id="cmf_afsrpc_DLL" />
+                <ComponentRef Id="cmf_afsrfc3961_DLL" />
                 <ComponentRef Id="cmf_afshcrypto_DLL" />
                 <ComponentRef Id="cmf_afsroken_DLL" />
                 <ComponentRef Id="cmf_afsadminutil_DLL" />
index befaf58..f2fb2d1 100644 (file)
@@ -50,6 +50,9 @@
                 <Component Win64="$(var.Win64)" Id="cmf_afsrpc_DLL" Guid="$(var.cmf_afsrpc_DLL_guid)">
                     <File Id="fileafsrpc_DLL" Name="afsrpc.dll" LongName="afsrpc.dll" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afsrpc.dll"/>
                 </Component>
+                <Component Win64="$(var.Win64)" Id="cmf_afsrfc3961_DLL" Guid="$(var.cmf_afsrfc3961_DLL_guid)">
+                    <File Id="fileafsrfc3961_DLL" Name="afsrfc39.dll" LongName="afsrfc3961.dll" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afsrfc3961.dll"/>
+                </Component>
                 <Component Win64="$(var.Win64)" Id="cmf_afshcrypto_DLL" Guid="$(var.cmf_afshcrypto_DLL_guid)">
                     <File Id="fileafshcrypto_DLL" Name="afshcryp.dll" LongName="afshcrypto.dll" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afshcrypto.dll"/>
                 </Component>
@@ -88,6 +91,7 @@
               <?endif?>
                 <Component Win64="$(var.Win64)" Id="cmp_CommonCommonDebug" Guid="$(var.cmp_CommonCommonDebug_guid)">
                     <File Id="fileafsrpc_PDB" Name="afsrpc.pdb" LongName="afsrpc.pdb" KeyPath="yes" DiskId="1" src="$(var.LibDir)\afsrpc.pdb"/>
+                    <File Id="fileafsrfc3961_PDB" Name="afsrfc39.pdb" LongName="afsrfc3961.pdb" DiskId="1" src="$(var.LibDir)\afsrfc3961.pdb"/>
                     <File Id="fileafshcrypto_PDB" Name="afshcryp.pdb" LongName="afshcrypto.pdb" DiskId="1" src="$(var.LibDir)\afshcrypto.pdb"/>
                     <File Id="fileafsroken_PDB" Name="afsroken.pdb" LongName="afsroken.pdb" DiskId="1" src="$(var.LibDir)\afsroken.pdb"/>
                     <File Id="filelibafsconf_PDB" Name="libafscf.pdb" LongName="libafsconf.pdb" DiskId="1" src="$(var.LibDir)\libafsconf.pdb"/>
                                 <File Id="fileafsint_H" Name="afsint.h" LongName="afsint.h" DiskId="1" src="$(var.IncDir)afs\afsint.h" /> 
                                 <File Id="fileafskfw_H" Name="afskfw.h" LongName="afskfw.h" DiskId="1" src="$(var.IncDir)afs\afskfw.h" /> 
                                 <File Id="fileafsrpc_H" Name="afsrpc.h" LongName="afsrpc.h" DiskId="1" src="$(var.IncDir)afs\afsrpc.h" /> 
+                                <File Id="filerfc3961_H" Name="rfc3961.h" LongName="rfc3961.h" DiskId="1" src="$(var.IncDir)afs\rfc3961.h" />
                                 <File Id="fileafssyscalls_H" Name="AFSSYSCL.h" LongName="afssyscalls.h" DiskId="1" src="$(var.IncDir)afs\afssyscalls.h" />
                                 <File Id="fileafsutil_H" Name="afsutil.h" LongName="afsutil.h" DiskId="1" src="$(var.IncDir)afs\afsutil.h" /> 
                                 <File Id="fileafsutil_prototypes_H" Name="AFSUTILP.h" LongName="afsutil_prototypes.h" DiskId="1" src="$(var.IncDir)afs\afsutil_prototypes.h" />
                             <File Id="fileafslwp_LIB" Name="afslwp.lib" LongName="afslwp.lib" DiskId="1" src="$(var.LibDir)afslwp.lib" /> 
                             <File Id="fileafspthread_LIB" Name="AFSPTHRD.lib" LongName="afspthread.lib" DiskId="1" src="$(var.LibDir)afspthread.lib" />
                             <File Id="fileafsrpc_LIB" Name="afsrpc.lib" LongName="afsrpc.lib" DiskId="1" src="$(var.LibDir)afsrpc.lib" /> 
+                            <File Id="fileafsrfc3961_LIB" Name="afsrfc39.lib" LongName="afsrfc3961.lib" DiskId="1" src="$(var.LibDir)afsrfc3961.lib" />
                             <File Id="fileafshcrypto_LIB" Name="afshcryp.lib" LongName="afshcrypto.lib" DiskId="1" src="$(var.LibDir)afshcrypto.lib" /> 
                             <File Id="fileafsroken_LIB" Name="afsroken.lib" LongName="afsroken.lib" DiskId="1" src="$(var.LibDir)afsroken.lib" /> 
                             <File Id="fileafsrx_LIB" Name="afsrx.lib" LongName="afsrx.lib" DiskId="1" src="$(var.LibDir)afsrx.lib" /> 
                           <File Id="fileafsauthent_A" Name="afsauth.a" LongName="afsauthent.a" DiskId="1" src="$(var.LibDir)afsauthent.a" />
                           <File Id="fileafspthread_A" Name="afspthrd.a" LongName="afspthread.a" DiskId="1" src="$(var.LibDir)afspthread.a" />
                           <File Id="fileafsrpc_A" Name="afsrpc.a" LongName="afsrpc.a" DiskId="1" src="$(var.LibDir)afsrpc.a" />
+                          <File Id="fileafsrfc3961_A" Name="afsrfc39.a" LongName="afsrfc3961.a" DiskId="1" src="$(var.LibDir)afsrfc3961.a" />
                           <File Id="fileafshcrypto_A" Name="afshcryp.a" LongName="afshcrypto.a" DiskId="1" src="$(var.LibDir)afshcrypto.a" />
                           <File Id="filelibafsconf_A" Name="libafscf.a" LongName="libafsconf.a" DiskId="1" src="$(var.LibDir)libafsconf.a" />
                           <File Id="filelibosi_A" Name="libosi.a" LongName="libosi.a" DiskId="1" src="$(var.ClientDir)libosi.a" /> 
index 1209a1b..9bd3512 100644 (file)
@@ -28,6 +28,7 @@
        <?define cmf_afsvosadmin_DLL_guid="8955900E-E743-41A9-9C54-FCEB91A72ADE"?>
        <?define cmf_afsadminutil_DLL_guid="72495728-0024-4AAC-81F6-6E826BFFED86"?>
        <?define cmf_afsrpc_DLL_guid="AE9350B3-21AA-4204-A0A8-3D58C57EB178"?>
+       <?define cmf_afsrfc3961_DLL_guid="FBC41858-4EB1-4EAA-9FD7-AB1029602A70"?>
         <?define cmf_afshcrypto_DLL_guid="4C35B73D-7477-44AA-8763-8C09F570C7BD"?>
         <?define cmf_afsroken_DLL_guid="A9BB2D83-26A4-44BF-8235-F305E59393EA"?>
        <?define cmf_afsauthent2_DLL_guid="7BD58D90-B600-44B7-BBCB-545861E878EB"?>
        <?define cmf_afsvosadmin_DLL_guid="A97E0801-06A5-465C-99E1-E5F0E07166F0"?>
        <?define cmf_afsadminutil_DLL_guid="A9782D0F-768F-40F4-A600-A7240EFBEC8C"?>
        <?define cmf_afsrpc_DLL_guid="E75E2FC0-D011-494A-8142-670B3286C5C2"?>
+       <?define cmf_afsrfc3961_DLL_guid="8504A69A-84A1-47BB-9D3C-4A35592BB4CA"?>
         <?define cmf_afshcrypto_DLL_guid="5FB93926-07D4-4BFB-9532-726233D256CA"?>
         <?define cmf_afsroken_DLL_guid="9586EDB5-C1DE-4666-994C-5D2F4FC4D55E"?>
        <?define cmf_afsauthent2_DLL_guid="7B806F96-0542-4BCC-865B-E126CE3BCDA6"?>
index 25a197b..e3ea181 100644 (file)
@@ -94,6 +94,7 @@ OBJFILES=                             \
 
 LIBFILES=                              \
         $(DESTDIR)\lib\afsroken.lib     \
+       $(DESTDIR)\lib\afsrpc.lib       \
        $(DESTDIR)\lib\afsauthent.lib   \
        $(DESTDIR)\lib\libafsconf.lib   \
         $(DESTDIR)\lib\afs\mtafsutil.lib\
index 5dc0991..db9b725 100644 (file)
@@ -876,7 +876,8 @@ afs_klog(khm_handle identity,
         increds.client = client_principal;
         increds.times.endtime = 0;
         /* Ask for DES since that is what V4 understands */
-        increds.session.keytype = ENCTYPE_DES_CBC_CRC;
+        if (method == AFS_TOKEN_KRB524)
+           increds.session.keytype = ENCTYPE_DES_CBC_CRC;
 
 #ifdef KRB5_TC_NOTICKET
         flags = KRB5_TC_OPENCLOSE;
@@ -1060,9 +1061,11 @@ afs_klog(khm_handle identity,
         atoken.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
         atoken.startTime = k5creds->times.starttime;
         atoken.endTime = k5creds->times.endtime;
-        memcpy(&atoken.sessionKey,
-               k5creds->session.keyvalue.data,
-               k5creds->session.keyvalue.length);
+       if (tkt_DeriveDesKey(k5creds->session.keytype,
+                            k5creds->session.keyvalue.data,
+                            k5creds->session.keyvalue.length,
+                            &atoken.sessionKey))
+           goto cleanup;
         atoken.ticketLen = k5creds->ticket.length;
         memcpy(atoken.ticket, k5creds->ticket.data, atoken.ticketLen);
 
index 9e5b811..b5c0108 100644 (file)
@@ -669,6 +669,8 @@ rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
     char k4inst[INST_SZ];
     char k4realm[REALM_SZ];
 #endif
+    void *inkey = get_cred_keydata(v5cred);
+    size_t inkey_sz = get_cred_keylen(v5cred);
 
     afs_dprintf("Using Kerberos V5 ticket natively\n");
 
@@ -712,8 +714,10 @@ rxkad_build_native_token(krb5_context context, krb5_creds *v5cred,
     token.kvno = RXKAD_TKT_TYPE_KERBEROS_V5;
     token.startTime = v5cred->times.starttime;;
     token.endTime = v5cred->times.endtime;
-    memcpy(&token.sessionKey, get_cred_keydata(v5cred),
-          get_cred_keylen(v5cred));
+    if (tkt_DeriveDesKey(get_creds_enctype(v5cred), inkey, inkey_sz,
+                        &token.sessionKey) != 0) {
+       return RXKADBADKEY;
+    }
     token.ticketLen = v5cred->ticket.length;
     memcpy(token.ticket, v5cred->ticket.data, token.ticketLen);
 
@@ -2124,8 +2128,9 @@ get_credv5(krb5_context context, char *name, char *inst, char *realm,
 
     increds.client = client_principal;
     increds.times.endtime = 0;
-    /* Ask for DES since that is what V4 understands */
-    get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
+    if (do524)
+       /* Ask for DES since that is what V4 understands */
+       get_creds_enctype((&increds)) = ENCTYPE_DES_CBC_CRC;
 
     if (keytab) {
        int allowed_enctypes[] = {
index e73fe57..7cbcba5 100644 (file)
@@ -32,6 +32,8 @@ static int
 stringToType(const char *string) {
     if (strcmp(string, "rxkad") == 0)
        return afsconf_rxkad;
+    if (strcmp(string, "rxkad_krb5") == 0)
+       return afsconf_rxkad_krb5;
 
     return atoi(string);
 }
@@ -103,7 +105,7 @@ keyFromCommandLine(afsconf_keyType type, int kvno, int subType,
 #endif
 
 static struct afsconf_typedKey *
-keyFromKeytab(int kvno, const char *keytab, const char *princ)
+keyFromKeytab(int kvno, afsconf_keyType type, int subtype, const char *keytab, const char *princ)
 {
     int retval;
     krb5_principal principal;
@@ -120,26 +122,38 @@ keyFromKeytab(int kvno, const char *keytab, const char *princ)
        exit(1);
     }
 
-    retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
-                                     kvno, ENCTYPE_DES_CBC_CRC, &key);
-    if (retval == KRB5_KT_NOTFOUND)
-       retval = krb5_kt_read_service_key(context, (char *)keytab,
-                                         principal, kvno,
-                                         ENCTYPE_DES_CBC_MD5, &key);
-    if (retval == KRB5_KT_NOTFOUND)
-       retval = krb5_kt_read_service_key(context, (char *)keytab,
-                                         principal, kvno,
-                                         ENCTYPE_DES_CBC_MD4, &key);
-
+    if (type == afsconf_rxkad) {
+       retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
+                                         kvno, ENCTYPE_DES_CBC_CRC, &key);
+       if (retval == KRB5_KT_NOTFOUND)
+           retval = krb5_kt_read_service_key(context, (char *)keytab,
+                                             principal, kvno,
+                                             ENCTYPE_DES_CBC_MD5, &key);
+       if (retval == KRB5_KT_NOTFOUND)
+           retval = krb5_kt_read_service_key(context, (char *)keytab,
+                                             principal, kvno,
+                                             ENCTYPE_DES_CBC_MD4, &key);
+    } else if (type == afsconf_rxkad_krb5) {
+       retval = krb5_kt_read_service_key(context, (char *)keytab, principal,
+                                         kvno, subtype, &key);
+    } else {
+       retval=AFSCONF_BADKEY;
+    }
     if (retval == KRB5_KT_NOTFOUND) {
        char * princname = NULL;
 
        krb5_unparse_name(context, principal, &princname);
 
-       afs_com_err("asetkey", retval,
-                   "for keytab entry with Principal %s, kvno %u, "
-                   "DES-CBC-CRC/MD5/MD4",
-                   princname ? princname : princ, kvno);
+       if (type == afsconf_rxkad) {
+           afs_com_err("asetkey", retval,
+                       "for keytab entry with Principal %s, kvno %u, "
+                       "DES-CBC-CRC/MD5/MD4",
+                       princname ? princname : princ, kvno);
+       } else {
+           afs_com_err("asetkey", retval,
+                       "for keytab entry with Principal %s, kvno %u",
+                       princname ? princname : princ, kvno);
+       }
        exit(1);
     }
 
@@ -148,7 +162,7 @@ keyFromKeytab(int kvno, const char *keytab, const char *princ)
        exit(1);
     }
 
-    if (deref_key_length(key) != 8) {
+    if (type == afsconf_rxkad && deref_key_length(key) != 8) {
        fprintf(stderr, "Key length should be 8, but is really %u!\n",
                (unsigned int)deref_key_length(key));
        exit(1);
@@ -156,7 +170,7 @@ keyFromKeytab(int kvno, const char *keytab, const char *princ)
 
     rx_opaque_populate(&buffer, deref_key_contents(key), deref_key_length(key));
 
-    typedKey = afsconf_typedKey_new(afsconf_rxkad, kvno, 0, &buffer);
+    typedKey = afsconf_typedKey_new(type, kvno, subtype, &buffer);
     rx_opaque_freeContents(&buffer);
     krb5_free_principal(context, principal);
     krb5_free_keyblock(context, key);
@@ -176,13 +190,27 @@ addKey(struct afsconf_dir *dir, int argc, char **argv) {
                                      argv[3], 8);
        break;
       case 5:
-       typedKey = keyFromKeytab(atoi(argv[2]), argv[3], argv[4]);
+       typedKey = keyFromKeytab(atoi(argv[2]), afsconf_rxkad, 0, argv[3], argv[4]);
        break;
       case 6:
        type = stringToType(argv[2]);
        kvno = atoi(argv[3]);
        if (type == afsconf_rxkad) {
            typedKey = keyFromCommandLine(afsconf_rxkad, kvno, 0, argv[5], 8);
+       } else if (type == afsconf_rxkad_krb5){
+           fprintf(stderr, "Raw keys for afsconf_rxkad_krb5 are unsupported");
+           exit(1);
+       } else {
+           fprintf(stderr, "Unknown key type %s\n", argv[2]);
+           exit(1);
+       }
+       break;
+      case 7:
+       type = stringToType(argv[2]);
+       kvno = atoi(argv[3]);
+       if (type == afsconf_rxkad || type == afsconf_rxkad_krb5) {
+           typedKey = keyFromKeytab(kvno, type, atoi(argv[4]), argv[5],
+                                    argv[6]);
        } else {
            fprintf(stderr, "Unknown key type %s\n", argv[2]);
            exit(1);
@@ -194,6 +222,8 @@ addKey(struct afsconf_dir *dir, int argc, char **argv) {
        fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
        fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
                argv[0]);
+       fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
+               argv[0]);
        fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
                exit(1);
     }
@@ -251,8 +281,15 @@ listKey(struct afsconf_dir *dir, int argc, char **argv)
                printKey(keyMaterial);
            }
            break;
+         case afsconf_rxkad_krb5:
+           if (kvno != -1) {
+               printf("rxkad_krb5\tkvno %4d enctype %d; key is: ",
+                      kvno, minorType);
+               printKey(keyMaterial);
+           }
+           break;
          default:
-           printf("unknown(%d)\tkvno %4d subtype %d key is: ", type,
+           printf("unknown(%d)\tkvno %4d subtype %d; key is: ", type,
                   kvno, minorType);
            printKey(keyMaterial);
            break;
@@ -274,6 +311,8 @@ main(int argc, char *argv[])
        fprintf(stderr, "\tOR\n\t%s add <kvno> <key>\n", argv[0]);
        fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <key>\n",
                argv[0]);
+       fprintf(stderr, "\tOR\n\t%s add <type> <kvno> <subtype> <keyfile> <princ>\n",
+               argv[0]);
        fprintf(stderr, "\t\tEx: %s add 0 \"80b6a7cd7a9dadb6\"\n", argv[0]);
        fprintf(stderr, "\t%s delete <kvno>\n", argv[0]);
        fprintf(stderr, "\t%s list\n", argv[0]);
index 51e5411..933a1a2 100644 (file)
@@ -634,9 +634,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
     for (service = service_temp;;service = "afs") {
         memset(mcred, 0, sizeof *mcred);
         mcred->client = princ;
-        /* Ask for DES since that is what rxkad understands */
-        if (service && !strncmp(service, "afs", 3))
-            get_creds_enctype(mcred) = ENCTYPE_DES_CBC_CRC;
         code = krb5_parse_name(k5context, service, &mcred->server);
         if (code) {
             afs_com_err(rn, code, "Unable to parse service <%s>\n", service);
@@ -680,13 +677,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
        struct ktc_principal aserver[1], aclient[1];
        struct ktc_token atoken[1];
 
-        if (get_cred_keylen(afscred) != sizeof(atoken->sessionKey)) {
-            afs_com_err(rn, 0, "Invalid rxkad key length (%u != 8) key type (%u)",
-                        (unsigned)get_cred_keylen(afscred),
-                        get_creds_enctype(afscred));
-            KLOGEXIT(1);
-        }
-
        memset(atoken, 0, sizeof *atoken);
        if (evil) {
            size_t elen = enc_part->length;
@@ -704,8 +694,15 @@ CommandProc(struct cmd_syndesc *as, void *arock)
        }
        atoken->startTime = afscred->times.starttime;
        atoken->endTime = afscred->times.endtime;
-       memcpy(&atoken->sessionKey, get_cred_keydata(afscred),
-           get_cred_keylen(afscred));
+       if (tkt_DeriveDesKey(get_creds_enctype(afscred),
+                            get_cred_keydata(afscred),
+                            get_cred_keylen(afscred), &atoken->sessionKey)) {
+           afs_com_err(rn, 0,
+                       "Cannot derive DES key from enctype %i of length %u",
+                       get_creds_enctype(afscred),
+                       (unsigned)get_cred_keylen(afscred));
+           KLOGEXIT(1);
+       }
        memcpy(atoken->ticket, enc_part->data,
            atoken->ticketLen = enc_part->length);
        memset(aserver, 0, sizeof *aserver);
index e6001c2..2a2c400 100644 (file)
@@ -29,6 +29,7 @@ LT_libs= $(LDFLAGS_roken) $(LIB_roken)
 
 LIBS=libauth.a \
       ${TOP_LIBDIR}/librxkad.a \
+      ${TOP_LIBDIR}/libafsrfc3961.a \
       ${TOP_LIBDIR}/librx.a \
       ${TOP_LIBDIR}/libsys.a \
       ${TOP_LIBDIR}/liblwp.a \
index 37146e8..0e77e0e 100644 (file)
@@ -99,7 +99,8 @@ EXELIBS =\
        $(EXELIBDIR)\libafsconf.lib \
        $(EXELIBDIR)\opr.lib \
        $(EXELIBDIR)\afshcrypto.lib \
-       $(EXELIBDIR)\afsroken.lib
+       $(EXELIBDIR)\afsroken.lib \
+       $(EXELIBDIR)\afsrfc3961.lib
 
 $(SETKEY_EXEFILE): $(SETKEY_EXEOBJS) $(EXELIBS)
        $(EXECONLINK) dnsapi.lib shell32.lib
index 54e842d..fe54bfd 100644 (file)
@@ -19,6 +19,7 @@
 
 #define HC_DEPRECATED
 #include <hcrypto/des.h>
+#include <hcrypto/rand.h>
 
 #include <rx/rxkad.h>
 #include <rx/rx.h>
@@ -42,6 +43,31 @@ QuickAuth(struct rx_securityClass **astr, afs_int32 *aindex)
 }
 
 #if !defined(UKERNEL)
+static int _afsconf_GetRxkadKrb5Key(void *arock, int kvno, int enctype, void *outkey,
+                                   size_t *keylen)
+{
+    struct afsconf_dir *adir = arock;
+    struct afsconf_typedKey *kobj;
+    struct rx_opaque *keymat;
+    afsconf_keyType tktype;
+    int tkvno, tenctype;
+    int code;
+
+    code = afsconf_GetKeyByTypes(adir, afsconf_rxkad_krb5, kvno, enctype, &kobj);
+    if (code != 0)
+       return code;
+    afsconf_typedKey_values(kobj, &tktype, &tkvno, &tenctype, &keymat);
+    if (*keylen < keymat->len) {
+       afsconf_typedKey_put(&kobj);
+       return AFSCONF_BADKEY;
+    }
+    memcpy(outkey, keymat->val, keymat->len);
+    *keylen = keymat->len;
+    afsconf_typedKey_put(&kobj);
+    return 0;
+}
+
+
 /* Return an appropriate security class and index */
 afs_int32
 afsconf_ServerAuth(void *arock,
@@ -53,7 +79,8 @@ afsconf_ServerAuth(void *arock,
 
     LOCK_GLOBAL_MUTEX;
     tclass = (struct rx_securityClass *)
-       rxkad_NewServerSecurityObject(0, adir, afsconf_GetKey, NULL);
+       rxkad_NewKrb5ServerSecurityObject(0, adir, afsconf_GetKey,
+                                         _afsconf_GetRxkadKrb5Key, NULL);
     if (tclass) {
        *astr = tclass;
        *aindex = RX_SECIDX_KAD;
@@ -72,35 +99,72 @@ GenericAuth(struct afsconf_dir *adir,
            afs_int32 *aindex,
            rxkad_level enclevel)
 {
-    char tbuffer[256];
+#ifdef UKERNEL
+    return QuickAuth(astr, aindex);
+#else
+    int enctype_preflist[]={18, 17, 23, 16, 0};
+    char tbuffer[512];
     struct ktc_encryptionKey key, session;
     struct rx_securityClass *tclass;
     afs_int32 kvno;
     afs_int32 ticketLen;
     afs_int32 code;
+    int use_krb5=0;
+    struct afsconf_typedKey *kobj;
+    struct rx_opaque *keymat;
+    int *et;
 
     /* first, find the right key and kvno to use */
-    code = afsconf_GetLatestKey(adir, &kvno, &key);
-    if (code) {
-       return QuickAuth(astr, aindex);
+
+    et = enctype_preflist;
+    while(*et != 0) {
+       code = afsconf_GetLatestKeyByTypes(adir, afsconf_rxkad_krb5, *et,
+                                          &kobj);
+       if (code == 0) {
+           afsconf_keyType tktype;
+           int tenctype;
+           afsconf_typedKey_values(kobj, &tktype, &kvno, &tenctype, &keymat);
+           RAND_add(keymat->val, keymat->len, 0.0);
+           use_krb5 = 1;
+           break;
+       }
+       et++;
     }
 
-    /* next create random session key, using key for seed to good random */
-    DES_init_random_number_generator((DES_cblock *) &key);
+    if (use_krb5 == 0) {
+       code = afsconf_GetLatestKey(adir, &kvno, &key);
+       if (code) {
+           return QuickAuth(astr, aindex);
+       }
+       /* next create random session key, using key for seed to good random */
+       DES_init_random_number_generator((DES_cblock *) &key);
+    }
     code = DES_new_random_key((DES_cblock *) &session);
     if (code) {
+       if (use_krb5)
+           afsconf_typedKey_put(&kobj);
        return QuickAuth(astr, aindex);
     }
 
-    /* now create the actual ticket */
-    ticketLen = sizeof(tbuffer);
-    memset(tbuffer, '\0', sizeof(tbuffer));
-    code =
-       tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0,
-                      0xffffffff, &session, 0, "afs", "");
-    /* parms were buffer, ticketlen, key to seal ticket with, principal
-     * name, instance and cell, start time, end time, session key to seal
-     * in ticket, inet host, server name and server instance */
+    if (use_krb5) {
+       ticketLen = sizeof(tbuffer);
+       memset(tbuffer, '\0', sizeof(tbuffer));
+       code =
+           tkt_MakeTicket5(tbuffer, &ticketLen, *et, &kvno, keymat->val,
+                           keymat->len, AUTH_SUPERUSER, "", "", 0, 0x7fffffff,
+                           &session, "afs", "");
+       afsconf_typedKey_put(&kobj);
+    } else {
+       /* now create the actual ticket */
+       ticketLen = sizeof(tbuffer);
+       memset(tbuffer, '\0', sizeof(tbuffer));
+       code =
+           tkt_MakeTicket(tbuffer, &ticketLen, &key, AUTH_SUPERUSER, "", "", 0,
+                          0xffffffff, &session, 0, "afs", "");
+       /* parms were buffer, ticketlen, key to seal ticket with, principal
+        * name, instance and cell, start time, end time, session key to seal
+        * in ticket, inet host, server name and server instance */
+    }
     if (code) {
        return QuickAuth(astr, aindex);
     }
@@ -115,6 +179,7 @@ GenericAuth(struct afsconf_dir *adir,
     *astr = tclass;
     *aindex = RX_SECIDX_KAD;
     return 0;
+#endif
 }
 
 /* build a fake ticket for 'afs' using keys from adir, returning an
@@ -254,12 +319,16 @@ afsconf_BuildServerSecurityObjects(void *rock,
 
     (*classes)[0] = rxnull_NewServerSecurityObject();
     (*classes)[1] = NULL;
-    (*classes)[2] = rxkad_NewServerSecurityObject(0, dir,
-                                                 afsconf_GetKey, NULL);
+    (*classes)[2] = rxkad_NewKrb5ServerSecurityObject(0, dir,
+                                                     afsconf_GetKey,
+                                                     _afsconf_GetRxkadKrb5Key,
+                                                     NULL);
 
     if (dir->securityFlags & AFSCONF_SECOPTS_ALWAYSENCRYPT)
-       (*classes)[3] = rxkad_NewServerSecurityObject(rxkad_crypt, dir,
-                                                     afsconf_GetKey, NULL);
+       (*classes)[3] = rxkad_NewKrb5ServerSecurityObject(rxkad_crypt, dir,
+                                                         afsconf_GetKey,
+                                                         _afsconf_GetRxkadKrb5Key,
+                                                         NULL);
 }
 #endif
 
index f22153d..c641fc3 100644 (file)
@@ -150,7 +150,8 @@ struct afsconf_typedKeyList {
 
 typedef enum {
     afsconf_rxkad = 0,
-    afsconf_rxgk  =1
+    afsconf_rxgk  =1,
+    afsconf_rxkad_krb5  =2
 } afsconf_keyType;
 
 extern struct afsconf_typedKey *
index 51cefac..b565d17 100644 (file)
@@ -39,6 +39,7 @@ LIBS=   ${TOP_LIBDIR}/librx.a \
        ${TOP_LIBDIR}/libopr.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libprocmgmt.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 OBJS=bosserver.o bnode.o ezbnodeops.o fsbnodeops.o bosint.ss.o bosint.xdr.o \
index a2ed440..c4c1703 100644 (file)
@@ -70,7 +70,8 @@ BOSSERVER_EXELIBS =\
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(BOSSERVER_EXEFILE): $(BOSSERVER_EXEOBJS) $(BOSSERVER_EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
@@ -109,7 +110,8 @@ BOS_EXELIBS =\
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(RS_BOS_EXEFILE): $(BOS_EXEOBJS) $(BOS_EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
index cb1ad0e..f70369e 100644 (file)
@@ -21,6 +21,7 @@ LIBS=${TOP_LIBDIR}/libbudb.a ${TOP_LIBDIR}/libbubasics.a \
         ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/util.a \
        $(TOP_LIBDIR)/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 all: ${TOP_LIBDIR}/libbxdb.a ${TOP_INCDIR}/afs/bucoord_prototypes.h ${TOP_INCDIR}/afs/bc.h backup
index 3085b95..05db66c 100644 (file)
@@ -93,7 +93,8 @@ EXELIBS =\
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
        
 
 $(EXEFILE): $(EXEOBJS) $(EXERES) $(EXELIBS)
index 2a406f3..1d39793 100644 (file)
@@ -42,6 +42,7 @@ LIBS=${TOP_LIBDIR}/libbubasics.a \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 COMMON_OBJS = database.o db_alloc.o db_dump.o db_hash.o struct_ops.o ol_verify.o
index 5d94741..1d9ecb9 100644 (file)
@@ -81,7 +81,8 @@ EXELIBS =\
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(EXEFILE): $(EXEOBJS)  $(EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
index 1dbe5bf..4648f96 100644 (file)
@@ -41,6 +41,7 @@ LIBS=${TOP_LIBDIR}/libbudb.a \
        ${TOP_LIBDIR}/liblwp.a \
         ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/libafscom_err.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/libusd.a \
        ${TOP_LIBDIR}/util.a \
index e0e0ffb..719333c 100644 (file)
@@ -55,7 +55,8 @@ EXELIBS =\
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(EXERES): butc.rc AFS_component_version_number.h
 
index 43d5de7..9e6ff77 100644 (file)
@@ -40,3 +40,10 @@ EXPORTS
        hc_RAND_add                             @39
        hc_RAND_write_file                      @40
        hc_RAND_bytes                           @41
+       hc_HMAC                                 @42
+       hc_HMAC_CTX_cleanup                     @43
+       hc_HMAC_CTX_init                        @44
+       hc_HMAC_Final                           @45
+       hc_HMAC_Init_ex                         @46
+       hc_HMAC_Update                          @47
+       hc_HMAC_size                            @48
index 27fd7de..edd04cf 100644 (file)
        hc_RAND_file_name;
        hc_RAND_add;
        hc_RAND_write_file;
+       hc_HMAC;
+       hc_HMAC_CTX_cleanup;
+       hc_HMAC_CTX_init;
+       hc_HMAC_Final;
+       hc_HMAC_Init_ex;
+       hc_HMAC_Update;
+       hc_HMAC_size;
     local:
        *;
 };
index fd884b2..5819bd8 100644 (file)
@@ -4,6 +4,9 @@
  * selected bits of Heimdal's libkrb5.
  */
 
+#ifndef RFC3961_RFC3961_H
+#define RFC3961_RFC3961_H
+
 typedef int krb5_error_code;
 typedef int krb5_key_usage;
 typedef struct _krb5_context * krb5_context;
@@ -22,6 +25,7 @@ typedef struct {
 
 typedef struct krb5_crypto_data *krb5_crypto;
 
+#ifndef RFC3961_NO_ENUMS
 typedef enum CKSUMTYPE {
   CKSUMTYPE_NONE = 0,
   CKSUMTYPE_CRC32 = 1,
@@ -42,14 +46,18 @@ typedef enum CKSUMTYPE {
   CKSUMTYPE_HMAC_MD5 = -138,
   CKSUMTYPE_HMAC_MD5_ENC = -1138
 } CKSUMTYPE;
+#endif
 
+#ifndef RFC3961_NO_CKSUM
 typedef struct Checksum {
   CKSUMTYPE cksumtype;
   afs_heim_octet_string checksum;
 } Checksum;
 
 typedef int krb5_cksumtype;
+#endif
 
+#ifndef RFC3961_NO_ENUMS
 typedef enum ENCTYPE {
   ETYPE_NULL = 0,
   ETYPE_DES_CBC_CRC = 1,
@@ -83,6 +91,10 @@ enum {
 
 typedef ENCTYPE krb5_enctype;
 
+#else
+typedef int krb5_enctype;
+#endif
+
 #define krb5_init_context oafs_h_krb5_init_context
 #define krb5_free_context oafs_h_krb5_free_context
 #define krb5_enctype_valid oafs_h_krb5_enctype_valid
@@ -170,6 +182,7 @@ krb5_error_code krb5_random_to_key(krb5_context context,
 size_t krb5_crypto_overhead (krb5_context context,
                             krb5_crypto crypto);
 
+#ifndef RFC3961_NO_CKSUM
 #define krb5_crypto_get_checksum_type oafs_h_krb5_crypto_get_checksum_type
 #define krb5_checksumsize oafs_h_krb5_checksumsize
 #define krb5_create_checksum oafs_h_krb5_create_checksum
@@ -200,6 +213,7 @@ krb5_error_code krb5_verify_checksum (krb5_context context,
 
 
 void free_Checksum(Checksum *data);
+#endif
 
 void krb5_keyblock_zero(krb5_keyblock *keyblock);
 void krb5_free_keyblock_contents(krb5_context context,
@@ -218,3 +232,5 @@ krb5_error_code krb5_keyblock_init(krb5_context context,
                   const void *data,
                   size_t size,
                   krb5_keyblock *key);
+
+#endif /* RFC3961_RFC3961_H */
index c15415a..606f7c9 100644 (file)
@@ -40,6 +40,7 @@ LIBS=${TOP_LIBDIR}/libubik.a \
        ${TOP_LIBDIR}/libkauth.a \
        ${TOP_LIBDIR}/libprot.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${XLIBS}
 
 all: translate_et
index 6b1b9e7..c26d3f2 100644 (file)
@@ -26,6 +26,7 @@ LIBS=${TOP_LIBDIR}/libvolser.a ${TOP_LIBDIR}/vlib.a ${TOP_LIBDIR}/libacl.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 all: ${TOP_INCDIR}/afs/fsprobe.h ${TOP_LIBDIR}/libfsprobe.a fsprobe_test
index b0433d0..1688e6f 100644 (file)
@@ -36,6 +36,7 @@ LIBS=\
        ${TOP_LIBDIR}/libkauth.a \
        ${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/librxkad.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/libopr.a \
        ${TOP_LIBDIR}/util.a
index 54b3849..c325247 100644 (file)
@@ -51,6 +51,7 @@ LIBS=${TOP_LIBDIR}/libubik.a \
        ${TOP_LIBDIR}/libafsutil.a \
        ${TOP_LIBDIR}/libopr.a \
        $(DBM) \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 KLIBS=${TOP_LIBDIR}/libubik.a \
@@ -65,6 +66,7 @@ KLIBS=${TOP_LIBDIR}/libubik.a \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/libafsutil.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 all: liboafs_kauth.la libauthent_kauth.la \
index 6efcb3d..7e3897a 100644 (file)
@@ -95,7 +95,8 @@ AFSLIBS =  \
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 TOKENLIB = $(DESTDIR)\lib\afs\afspioctl.lib
 
index 0fe5c66..8a836c7 100644 (file)
@@ -18,7 +18,8 @@ EXELIBS = \
        $(DESTDIR)\afs\afsprot.lib \
        $(DESTDIR)\afsrx.lib \
        $(DESTDIR)\afs\afscom_err.lib \
-       $(DESTDIR)\afs\afskauth.lib
+       $(DESTDIR)\afs\afskauth.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 
 $(OUT)\multiklog.exe: $(OUT)\multiklog.obj
index 78ba93e..95ad027 100644 (file)
@@ -13,6 +13,7 @@ LT_objs = \
        $(top_builddir)/src/fsint/libafsrpc_fsint.la \
        $(top_builddir)/src/rx/libafsrpc_rx.la \
        $(top_builddir)/src/rxkad/libafsrpc_rxkad.la \
+       $(top_builddir)/src/crypto/rfc3961/libafsrpc_rfc3961.la \
        $(top_builddir)/src/comerr/libafsrpc_comerr.la \
        $(top_builddir)/src/util/libafsrpc_util.la \
        $(top_builddir)/src/rxstat/libafsrpc_rxstat.la \
index 732cd18..c5fece3 100644 (file)
@@ -94,6 +94,7 @@ DLLLIBS =\
        $(DESTDIR)\lib\afs\afsreg.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib \
        $(DESTDIR)\lib\afsroken.lib
 
 $(LIBFILE): $(DLLOBJS) $(DLLLIBS)
index 8c6bedd..d7beb72 100755 (executable)
@@ -340,6 +340,9 @@ EXPORTS
        initialize_RXK_error_table              @345
        rx_GetNetworkError                      @346
         afs_set_com_err_hook                    @347
+       rxkad_NewKrb5ServerSecurityObject       @348
+       tkt_MakeTicket5                         @349
+       tkt_DeriveDesKey                        @350
 
 ; for performance testing
         rx_TSFPQGlobSize                        @2001 DATA
index b1858a9..7636116 100644 (file)
@@ -153,6 +153,7 @@ rxi_RoundUpPacket
 rxi_SetCallNumberVector
 rxkad_GetServerInfo
 rxkad_NewClientSecurityObject
+rxkad_NewKrb5ServerSecurityObject
 rxkad_NewServerSecurityObject
 rxkad_global_stats
 rxkad_global_stats_lock
@@ -163,7 +164,9 @@ rxs_Release
 time_to_life
 tkt_CheckTimes
 tkt_DecodeTicket
+tkt_DeriveDesKey
 tkt_MakeTicket
+tkt_MakeTicket5
 xdr_afsUUID
 xdr_afs_int32
 xdr_afs_int64
index 49a48c3..cdc6397 100644 (file)
@@ -22,6 +22,7 @@ LIBRARIES=${TOP_LIBDIR}/libauth.a \
                ${TOP_LIBDIR}/libsys.a \
                ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
                ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libopr.a \
+               ${TOP_LIBDIR}/libafsrfc3961.a \
                ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 KLIBRARIES=${TOP_LIBDIR}/libauth.krb.a \
@@ -30,6 +31,7 @@ KLIBRARIES=${TOP_LIBDIR}/libauth.krb.a \
                ${TOP_LIBDIR}/libsys.a \
                ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libcmd.a \
                ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libopr.a \
+               ${TOP_LIBDIR}/libafsrfc3961.a \
                ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 #
index 3d018e8..dee4513 100644 (file)
@@ -41,6 +41,7 @@ LIBS=   ${TOP_LIBDIR}/libubik.a \
        ${TOP_LIBDIR}/libaudit.a \
        ${TOP_LIBDIR}/libafsutil.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 LT_objs = ptuser.lo pterror.lo ptint.cs.lo ptint.xdr.lo display.lo
index bc5846e..709bd44 100644 (file)
@@ -73,7 +73,8 @@ PTSERVER_EXELIBS =\
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 !IF (("$(SYS_NAME)"!="i386_win95" ) && ("$(SYS_NAME)"!="I386_WIN95" ))
 PTSERVER_EXELIBS =$(PTSERVER_EXELIBS) $(DESTDIR)\lib\afs\afsprocmgmt.lib
@@ -126,7 +127,8 @@ PTS_EXELIBS =\
        $(DESTDIR)\lib\libafsconf.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(PTS): $(PTS_EXEOBJS) $(PTS_EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
index 31ba16e..4300d6a 100644 (file)
@@ -23,7 +23,8 @@ LT_objs=rxkad_client.lo rxkad_server.lo rxkad_common.lo rxkad_errs.lo \
 
 LT_deps=$(top_builddir)/src/comerr/liboafs_comerr.la \
        $(top_builddir)/src/rx/liboafs_rx.la \
-       $(top_builddir)/src/opr/liboafs_opr.la
+       $(top_builddir)/src/opr/liboafs_opr.la \
+       $(top_builddir)/src/crypto/rfc3961/liboafs_rfc3961.la
 
 LT_libs=$(LDFLAGS_hcrypto) $(LIB_hcrypto)
 
index 7590599..cfcc585 100644 (file)
@@ -2,7 +2,10 @@ initialize_RXK_error_table
 life_to_time
 rxkad_GetServerInfo
 rxkad_NewClientSecurityObject
+rxkad_NewKrb5ServerSecurityObject
 rxkad_NewServerSecurityObject
 time_to_life
 tkt_CheckTimes
+tkt_DeriveDesKey
 tkt_MakeTicket
+tkt_MakeTicket5
index a26c603..fc4ccf6 100644 (file)
@@ -78,6 +78,7 @@ struct rxkad_sprivate {
     int (*get_key) (void *, int,
                    struct ktc_encryptionKey *);
                                /* func. of kvno and server key ptr */
+    rxkad_get_key_enctype_func get_key_enctype;
     int (*user_ok) (char *, char *,
                    char *, afs_int32);
                                /* func called with new client name */
index 55cfcfa..141f534 100644 (file)
@@ -91,6 +91,10 @@ typedef signed char rxkad_level;
 
 
 extern int rxkad_EpochWasSet;  /* TRUE => we called rx_SetEpoch */
+/* Get key by enctype.  Takes a rock (path to conf dir), kvno and enctype as
+ * input and returns the key and key length.  On input, the keylength parameter
+ * must be set to the length of storage allocated by the caller. */
+typedef int (*rxkad_get_key_enctype_func) (void *, int, int, void *, size_t *);
 
 #include <rx/rxkad_prototypes.h>
 
index 9fa059f..a13c9fe 100644 (file)
@@ -106,6 +106,12 @@ extern struct rx_securityClass *rxkad_NewServerSecurityObject(rxkad_level
                                                               char *cell,
                                                               afs_int32
                                                               kvno));
+extern struct rx_securityClass *rxkad_NewKrb5ServerSecurityObject
+(rxkad_level level, void *get_key_rock,
+ int (*get_key) (void *get_key_rock, int kvno,
+                struct ktc_encryptionKey *serverKey),
+ rxkad_get_key_enctype_func get_key_enctype,
+ int (*user_ok) (char *name, char *instance, char *cell, afs_int32 kvno));
 extern int rxkad_CheckAuthentication(struct rx_securityClass *aobj,
                                     struct rx_connection *aconn);
 extern int rxkad_CreateChallenge(struct rx_securityClass *aobj,
@@ -151,9 +157,21 @@ extern afs_uint32 _rxkad_crc_update(const char *p, size_t len, afs_uint32 res);
 extern int tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
                             int (*get_key) (void *, int,
                                             struct ktc_encryptionKey *),
+                            rxkad_get_key_enctype_func get_key2,
                             char *get_key_rock, int serv_kvno, char *name,
                             char *inst, char *cell, struct ktc_encryptionKey *session_key,
                             afs_int32 * host, afs_uint32 * start,
                             afs_uint32 * end, afs_int32 disableDotCheck);
+extern int tkt_MakeTicket5(char *ticket, int *ticketLen, int enctype, int *kvno,
+                          void *key, size_t keylen,
+                          char *name, char *inst, char *cell, afs_uint32 start,
+                          afs_uint32 end, struct ktc_encryptionKey *sessionKey,
+                          char *sname, char *sinst);
+/*
+ * Compute a des key from a key of a semi-arbitrary kerberos 5 enctype.
+ * Modifies keydata if enctype is 3des.
+ */
+extern int tkt_DeriveDesKey(int enctype, void *keydata, size_t keylen, struct ktc_encryptionKey
+                           *output);
 
 #endif
index be0abef..07e806b 100644 (file)
@@ -165,6 +165,23 @@ rxkad_NewServerSecurityObject(rxkad_level level, void *get_key_rock,
     return tsc;
 }
 
+struct rx_securityClass *
+rxkad_NewKrb5ServerSecurityObject(rxkad_level level, void *get_key_rock,
+                                 int (*get_key) (void *get_key_rock, int kvno,
+                                                 struct ktc_encryptionKey *
+                                                 serverKey),
+                                 rxkad_get_key_enctype_func get_key_enctype,
+                                 int (*user_ok) (char *name, char *instance,
+                                                 char *cell, afs_int32 kvno)
+) {
+    struct rx_securityClass *tsc;
+    struct rxkad_sprivate *tsp;
+    tsc = rxkad_NewServerSecurityObject(level, get_key_rock, get_key, user_ok);
+    tsp = (struct rxkad_sprivate *)tsc->privateData;
+    tsp->get_key_enctype = get_key_enctype;
+    return tsc;
+}
+
 /* server: called to tell if a connection authenticated properly */
 
 int
@@ -325,8 +342,9 @@ rxkad_CheckResponse(struct rx_securityClass *aobj,
     if (code == -1 && ((kvno == RXKAD_TKT_TYPE_KERBEROS_V5)
        || (kvno == RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY))) {
        code =
-           tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_rock,
-                             kvno, client.name, client.instance, client.cell,
+           tkt_DecodeTicket5(tix, tlen, tsp->get_key, tsp->get_key_enctype,
+                             tsp->get_key_rock, kvno, client.name,
+                             client.instance, client.cell,
                              &sessionkey, &host, &start, &end,
                              tsp->flags & RXS_CONFIG_FLAGS_DISABLE_DOTCHECK);
        if (code)
index f0e830c..f875cd0 100644 (file)
 #include <rx/xdr.h>
 #include <rx/rx.h>
 
+#define HC_DEPRECATED_CRYPTO
 #include <hcrypto/md4.h>
 #include <hcrypto/md5.h>
 #include <hcrypto/des.h>
+#include <hcrypto/hmac.h>
 
 #include "lifetimes.h"
 #include "rxkad.h"
 #include "v5der.c"
 #include "v5gen.c"
 
+#define RFC3961_NO_ENUMS
+#define RFC3961_NO_CKSUM
+#include <afs/rfc3961.h>
+
 /*
  * Principal conversion Taken from src/lib/krb5/krb/conv_princ from MIT Kerberos.  If you
  * find a need to change the services here, please consider opening a
@@ -169,19 +175,26 @@ static const struct krb_convert sconv_list[] = {
 static int
   krb5_des_decrypt(struct ktc_encryptionKey *, int, void *, size_t, void *,
                   size_t *);
-
-
-
+static int rxkad_derive_des_key(const void *, size_t,
+                               struct ktc_encryptionKey *);
+static int compress_parity_bits(void *, size_t *);
 
 int
 tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
                  int (*get_key) (void *, int, struct ktc_encryptionKey *),
+                 rxkad_get_key_enctype_func get_key_enctype,
                  char *get_key_rock, int serv_kvno, char *name, char *inst,
                  char *cell, struct ktc_encryptionKey *session_key, afs_int32 * host,
                  afs_uint32 * start, afs_uint32 * end, afs_int32 disableCheckdot)
 {
     char plain[MAXKRB5TICKETLEN];
     struct ktc_encryptionKey serv_key;
+    void *keybuf;
+    size_t keysize, allocsiz;
+    krb5_context context;
+    krb5_keyblock k;
+    krb5_crypto cr;
+    krb5_data plaindata;
     Ticket t5;                 /* Must free */
     EncTicketPart decr_part;   /* Must free */
     int code;
@@ -224,25 +237,82 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
     case ETYPE_DES_CBC_CRC:
     case ETYPE_DES_CBC_MD4:
     case ETYPE_DES_CBC_MD5:
+       /* check ticket */
+       if (t5.enc_part.cipher.length > sizeof(plain)
+           || t5.enc_part.cipher.length % 8 != 0)
+           goto bad_ticket;
+
+       code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key);
+       if (code)
+           goto unknown_key;
+
+       /* Decrypt data here, save in plain, assume it will shrink */
+       code =
+           krb5_des_decrypt(&serv_key, t5.enc_part.etype,
+                            t5.enc_part.cipher.data, t5.enc_part.cipher.length,
+                            plain, &plainsiz);
        break;
     default:
-       goto unknown_key;
+       if (get_key_enctype == NULL)
+           goto unknown_key;
+       code = krb5_init_context(&context);
+       if (code != 0)
+           goto unknown_key;
+       code = krb5_enctype_valid(context, t5.enc_part.etype);
+       if (code != 0) {
+           krb5_free_context(context);
+           goto unknown_key;
+       }
+       code = krb5_enctype_keybits(context,  t5.enc_part.etype, &keysize);
+       if (code != 0) {
+           krb5_free_context(context);
+           goto unknown_key;
+       }
+       keysize = keysize / 8;
+       allocsiz = keysize;
+       keybuf = rxi_Alloc(allocsiz);
+       /* this is not quite a hole for afsconf_GetKeyByTypes. A wrapper
+          that calls afsconf_GetKeyByTypes and afsconf_typedKey_values
+          is needed */
+       code = get_key_enctype(get_key_rock, v5_serv_kvno, t5.enc_part.etype,
+                              keybuf, &keysize);
+       if (code) {
+           rxi_Free(keybuf, allocsiz);
+           krb5_free_context(context);
+           goto unknown_key;
+       }
+       code = krb5_keyblock_init(context, t5.enc_part.etype,
+                                 keybuf, keysize, &k);
+       rxi_Free(keybuf, allocsiz);
+       if (code != 0) {
+           krb5_free_context(context);
+           goto unknown_key;
+       }
+       code = krb5_crypto_init(context, &k, t5.enc_part.etype, &cr);
+       krb5_free_keyblock_contents(context, &k);
+       if (code != 0) {
+           krb5_free_context(context);
+           goto unknown_key;
+       }
+#ifndef KRB5_KU_TICKET
+#define KRB5_KU_TICKET 2
+#endif
+       code = krb5_decrypt(context, cr, KRB5_KU_TICKET, t5.enc_part.cipher.data,
+                           t5.enc_part.cipher.length, &plaindata);
+       krb5_crypto_destroy(context, cr);
+       if (code == 0) {
+           if (plaindata.length > MAXKRB5TICKETLEN) {
+               krb5_data_free(&plaindata);
+               krb5_free_context(context);
+               goto bad_ticket;
+           }
+           memcpy(plain, plaindata.data, plaindata.length);
+           plainsiz = plaindata.length;
+           krb5_data_free(&plaindata);
+       }
+       krb5_free_context(context);
     }
 
-    /* check ticket */
-    if (t5.enc_part.cipher.length > sizeof(plain)
-       || t5.enc_part.cipher.length % 8 != 0)
-       goto bad_ticket;
-
-    code = (*get_key) (get_key_rock, v5_serv_kvno, &serv_key);
-    if (code)
-       goto unknown_key;
-
-    /* Decrypt data here, save in plain, assume it will shrink */
-    code =
-       krb5_des_decrypt(&serv_key, t5.enc_part.etype,
-                        t5.enc_part.cipher.data, t5.enc_part.cipher.length,
-                        plain, &plainsiz);
     if (code != 0)
        goto bad_ticket;
 
@@ -306,21 +376,9 @@ tkt_DecodeTicket5(char *ticket, afs_int32 ticket_len,
     }
 
     /* Verify that decr_part.key is of right type */
-    switch (decr_part.key.keytype) {
-    case ETYPE_DES_CBC_CRC:
-    case ETYPE_DES_CBC_MD4:
-    case ETYPE_DES_CBC_MD5:
-       break;
-    default:
+    if (tkt_DeriveDesKey(decr_part.key.keytype, decr_part.key.keyvalue.data,
+                        decr_part.key.keyvalue.length, session_key) != 0)
        goto bad_ticket;
-    }
-
-    if (decr_part.key.keyvalue.length != 8)
-       goto bad_ticket;
-
-    /* Extract session key */
-    memcpy(session_key, decr_part.key.keyvalue.data, 8);
-
     /* Check lifetimes and host addresses, flags etc */
     {
        time_t now = time(0);   /* Use fast time package instead??? */
@@ -468,3 +526,232 @@ krb5_des_decrypt(struct ktc_encryptionKey *key, int etype, void *in,
 
     return ret;
 }
+
+int
+tkt_MakeTicket5(char *ticket, int *ticketLen, int enctype, int *kvno,
+               void *key, size_t keylen,
+               char *name, char *inst, char *cell, afs_uint32 start,
+               afs_uint32 end, struct ktc_encryptionKey *sessionKey,
+               char *sname, char *sinst)
+{
+    EncTicketPart data;
+    EncryptedData encdata;
+    char *buf, *encodebuf;
+    size_t encodelen, allocsiz;
+    heim_general_string carray[2];
+    int code;
+    krb5_context context;
+    krb5_keyblock kb;
+    krb5_crypto cr;
+    krb5_data encrypted;
+    size_t tl;
+
+    memset(&encrypted, 0, sizeof(encrypted));
+    cr = NULL;
+    context = NULL;
+    buf = NULL;
+    memset(&kb, 0, sizeof(kb));
+    memset(&data, 0, sizeof(data));
+
+    data.flags.transited_policy_checked = 1;
+    data.key.keytype=ETYPE_DES_CBC_CRC;
+    data.key.keyvalue.data=sessionKey->data;
+    data.key.keyvalue.length=8;
+    data.crealm=cell;
+    carray[0]=name;
+    carray[1]=inst;
+    data.cname.name_type=KRB5_NT_PRINCIPAL;
+    data.cname.name_string.val=carray;
+    data.cname.name_string.len=inst[0]?2:1;
+    data.authtime=start;
+    data.endtime=end;
+
+    allocsiz = length_EncTicketPart(&data);
+    buf = rxi_Alloc(allocsiz);
+    encodelen = allocsiz;
+    /* encode function wants pointer to end of buffer */
+    encodebuf = buf + allocsiz - 1;
+    code = encode_EncTicketPart(encodebuf, allocsiz, &data, &encodelen);
+
+    if (code)
+       goto cleanup;
+    code = krb5_init_context(&context);
+    if (code)
+       goto cleanup;
+    code = krb5_keyblock_init(context, enctype, key, keylen, &kb);
+    if (code)
+       goto cleanup;
+    code = krb5_crypto_init(context, &kb, enctype, &cr);
+    if (code)
+       goto cleanup;
+    code = krb5_encrypt(context, cr, KRB5_KU_TICKET, buf,
+                       encodelen, &encrypted);
+    if (code)
+       goto cleanup;
+    memset(&encdata, 0, sizeof(encdata));
+    encdata.etype=enctype;
+    encdata.kvno=kvno;
+    encdata.cipher.data=encrypted.data;
+    encdata.cipher.length=encrypted.length;
+
+    if (length_EncryptedData(&encdata) > *ticketLen) {
+       code = RXKADTICKETLEN;
+       goto cleanup;
+    }
+    tl=*ticketLen;
+    code = encode_EncryptedData(ticket + *ticketLen - 1, *ticketLen, &encdata, &tl);
+    if (code == 0) {
+       *kvno=RXKAD_TKT_TYPE_KERBEROS_V5_ENCPART_ONLY;
+       /*
+        * encode function fills in from the end. move data to
+        * beginning of buffer
+        */
+       memmove(ticket, ticket + *ticketLen - tl, tl);
+       *ticketLen=tl;
+    }
+
+cleanup:
+    krb5_data_free(&encrypted);
+    if (cr != NULL)
+       krb5_crypto_destroy(context, cr);
+    krb5_free_keyblock_contents(context, &kb);
+    krb5_free_context(context);
+    rxi_Free(buf, allocsiz);
+    if ((code && 0xFFFFFF00) == ERROR_TABLE_BASE_asn1)
+       return RXKADINCONSISTENCY;
+    return code;
+}
+
+/*
+ * Use NIST SP800-108 with HMAC(MD5) in counter mode as the PRF to derive a
+ * des key from another type of key.
+ *
+ * L is 64, as we take 64 random bits and turn them into a 56-bit des key.
+ * The output of hmac_md5 is 128 bits; we take the first 64 only, so n
+ * properly should be 1.  However, we apply a slight variation due to the
+ * possibility of producing a weak des key.  If the output key is weak, do NOT
+ * simply correct it, instead, the counter is advanced and the next output
+ * used.  As such, we code so as to have n be the full 255 permitted by our
+ * encoding of the counter i in an 8-bit field.  L itself is encoded as a
+ * 32-bit field, big-endian.  We use the constant string "rxkad" as a label
+ * for this key derivation, the standard NUL byte separator, and omit a
+ * key-derivation context.  The input key is unique to the krb5 service ticket,
+ * which is unlikely to be used in an other location.  If it is used in such
+ * a fashion, both locations will derive the same des key from the PRF, but
+ * this is no different from if a krb5 des key had been used in the same way,
+ * as traditional krb5 rxkad uses the ticket session key directly as the token
+ * key.
+ */
+static int
+rxkad_derive_des_key(const void *in, size_t insize,
+                    struct ktc_encryptionKey *out)
+{
+    unsigned char i;
+    char Lbuf[4];              /* bits of output, as 32 bit word, MSB first */
+    char tmp[64];              /* only needs to be 16 for md5, but lets be sure it fits */
+    unsigned int mdsize;
+    DES_cblock ktmp;
+    HMAC_CTX mctx;
+
+    Lbuf[0] = 0;
+    Lbuf[1] = 0;
+    Lbuf[2] = 0;
+    Lbuf[3] = 64;
+
+    /* stop when 8 bit counter wraps to 0 */
+    for (i = 1; i; i++) {
+       HMAC_CTX_init(&mctx);
+       HMAC_Init_ex(&mctx, in, insize, EVP_md5(), NULL);
+       HMAC_Update(&mctx, &i, 1);
+       HMAC_Update(&mctx, "rxkad", strlen("rxkad") + 1);   /* includes label and separator */
+       HMAC_Update(&mctx, Lbuf, 4);
+       mdsize = sizeof(tmp);
+       HMAC_Final(&mctx, tmp, &mdsize);
+       memcpy(ktmp, tmp, 8);
+       DES_set_odd_parity(&ktmp);
+       if (!DES_is_weak_key(&ktmp)) {
+           memcpy(out->data, ktmp, 8);
+           return 0;
+       }
+    }
+    return -1;
+}
+
+/*
+ * This is the inverse of the random-to-key for 3des specified in
+ * rfc3961, converting blocks of 8 bytes to blocks of 7 bytes by distributing
+ * the bits of each 8th byte as the lsb of the previous 7 bytes.
+ */
+static int
+compress_parity_bits(void *buffer, size_t *bufsiz)
+{
+    unsigned char *cb, tmp;
+    int i, j, nk;
+
+    if (*bufsiz % 8 != 0)
+       return 1;
+    cb = (unsigned char *)buffer;
+    nk = *bufsiz / 8;
+    for (i = 0; i < nk; i++) {
+       tmp = cb[8 * i + 7] >> 1;
+       for (j = 0; j < 7; j++) {
+           cb[8 * i + j] &= 0xfe;
+           cb[8 * i + j] |= tmp & 0x1;
+           tmp >>= 1;
+       }
+    }
+    for (i = 1; i < nk; i++)
+       memmove(cb + 7 * i, cb + 8 * i, 7);
+    *bufsiz = 7 * nk;
+    return 0;
+}
+
+/*
+ * Enctype-specific knowledge about how to derive a des key from a given
+ * key.  If given a des key, use it directly; otherwise, perform any
+ * parity fixup that may be needed and pass through to the hmad-md5 bits.
+ */
+int
+tkt_DeriveDesKey(int enctype, void *keydata, size_t keylen,
+                struct ktc_encryptionKey *output)
+{
+    switch (enctype) {
+    case ETYPE_DES_CBC_CRC:
+    case ETYPE_DES_CBC_MD4:
+    case ETYPE_DES_CBC_MD5:
+       if (keylen != 8)
+           return 1;
+
+       /* Extract session key */
+       memcpy(output, keydata, 8);
+       break;
+    case ETYPE_NULL:
+    case 4:
+    case 6:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
+    case 13:
+    case 14:
+    case 15:
+       return 1;
+       /*In order to become a "Cryptographic Key" as specified in
+        * SP800-108, it must be indistinguishable from a random bitstring. */
+    case ETYPE_DES3_CBC_MD5:
+    case ETYPE_OLD_DES3_CBC_SHA1:
+    case ETYPE_DES3_CBC_SHA1:
+       if (compress_parity_bits(keydata, &keylen))
+           return 1;
+       /* FALLTHROUGH */
+    default:
+       if (enctype < 0)
+           return 1;
+       if (keylen < 7)
+           return 1;
+       if (rxkad_derive_des_key(keydata, keylen, output) != 0)
+           return 1;
+    }
+    return 0;
+}
index 53e8b2d..d7708cd 100644 (file)
@@ -43,6 +43,7 @@ LIBS=${TOP_LIBDIR}/libgtx.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 all: scout
index 5c55120..5d36ea1 100644 (file)
@@ -25,6 +25,7 @@ AFSLIBS=${TOP_LIBDIR}/libkauth.a \
        ${TOP_LIBDIR}/librxkad.a \
        ${TOP_LIBDIR}/libsys.a \
        ${LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${LIBDIR}/liblwp.a \
         ${TOP_LIBDIR}/libcmd.a \
@@ -38,6 +39,7 @@ KAFSLIBS=${TOP_LIBDIR}/libkauth.krb.a \
        ${TOP_LIBDIR}/librxkad.a \
        ${TOP_LIBDIR}/libsys.a \
        ${LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${LIBDIR}/liblwp.a \
         ${TOP_LIBDIR}/libcmd.a \
index ee134fa..3c991f3 100644 (file)
@@ -83,7 +83,8 @@ BUTCLIBS=$(DESTDIR)\lib\afs\afsbudb.lib  \
             $(DESTDIR)\lib\libafsconf.lib \
             $(DESTDIR)\lib\opr.lib \
             $(DESTDIR)\lib\afshcrypto.lib \
-            $(DESTDIR)\lib\afsroken.lib
+            $(DESTDIR)\lib\afsroken.lib \
+            $(DESTDIR)\lib\afsrfc3961.lib
 
 # rm $(OUT)\tcstatus.obj
 # nmake /nologo /f ntmakefile install
index c9a82f5..c7d3e0c 100644 (file)
@@ -11,7 +11,7 @@ SYS_LIBS      = ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a $
 
 AUTH_LIBS      = ${TOP_LIBDIR}/libauth.a ${SYS_LIBS}
 
-INT_LIBS       = ${TOP_LIBDIR}/libafsint.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libafscom_err.a ${TOP_LIBDIR}/util.a
+INT_LIBS       = ${TOP_LIBDIR}/libafsint.a ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/librxkad.a ${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libafscom_err.a ${TOP_LIBDIR}/util.a ${TOP_LIBDIR}/libafsrfc3961.a
 
 TEST_PROGRAMS = write-ro-file hello-world read-vs-mmap read-vs-mmap2    \
                mmap-and-read large-dir large-dir2 large-dir3 mountpoint \
index f535923..6ccfd7d 100644 (file)
@@ -95,7 +95,8 @@ PTSERVER_EXELIBS =\
        $(DESTDIR)\lib\libafsconf.lib \
         $(DESTDIR)\lib\afs\afspioctl.lib \
         $(DESTDIR)\lib\afs\afsprocmgmt.lib \
-        $(DESTDIR)\lib\afspthread.lib
+        $(DESTDIR)\lib\afspthread.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(PTSERVER): $(PTSERVER_EXEOBJS) $(PTUTILS_OBJ) $(PTINT_XDR_OBJ) $(UTILS_OBJ) $(MAP_OBJ) $(LWP_OBJS) $(PTSERVER_EXERES) $(RXKADOBJS) $(PTSERVER_EXELIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
index a524901..a88a2e7 100644 (file)
@@ -18,6 +18,7 @@ AFSLIBS = \
                ${TOP_LIBDIR}/libauth.a \
                ${TOP_LIBDIR}/librxkad.a \
                ${TOP_LIBDIR}/libsys.a \
+               ${TOP_LIBDIR}/libafsrfc3961.a \
                ${TOP_LIBDIR}/libafshcrypto_lwp.a \
                ${TOP_LIBDIR}/librx.a \
                ${TOP_LIBDIR}/liblwp.a \
index 96fb5d1..2dd023d 100644 (file)
@@ -19,6 +19,7 @@ LIBS=${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 all: upserver upclient
index 5577e64..2f6f9e7 100644 (file)
@@ -25,7 +25,8 @@ LIBS = \
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 ############################################################################
 # Definitions for generating files via RXGEN
index 0fe7867..250aa3f 100644 (file)
@@ -30,6 +30,7 @@ LIBS=${TOP_LIBDIR}/libvolser.a \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 OBJS =  uss_procs.o \
index c78a80e..7eb6aed 100644 (file)
@@ -47,6 +47,7 @@ FSLIBS=${TOP_LIBDIR}/libsys.a \
         ${TOP_LIBDIR}/libaudit.a \
         $(TOP_LIBDIR)/libafsutil.a \
         $(TOP_LIBDIR)/libopr.a \
+        ${TOP_LIBDIR}/libafsrfc3961.a \
         ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 CMLIBS=${TOP_LIBDIR}/libsys.a \
index 3c0b782..72aa02d 100644 (file)
@@ -82,7 +82,8 @@ EXELIBS = \
         $(DESTDIR)\lib\afs\mtafsdir.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afspthread.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(EXEFILE): $(EXEOBJS) $(EXELIBS)
        $(EXECONLINK)
index d2ac689..13957e4 100644 (file)
@@ -35,6 +35,7 @@ LIBS=\
        ${TOP_LIBDIR}/libaudit.a \
        ${TOP_LIBDIR}/libafsutil.a \
        $(TOP_LIBDIR)/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 LT_objs = vldbint.xdr.lo vldbint.cs.lo vl_errors.lo
index fc28ef9..d097ab5 100644 (file)
@@ -92,7 +92,8 @@ VLSERVER_EXECLIBS = \
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 $(VLSERVER): $(VLSERVER_EXEOBJS) $(LIBFILE) $(VLSERVER_EXECLIBS)
        $(EXECONLINK) dnsapi.lib mpr.lib iphlpapi.lib shell32.lib
index 87f4dd4..4066959 100644 (file)
@@ -42,6 +42,7 @@ LIBS=\
        ${TOP_LIBDIR}/libusd.a \
        ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libopr.a \
+       ${TOP_LIBDIR}/libafsrfc3961.a \
        ${TOP_LIBDIR}/libafshcrypto_lwp.a
 
 VOLDUMP_LIBS = \
index 8622554..e134b62 100644 (file)
@@ -75,7 +75,8 @@ EXEC_LIBS = \
         $(DESTDIR)\lib\afs\afspioctl.lib \
        $(DESTDIR)\lib\opr.lib \
        $(DESTDIR)\lib\afshcrypto.lib \
-       $(DESTDIR)\lib\afsroken.lib
+       $(DESTDIR)\lib\afsroken.lib \
+       $(DESTDIR)\lib\afsrfc3961.lib
 
 
 ############################################################################