/*
  radix.c

  base-64 encoding pinched from lynx2-7-2, who pinched it from rpem.
  Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991
  and placed in the public domain.

  Dug Song <dugsong@UMICH.EDU>
*/
  
#include "includes.h"

#ifdef AFS
#include <krb.h>

char six2pr[64] = {
    'A','B','C','D','E','F','G','H','I','J','K','L','M',
    'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
    'a','b','c','d','e','f','g','h','i','j','k','l','m',
    'n','o','p','q','r','s','t','u','v','w','x','y','z',
    '0','1','2','3','4','5','6','7','8','9','+','/'
};

unsigned char pr2six[256];

int uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
{
  /* ENC is the basic 1 character encoding function to make a char printing */
#define ENC(c) six2pr[c]
  
  register char *outptr = bufcoded;
  unsigned int i;
  
  for (i=0; i<nbytes; i += 3) {
    *(outptr++) = ENC(*bufin >> 2);            /* c1 */
    *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
    *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));/*c3*/
    *(outptr++) = ENC(bufin[2] & 077);         /* c4 */
    bufin += 3;
  }
  if (i == nbytes+1) {
    outptr[-1] = '=';
  } else if (i == nbytes+2) {
    outptr[-1] = '=';
    outptr[-2] = '=';
  }
  *outptr = '\0';
  return(outptr - bufcoded);
}

int uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
{
  /* single character decode */
#define DEC(c) pr2six[(unsigned char)c]
#define MAXVAL 63
  
  static int first = 1;
  int nbytesdecoded, j;
  const char *bufin = bufcoded;
  register unsigned char *bufout = bufplain;
  register int nprbytes;
  
  /* If this is the first call, initialize the mapping table. */
  if (first) {
    first = 0;
    for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;
    for(j=0; j<64; j++) pr2six[(unsigned char)six2pr[j]] = (unsigned char)j;
  }
  
  /* Strip leading whitespace. */
  while (*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
  
  /* Figure out how many characters are in the input buffer.
     If this would decode into more bytes than would fit into
     the output buffer, adjust the number of input bytes downwards. */
  bufin = bufcoded;
  while (DEC(*(bufin++)) <= MAXVAL);
  nprbytes = bufin - bufcoded - 1;
  nbytesdecoded = ((nprbytes+3)/4) * 3;
  if (nbytesdecoded > outbufsize)
    nprbytes = (outbufsize*4)/3;
  
  bufin = bufcoded;
  
  while (nprbytes > 0) {
    *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
    *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
    *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
    bufin += 4;
    nprbytes -= 4;
  }
  if (nprbytes & 03) {
    if (DEC(bufin[-2]) > MAXVAL)
      nbytesdecoded -= 2;
    else 
      nbytesdecoded -= 1;
  }
  return(nbytesdecoded);
}

typedef unsigned char my_u_char;
typedef unsigned int my_u_int32_t;
typedef unsigned short my_u_short;

/* Nasty macros from BIND-4.9.2 */

#define GETSHORT(s, cp) { \
	register my_u_char *t_cp = (my_u_char*)(cp); \
	(s) = (((my_u_short)t_cp[0]) << 8) \
	    | (((my_u_short)t_cp[1])) \
	    ; \
	(cp) += 2; \
}

#define GETLONG(l, cp) { \
	register my_u_char *t_cp = (my_u_char*)(cp); \
	(l) = (((my_u_int32_t)t_cp[0]) << 24) \
	    | (((my_u_int32_t)t_cp[1]) << 16) \
	    | (((my_u_int32_t)t_cp[2]) << 8) \
	    | (((my_u_int32_t)t_cp[3])) \
	    ; \
	(cp) += 4; \
}

#define PUTSHORT(s, cp) { \
	register my_u_short t_s = (my_u_short)(s); \
	register my_u_char *t_cp = (my_u_char*)(cp); \
	*t_cp++ = t_s >> 8; \
	*t_cp   = t_s; \
	(cp) += 2; \
}

#define PUTLONG(l, cp) { \
	register my_u_int32_t t_l = (my_u_int32_t)(l); \
	register my_u_char *t_cp = (my_u_char*)(cp); \
	*t_cp++ = t_l >> 24; \
	*t_cp++ = t_l >> 16; \
	*t_cp++ = t_l >> 8; \
	*t_cp   = t_l; \
	(cp) += 4; \
}

#define GETSTRING(s, p, p_l) {			\
    register char* p_targ = (p) + p_l;		\
    register char* s_c = (s);			\
    register char* p_c = (p);			\
    while (*p_c && (p_c < p_targ)) {		\
	*s_c++ = *p_c++;			\
    }						\
    if (p_c == p_targ) {			\
	return 1;				\
    }						\
    *s_c = *p_c++;				\
    (p_l) = (p_l) - (p_c - (p));		\
    (p) = p_c;					\
}


int creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
{
  char *p, *s;
  int len;
  char temp[2048];
  
  p = temp;
  *p++ = 1; /* version */
  s = creds->service;	while (*s) *p++ = *s++; *p++ = *s;
  s = creds->instance;	while (*s) *p++ = *s++; *p++ = *s;
  s = creds->realm;	while (*s) *p++ = *s++; *p++ = *s;

  s = creds->pname;	while (*s) *p++ = *s++;   *p++ = *s;
  s = creds->pinst;	while (*s) *p++ = *s++;   *p++ = *s;
  /* Null string to repeat the realm. */
  *p++ = '\0';

  PUTLONG(creds->issue_date,p);
  {
    unsigned int	endTime ;
    endTime = (unsigned int)krb_life_to_time(creds->issue_date,
					      creds->lifetime);
    PUTLONG(endTime,p);
  }

  memcpy(p,&creds->session, sizeof(creds->session));
  p += sizeof(creds->session);
  
  PUTSHORT(creds->kvno,p);
  PUTLONG(creds->ticket_st.length,p);
  
  memcpy(p,creds->ticket_st.dat, creds->ticket_st.length);
  p += creds->ticket_st.length;
  len = p - temp;

  return(uuencode(temp, len, buf));
}

int radix_to_creds(const char *buf, CREDENTIALS *creds)
{

  char *p;
  int len, tl;
  char version;
  char temp[2048];
  
  if (!(len = uudecode(buf, temp, sizeof(temp))))
    return 0;
  
  p = temp;

  /* check version and length! */
  if (len < 1) return 0;
  version = *p; p++; len--;

  GETSTRING(creds->service, p, len);
  GETSTRING(creds->instance, p, len);
  GETSTRING(creds->realm, p, len);
  
  GETSTRING(creds->pname, p, len);
  GETSTRING(creds->pinst, p, len);
  /* Ignore possibly different realm. */
  while (*p && len) p++, len--;
  if (len == 0) return 0;
  p++, len--;
  
  /* Enough space for remaining fixed-length parts? */
  if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
    return 0;
  
  GETLONG(creds->issue_date,p);
  len -= 4;
  {
    unsigned int	endTime;
    GETLONG(endTime,p);
    len -= 4;
    creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
  }

  memcpy(&creds->session, p, sizeof(creds->session));
  p += sizeof(creds->session);
  len -= sizeof(creds->session);
  
  GETSHORT(creds->kvno,p);
  len -= 2;
  GETLONG(creds->ticket_st.length,p);
  len -= 4;

  tl = creds->ticket_st.length;
  if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
    return 0;
  
  memcpy(creds->ticket_st.dat, p, tl);
  p += tl;
  len -= tl;
  
  return 1;
}

#endif /* AFS */
