#define HC_DEPRECATED
#include <hcrypto/des.h>
+#include <hcrypto/rand.h>
#include <rx/rxkad.h>
#include <rx/rx.h>
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);
}
*astr = tclass;
*aindex = RX_SECIDX_KAD;
return 0;
+#endif
}
/* build a fake ticket for 'afs' using keys from adir, returning an
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;
+}