#include <afsconfig.h>
#if defined(UKERNEL)
-#include "../afs/param.h"
+#include "afs/param.h"
#else
#include <afs/param.h>
#endif
RCSID("$Header$");
#if defined(UKERNEL)
-#include "../afs/sysincludes.h"
-#include "../afs/afsincludes.h"
-#include "../afs/stds.h"
-#include "../rx/xdr.h"
-#include "../rx/rx.h"
-#include "../des/des.h"
-#include "../afs/lifetimes.h"
-#include "../afs/rxkad.h"
+#include "afs/sysincludes.h"
+#include "afsincludes.h"
+#include "afs/stds.h"
+#include "rx/xdr.h"
+#include "rx/rx.h"
+#include "des/des.h"
+#include "rxkad/lifetimes.h"
+#include "rx/rxkad.h"
#else /* defined(UKERNEL) */
#include <afs/stds.h>
#include <sys/types.h>
#include "rxkad.h"
#endif /* defined(UKERNEL) */
-/* static prototypes */
+/* This union is used to insure we allocate enough space for a key
+ * schedule even if we are linked against a library that uses OpenSSL's
+ * larger representation. This is necessary so we don't lose if an
+ * application uses both rxkad and openssl.
+ */
+union Key_schedule_safe {
+ Key_schedule schedule;
+ struct {
+ union {
+ char cblock[8];
+ long deslong[2];
+ } ks;
+ int weak_key;
+ } openssl_schedule[16];
+};
+
+#define getstr(name,min) \
+ slen = strlen(ticket); \
+ if ((slen < min) || (slen >= MAXKTCNAMELEN)) return -1; \
+ strcpy (name, ticket); \
+ ticket += slen+1
+
static int decode_athena_ticket (char *ticket, int ticketLen, char *name,
- char *inst, char *realm, afs_int32 *host, struct ktc_encryptionKey *sessionKey,
- afs_uint32 *start, afs_uint32 *end);
-static int assemble_athena_ticket (char *ticket, int *ticketLen, char *name,
- char *inst, char *realm, afs_int32 host, struct ktc_encryptionKey *sessionKey,
- afs_uint32 start, afs_uint32 end, char *sname, char *sinst);
+ char *inst, char *realm, afs_int32 *host, struct ktc_encryptionKey *sessionKey,
+ afs_uint32 *start, afs_uint32 *end)
+{ char *ticketBeg = ticket;
+ char flags;
+ int slen;
+ int tlen;
+ unsigned char lifetime;
+ char sname[MAXKTCNAMELEN]; /* these aren't used, */
+ char sinst[MAXKTCNAMELEN]; /* but are in the ticket */
+
+ flags = *ticket++;
+ getstr (name, 1);
+ getstr (inst, 0);
+ getstr (realm, 0);
+
+ memcpy(host, ticket, sizeof (*host));
+ ticket += sizeof(*host);
+ *host = ktohl (flags, *host);
+
+ memcpy(sessionKey, ticket, sizeof (struct ktc_encryptionKey));
+ ticket += sizeof (struct ktc_encryptionKey);
+
+ lifetime = *ticket++;
+ memcpy(start, ticket, sizeof (*start));
+ ticket += sizeof(*start);
+ *start = ktohl (flags, *start);
+ *end = life_to_time (*start, lifetime);
-#define ANDREWFLAGSVALUE (0x80)
-#define TICKET_LABEL "TicketEnd"
+ getstr (sname, 1);
+ getstr (sinst, 0);
+
+ tlen = ticket - ticketBeg;
+ if ((round_up_to_ebs(tlen) != ticketLen) && (ticketLen != 56)) return -1;
+ return 0;
+}
/* This is called to interpret a ticket. It is assumed that the necessary keys
have been added so that the key version number in the ticket will indicate a
char *sessionKey, afs_int32 *host, afs_int32 *start, afs_int32 *end)
{ char clear_ticket[MAXKTCTICKETLEN];
char *ticket;
- Key_schedule schedule;
- /* unsigned char flags; */
+ union Key_schedule_safe schedule;
int code;
if (ticketLen == 0) return RXKADBADTICKET; /* no ticket */
if ((ticketLen < MINKTCTICKETLEN) || /* minimum legal ticket size */
+ (ticketLen > MAXKTCTICKETLEN) || /* maximum legal ticket size */
((ticketLen) % 8 != 0)) /* enc. part must be (0 mod 8) bytes */
return RXKADBADTICKET;
- if (key_sched (key, schedule)) return RXKADBADKEY;
+ if (key_sched (key, schedule.schedule)) return RXKADBADKEY;
ticket = clear_ticket;
- pcbc_encrypt (asecret, ticket, ticketLen, schedule, key, DECRYPT);
-
- /* flags = *ticket; */ /* get the first byte: the flags */
-#if 0
- if (flags == ANDREWFLAGSVALUE) {
- code = decode_andrew_ticket (ticket, ticketLen, name, inst, cell,
- host, sessionKey, start, end);
- if (code) {
- code = decode_athena_ticket (ticket, ticketLen, name, inst, cell,
- host, sessionKey, start, end);
- flags = 0;
- }
- }
- else {
- code = decode_athena_ticket (ticket, ticketLen, name, inst, cell,
- host, sessionKey, start, end);
- if (code) {
- code = decode_andrew_ticket (ticket, ticketLen, name, inst, cell,
- host, sessionKey, start, end);
- flags = ANDREWFLAGSVALUE;
- }
- }
-#else
+ pcbc_encrypt (asecret, ticket, ticketLen, schedule.schedule, key, DECRYPT);
+
code = decode_athena_ticket
(ticket, ticketLen, name, inst, cell, host, sessionKey, start, end);
- /* flags = 0; */
-#endif
if (code) return RXKADBADTICKET;
if (tkt_CheckTimes (*start, *end, time(0)) < -1) return RXKADBADTICKET;
char *sinst;
*/
-int tkt_MakeTicket (char *ticket, int *ticketLen,
- struct ktc_encryptionKey *key, char *name, char *inst, char *cell,
- afs_uint32 start, afs_uint32 end, struct ktc_encryptionKey *sessionKey,
- afs_uint32 host, char *sname, char *sinst)
-{ int code;
- Key_schedule schedule;
-
- *ticketLen = 0; /* in case we return early */
- code = assemble_athena_ticket (ticket, ticketLen, name, inst, cell,
- host, sessionKey, start, end, sname, sinst);
- *ticketLen = round_up_to_ebs(*ticketLen); /* round up */
- if (code) return -1;
-
- /* encrypt ticket */
- if ((code = key_sched (key, schedule))) {
- printf ("In tkt_MakeTicket: key_sched returned %d\n", code);
- return RXKADBADKEY;
- }
- pcbc_encrypt (ticket, ticket, *ticketLen, schedule, key, ENCRYPT);
- return 0;
-}
-
-#define getstr(name,min) \
- slen = strlen(ticket); \
- if ((slen < min) || (slen >= MAXKTCNAMELEN)) return -1; \
- strcpy (name, ticket); \
- ticket += slen+1
-
-static int decode_athena_ticket (char *ticket, int ticketLen, char *name,
- char *inst, char *realm, afs_int32 *host, struct ktc_encryptionKey *sessionKey,
- afs_uint32 *start, afs_uint32 *end)
-{ char *ticketBeg = ticket;
- char flags;
- int slen;
- int tlen;
- unsigned char lifetime;
- char sname[MAXKTCNAMELEN]; /* these aren't used, */
- char sinst[MAXKTCNAMELEN]; /* but are in the ticket */
-
- flags = *ticket++;
- getstr (name, 1);
- getstr (inst, 0);
- getstr (realm, 0);
-
- memcpy(host, ticket, sizeof (*host));
- ticket += sizeof(*host);
- *host = ktohl (flags, *host);
-
- memcpy(sessionKey, ticket, sizeof (struct ktc_encryptionKey));
- ticket += sizeof (struct ktc_encryptionKey);
-
- lifetime = *ticket++;
- memcpy(start, ticket, sizeof (*start));
- ticket += sizeof(*start);
- *start = ktohl (flags, *start);
- *end = life_to_time (*start, lifetime);
-
- getstr (sname, 1);
- getstr (sinst, 0);
-
- tlen = ticket - ticketBeg;
- if ((round_up_to_ebs(tlen) != ticketLen) && (ticketLen != 56)) return -1;
- return 0;
-}
-
#define putstr(name,min) \
slen = strlen(name); \
if ((slen < min) || (slen >= MAXKTCNAMELEN)) return -1; \
return 0;
}
+int tkt_MakeTicket (char *ticket, int *ticketLen,
+ struct ktc_encryptionKey *key, char *name, char *inst, char *cell,
+ afs_uint32 start, afs_uint32 end, struct ktc_encryptionKey *sessionKey,
+ afs_uint32 host, char *sname, char *sinst)
+{ int code;
+ union Key_schedule_safe schedule;
+
+ *ticketLen = 0; /* in case we return early */
+ code = assemble_athena_ticket (ticket, ticketLen, name, inst, cell,
+ host, sessionKey, start, end, sname, sinst);
+ *ticketLen = round_up_to_ebs(*ticketLen); /* round up */
+ if (code) return -1;
+
+ /* encrypt ticket */
+ if (code = key_sched (key, schedule.schedule)) {
+ printf ("In tkt_MakeTicket: key_sched returned %d\n", code);
+ return RXKADBADKEY;
+ }
+ pcbc_encrypt (ticket, ticket, *ticketLen, schedule.schedule, key, ENCRYPT);
+ return 0;
+}
+
/* This is just a routine that checks the consistency of ticket lifetimes. It
returns three values: */
/* -2 means the times are inconsistent or ticket has expired