rxkad: Remove DES include from header file
[openafs.git] / src / rxkad / ticket.c
index 15c63cb..e543bbc 100644 (file)
@@ -1,62 +1,89 @@
 /*
  * Copyright 2000, International Business Machines Corporation and others.
  * All Rights Reserved.
- * 
+ *
  * This software has been released under the terms of the IBM Public
  * License.  For details, see the LICENSE file in the top-level source
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
 #include <afsconfig.h>
-#if defined(UKERNEL)
-#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"
-#else /* defined(UKERNEL) */
 #include <afs/stds.h>
-#include <sys/types.h>
-#ifdef AFS_NT40_ENV
-#include <winsock2.h>
-#else
-#include <netinet/in.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
+
+#include <roken.h>
+
+#include <hcrypto/des.h>
+
 #include <rx/xdr.h>
 #include <rx/rx.h>
-#include <des.h>
+
 #include "lifetimes.h"
 #include "rxkad.h"
-#endif /* defined(UKERNEL) */
+#include "rxkad_convert.h"
+
+/* 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 {
+    DES_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)
+{
+    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);
 
-extern afs_int32 ktohl();
-extern afs_uint32 life_to_time();
-extern unsigned char time_to_life();
+    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);
 
-static int decode_athena_ticket();
-static int assemble_athena_ticket();
+    getstr(sname, 1);
+    getstr(sinst, 0);
 
-#define ANDREWFLAGSVALUE (0x80)
-#define TICKET_LABEL "TicketEnd"
+    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
@@ -65,149 +92,62 @@ static int assemble_athena_ticket();
    interpreting the ticket and the values of the output parameters are
    undefined. */
 
-int tkt_DecodeTicket (asecret, ticketLen, key,
-                     name, inst, cell, sessionKey, host, start, end)
-  char         *asecret;
-  afs_int32             ticketLen;
-  struct ktc_encryptionKey *key;
-  char         *name;
-  char         *inst;
-  char         *cell;
-  char         *sessionKey;
-  afs_int32            *host;
-  afs_int32            *start;
-  afs_int32            *end;
-{   char          clear_ticket[MAXKTCTICKETLEN];
-    char         *ticket;
-    Key_schedule   schedule;
-    /* unsigned char  flags; */
-    int                   code;
-
-    if (ticketLen == 0) return RXKADBADTICKET; /* no ticket */
-    if ((ticketLen < MINKTCTICKETLEN) || /* minimum legal ticket size */
-       ((ticketLen) % 8 != 0))         /* enc. part must be (0 mod 8) bytes */
+int
+tkt_DecodeTicket(char *asecret, afs_int32 ticketLen,
+                struct ktc_encryptionKey *key, char *name, char *inst,
+                char *cell, struct ktc_encryptionKey *sessionKey, afs_int32 * host,
+                afs_uint32 * start, afs_uint32 * end)
+{
+    char clear_ticket[MAXKTCTICKETLEN];
+    char *ticket;
+    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 (DES_key_sched(ktc_to_cblock(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
-    code = decode_athena_ticket
-       (ticket, ticketLen, name, inst, cell, host, sessionKey, start, end);
-    /* flags = 0; */
+    DES_pcbc_encrypt(asecret, ticket, ticketLen, &schedule.schedule, ktc_to_cblockptr(key), DECRYPT);
+
+    code =
+       decode_athena_ticket(ticket, ticketLen, name, inst, cell, host,
+                            (struct ktc_encryptionKey *)sessionKey, start, end);
 
-#endif
-    if (code) return RXKADBADTICKET;
-    if (tkt_CheckTimes (*start, *end, time(0)) < -1) return RXKADBADTICKET;
+    if (code)
+       return RXKADBADTICKET;
+
+    code = tkt_CheckTimes(*start, *end, time(0));
+    if (code == 0)
+       return RXKADNOAUTH;
+    else if (code == -1)
+       return RXKADEXPIRED;
+    else if (code < -1)
+       return RXKADBADTICKET;
 
     return 0;
 }
 
 /* This makes a Kerberos ticket */
-
-int tkt_MakeTicket (ticket, ticketLen, key, name, inst, cell,
-                   start, end, sessionKey, host, sname, sinst)
-  char         *ticket;                /* ticket is constructed here */
-  int          *ticketLen;             /* output length of finished ticket */
-  struct ktc_encryptionKey *key;       /* key ticket should be sealed with */
-  char         *name;                  /* user of this ticket */
+/*
+  char         *ticket;                * ticket is constructed here *
+  int          *ticketLen;             * output length of finished ticket *
+  struct ktc_encryptionKey *key;       * key ticket should be sealed with *
+  char         *name;                  * user of this ticket *
   char         *inst;
-  char         *cell;                  /* cell of authentication */
-  afs_uint32    start,end;             /* life of ticket */
-  struct ktc_encryptionKey *sessionKey;        /* session key invented for ticket */
-  afs_uint32    host;                  /* caller's host address */
-  char         *sname;                 /* server */
+  char         *cell;                  * cell of authentication *
+  afs_uint32    start,end;             * life of ticket *
+  struct ktc_encryptionKey *sessionKey;        * session key invented for ticket *
+  afs_uint32    host;                  * caller's host address *
+  char         *sname;                 * server *
   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 (ticket, ticketLen, name, inst, realm,
-                                 host, sessionKey, start, end)
-  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); \
@@ -218,44 +158,65 @@ static int decode_athena_ticket (ticket, ticketLen, name, inst, realm,
                    memcpy(ticket, &num, sizeof(num));\
                    ticket += sizeof(num)
 
-static int assemble_athena_ticket (ticket, ticketLen, name, inst, realm,
-                                   host, sessionKey, start, end, sname, sinst)
-  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 *ticketBeg = ticket;
-    int          slen;
-    unsigned char  life;
-
-    *ticket++ = 0;                     /* flags, always send net-byte-order */
-    putstr (name, 1);
-    putstr (inst, 0);
-    putstr (realm, 0);
-    putint (host);
+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 *ticketBeg = ticket;
+    int slen;
+    unsigned char life;
+
+    *ticket++ = 0;             /* flags, always send net-byte-order */
+    putstr(name, 1);
+    putstr(inst, 0);
+    putstr(realm, 0);
+    putint(host);
 
     memcpy(ticket, sessionKey, sizeof(struct ktc_encryptionKey));
     ticket += sizeof(struct ktc_encryptionKey);
 
-    life = time_to_life (start, end);
-    if (life == 0) return -1;
+    life = time_to_life(start, end);
+    if (life == 0)
+       return -1;
     *ticket++ = life;
 
-    putint (start);
-    putstr (sname, 1);
-    putstr (sinst, 0);
+    putint(start);
+    putstr(sname, 1);
+    putstr(sinst, 0);
 
     *ticketLen = ticket - ticketBeg;
     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 = DES_key_sched(ktc_to_cblock(key), &schedule.schedule))) {
+       printf("In tkt_MakeTicket: key_sched returned %d\n", code);
+       return RXKADBADKEY;
+    }
+    DES_pcbc_encrypt(ticket, ticket, *ticketLen, &schedule.schedule,
+                    ktc_to_cblockptr(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
@@ -266,38 +227,42 @@ static int assemble_athena_ticket (ticket, ticketLen, name, inst, realm,
            and the lifetime is within the legal limit.
  */
 
-int tkt_CheckTimes (start, end, now)
-  afs_uint32 start;
-  afs_uint32 end;
-  afs_uint32 now;
-{   int active;
-
-    if (start >= end) return -2;       /* zero or negative lifetime */
-    if (start > now+KTC_TIME_UNCERTAINTY+MAXKTCTICKETLIFETIME)
-       return -2;                      /* starts too far in the future? */
-    if ((start != 0) && (end != NEVERDATE) &&
-       (end-start > MAXKTCTICKETLIFETIME)) return -2; /* too long a life */
-    if ((end != NEVERDATE) && (end+KTC_TIME_UNCERTAINTY < now)) { /* expired */
-       if ((start != 0) && (now - start > MAXKTCTICKETLIFETIME + 24*60*60))
+int
+tkt_CheckTimes(afs_uint32 start, afs_uint32 end, afs_uint32 now)
+{
+    int active;
+
+    if (start >= end)
+       return -2;              /* zero or negative lifetime */
+    if (start > now + KTC_TIME_UNCERTAINTY + MAXKTCTICKETLIFETIME)
+       return -2;              /* starts too far in the future? */
+    if ((start != 0) && (end != NEVERDATE)
+       && (end - start > MAXKTCTICKETLIFETIME))
+       return -2;              /* too long a life */
+    if ((end != NEVERDATE) && (end + KTC_TIME_UNCERTAINTY < now)) {    /* expired */
+       if ((start != 0)
+           && (now - start > MAXKTCTICKETLIFETIME + 24 * 60 * 60))
            return -2;
-       else return -1;                 /* expired only recently */
+       else
+           return -1;          /* expired only recently */
     }
-    if ((start == 0) || (start-KTC_TIME_UNCERTAINTY <= now)) active = 1;
-    else active = 0;                   /* start time not yet arrived */
+    if ((start == 0) || (start - KTC_TIME_UNCERTAINTY <= now))
+       active = 1;
+    else
+       active = 0;             /* start time not yet arrived */
 
     if ((start == 0) || (end == NEVERDATE))
-       return active; /* no expiration time */
-    return active*2;                   /* ticket valid */
+       return active;          /* no expiration time */
+    return active * 2;         /* ticket valid */
 }
 
-afs_int32 ktohl (flags, l)
-  char flags;
-  afs_int32 l;
+afs_int32
+ktohl(char flags, afs_int32 l)
 {
     if (flags & 1) {
        unsigned char *lp = (unsigned char *)&l;
-       afs_int32              hl;
-       hl = *lp + (*(lp+1) << 8) + (*(lp+2) << 16) + (*(lp+3) << 24);
+       afs_int32 hl;
+       hl = *lp + (*(lp + 1) << 8) + (*(lp + 2) << 16) + (*(lp + 3) << 24);
        return hl;
     }
     return ntohl(l);
@@ -314,14 +279,17 @@ afs_int32 ktohl (flags, l)
  * table to extract the lifetime in seconds, which is added to start to produce
  * the end time. */
 
-afs_uint32 life_to_time (start, life)
-  afs_uint32 start;
-  unsigned char life;
-{   int realLife;
-
-    if (life == TKTLIFENOEXPIRE) return NEVERDATE;
-    if (life < TKTLIFEMINFIXED) return start + life*5*60;
-    if (life > TKTLIFEMAXFIXED) return start + MAXTKTLIFETIME;
+afs_uint32
+life_to_time(afs_uint32 start, unsigned char life)
+{
+    int realLife;
+
+    if (life == TKTLIFENOEXPIRE)
+       return NEVERDATE;
+    if (life < TKTLIFEMINFIXED)
+       return start + life * 5 * 60;
+    if (life > TKTLIFEMAXFIXED)
+       return start + MAXTKTLIFETIME;
     realLife = tkt_lifetimes[life - TKTLIFEMINFIXED];
     return start + realLife;
 }
@@ -337,25 +305,30 @@ afs_uint32 life_to_time (start, life)
  * entry.  The actual code is prepared to handle the case where the table is
  * unordered but that it an unnecessary frill. */
 
-unsigned char time_to_life (start, end)
-  afs_uint32 start;
-  afs_uint32 end;
-{   int lifetime = end-start;
+unsigned char
+time_to_life(afs_uint32 start, afs_uint32 end)
+{
+    int lifetime = end - start;
     int best, best_i;
     int i;
 
-    if (end == NEVERDATE) return TKTLIFENOEXPIRE;
-    if ((lifetime > MAXKTCTICKETLIFETIME) || (lifetime <= 0)) return 0;
-    if (lifetime < tkt_lifetimes[0]) return (lifetime + 5*60-1) / (5*60);
+    if (end == NEVERDATE)
+       return TKTLIFENOEXPIRE;
+    if ((lifetime > MAXKTCTICKETLIFETIME) || (lifetime <= 0))
+       return 0;
+    if (lifetime < tkt_lifetimes[0])
+       return (lifetime + 5 * 60 - 1) / (5 * 60);
     best_i = -1;
     best = MAXKTCTICKETLIFETIME;
-    for (i=0; i<TKTLIFENUMFIXED; i++)
+    for (i = 0; i < TKTLIFENUMFIXED; i++)
        if (tkt_lifetimes[i] >= lifetime) {
-           int diff = tkt_lifetimes[i]-lifetime;
+           int diff = tkt_lifetimes[i] - lifetime;
            if (diff < best) {
                best = diff;
                best_i = i;
-           }}
-    if (best_i < 0) return 0;
-    return best_i+TKTLIFEMINFIXED;
+           }
+       }
+    if (best_i < 0)
+       return 0;
+    return best_i + TKTLIFEMINFIXED;
 }