[BACK]Return to radix.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/radix.c, Revision 1.3

1.1       deraadt     1: /*
                      2:   radix.c
                      3:
                      4:   base-64 encoding pinched from lynx2-7-2, who pinched it from rpem.
                      5:   Originally written by Mark Riordan 12 August 1990 and 17 Feb 1991
                      6:   and placed in the public domain.
                      7:
1.2       dugsong     8:   Dug Song <dugsong@UMICH.EDU>
1.1       deraadt     9: */
                     10:
                     11: #include "includes.h"
                     12:
                     13: #ifdef AFS
                     14: #include <krb.h>
                     15:
                     16: char six2pr[64] = {
                     17:     'A','B','C','D','E','F','G','H','I','J','K','L','M',
                     18:     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
                     19:     'a','b','c','d','e','f','g','h','i','j','k','l','m',
                     20:     'n','o','p','q','r','s','t','u','v','w','x','y','z',
                     21:     '0','1','2','3','4','5','6','7','8','9','+','/'
                     22: };
                     23:
                     24: unsigned char pr2six[256];
                     25:
                     26: int uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
                     27: {
                     28:   /* ENC is the basic 1 character encoding function to make a char printing */
                     29: #define ENC(c) six2pr[c]
                     30:
                     31:   register char *outptr = bufcoded;
                     32:   unsigned int i;
                     33:
                     34:   for (i=0; i<nbytes; i += 3) {
                     35:     *(outptr++) = ENC(*bufin >> 2);            /* c1 */
                     36:     *(outptr++) = ENC(((*bufin << 4) & 060) | ((bufin[1] >> 4) & 017)); /*c2*/
                     37:     *(outptr++) = ENC(((bufin[1] << 2) & 074) | ((bufin[2] >> 6) & 03));/*c3*/
                     38:     *(outptr++) = ENC(bufin[2] & 077);         /* c4 */
                     39:     bufin += 3;
                     40:   }
                     41:   if (i == nbytes+1) {
                     42:     outptr[-1] = '=';
                     43:   } else if (i == nbytes+2) {
                     44:     outptr[-1] = '=';
                     45:     outptr[-2] = '=';
                     46:   }
                     47:   *outptr = '\0';
                     48:   return(outptr - bufcoded);
                     49: }
                     50:
                     51: int uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
                     52: {
                     53:   /* single character decode */
1.2       dugsong    54: #define DEC(c) pr2six[(unsigned char)c]
1.1       deraadt    55: #define MAXVAL 63
                     56:
                     57:   static int first = 1;
                     58:   int nbytesdecoded, j;
                     59:   const char *bufin = bufcoded;
                     60:   register unsigned char *bufout = bufplain;
                     61:   register int nprbytes;
                     62:
                     63:   /* If this is the first call, initialize the mapping table. */
                     64:   if (first) {
                     65:     first = 0;
                     66:     for(j=0; j<256; j++) pr2six[j] = MAXVAL+1;
                     67:     for(j=0; j<64; j++) pr2six[(unsigned char)six2pr[j]] = (unsigned char)j;
                     68:   }
                     69:
                     70:   /* Strip leading whitespace. */
                     71:   while (*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
                     72:
                     73:   /* Figure out how many characters are in the input buffer.
                     74:      If this would decode into more bytes than would fit into
                     75:      the output buffer, adjust the number of input bytes downwards. */
                     76:   bufin = bufcoded;
1.2       dugsong    77:   while (DEC(*(bufin++)) <= MAXVAL);
1.1       deraadt    78:   nprbytes = bufin - bufcoded - 1;
                     79:   nbytesdecoded = ((nprbytes+3)/4) * 3;
                     80:   if (nbytesdecoded > outbufsize)
                     81:     nprbytes = (outbufsize*4)/3;
                     82:
                     83:   bufin = bufcoded;
                     84:
                     85:   while (nprbytes > 0) {
                     86:     *(bufout++) = (unsigned char) (DEC(*bufin) << 2 | DEC(bufin[1]) >> 4);
                     87:     *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
                     88:     *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
                     89:     bufin += 4;
                     90:     nprbytes -= 4;
                     91:   }
                     92:   if (nprbytes & 03) {
1.2       dugsong    93:     if (DEC(bufin[-2]) > MAXVAL)
1.1       deraadt    94:       nbytesdecoded -= 2;
                     95:     else
                     96:       nbytesdecoded -= 1;
                     97:   }
                     98:   return(nbytesdecoded);
                     99: }
                    100:
                    101: typedef unsigned char my_u_char;
                    102: typedef unsigned int my_u_int32_t;
                    103: typedef unsigned short my_u_short;
                    104:
                    105: /* Nasty macros from BIND-4.9.2 */
                    106:
                    107: #define GETSHORT(s, cp) { \
                    108:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    109:        (s) = (((my_u_short)t_cp[0]) << 8) \
                    110:            | (((my_u_short)t_cp[1])) \
                    111:            ; \
                    112:        (cp) += 2; \
                    113: }
                    114:
                    115: #define GETLONG(l, cp) { \
                    116:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    117:        (l) = (((my_u_int32_t)t_cp[0]) << 24) \
                    118:            | (((my_u_int32_t)t_cp[1]) << 16) \
                    119:            | (((my_u_int32_t)t_cp[2]) << 8) \
                    120:            | (((my_u_int32_t)t_cp[3])) \
                    121:            ; \
                    122:        (cp) += 4; \
                    123: }
                    124:
                    125: #define PUTSHORT(s, cp) { \
                    126:        register my_u_short t_s = (my_u_short)(s); \
                    127:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    128:        *t_cp++ = t_s >> 8; \
                    129:        *t_cp   = t_s; \
                    130:        (cp) += 2; \
                    131: }
                    132:
                    133: #define PUTLONG(l, cp) { \
                    134:        register my_u_int32_t t_l = (my_u_int32_t)(l); \
                    135:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    136:        *t_cp++ = t_l >> 24; \
                    137:        *t_cp++ = t_l >> 16; \
                    138:        *t_cp++ = t_l >> 8; \
                    139:        *t_cp   = t_l; \
                    140:        (cp) += 4; \
                    141: }
                    142:
                    143: #define GETSTRING(s, p, p_l) {                 \
                    144:     register char* p_targ = (p) + p_l;         \
                    145:     register char* s_c = (s);                  \
                    146:     register char* p_c = (p);                  \
                    147:     while (*p_c && (p_c < p_targ)) {           \
                    148:        *s_c++ = *p_c++;                        \
                    149:     }                                          \
                    150:     if (p_c == p_targ) {                       \
                    151:        return 1;                               \
                    152:     }                                          \
                    153:     *s_c = *p_c++;                             \
                    154:     (p_l) = (p_l) - (p_c - (p));               \
                    155:     (p) = p_c;                                 \
                    156: }
                    157:
                    158:
                    159: int creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
                    160: {
                    161:   char *p, *s;
                    162:   int len;
                    163:   char temp[2048];
                    164:
                    165:   p = temp;
                    166:   *p++ = 1; /* version */
                    167:   s = creds->service;  while (*s) *p++ = *s++; *p++ = *s;
                    168:   s = creds->instance; while (*s) *p++ = *s++; *p++ = *s;
                    169:   s = creds->realm;    while (*s) *p++ = *s++; *p++ = *s;
                    170:
                    171:   s = creds->pname;    while (*s) *p++ = *s++;   *p++ = *s;
                    172:   s = creds->pinst;    while (*s) *p++ = *s++;   *p++ = *s;
                    173:   /* Null string to repeat the realm. */
                    174:   *p++ = '\0';
                    175:
                    176:   PUTLONG(creds->issue_date,p);
                    177:   {
1.3     ! deraadt   178:     unsigned int       endTime ;
        !           179:     endTime = (unsigned int)krb_life_to_time(creds->issue_date,
1.1       deraadt   180:                                              creds->lifetime);
                    181:     PUTLONG(endTime,p);
                    182:   }
                    183:
                    184:   memcpy(p,&creds->session, sizeof(creds->session));
                    185:   p += sizeof(creds->session);
                    186:
                    187:   PUTSHORT(creds->kvno,p);
                    188:   PUTLONG(creds->ticket_st.length,p);
                    189:
                    190:   memcpy(p,creds->ticket_st.dat, creds->ticket_st.length);
                    191:   p += creds->ticket_st.length;
                    192:   len = p - temp;
                    193:
                    194:   return(uuencode(temp, len, buf));
                    195: }
                    196:
                    197: int radix_to_creds(const char *buf, CREDENTIALS *creds)
                    198: {
                    199:
                    200:   char *p;
                    201:   int len, tl;
                    202:   char version;
                    203:   char temp[2048];
                    204:
                    205:   if (!(len = uudecode(buf, temp, sizeof(temp))))
                    206:     return 0;
                    207:
                    208:   p = temp;
                    209:
                    210:   /* check version and length! */
                    211:   if (len < 1) return 0;
                    212:   version = *p; p++; len--;
                    213:
                    214:   GETSTRING(creds->service, p, len);
                    215:   GETSTRING(creds->instance, p, len);
                    216:   GETSTRING(creds->realm, p, len);
                    217:
                    218:   GETSTRING(creds->pname, p, len);
                    219:   GETSTRING(creds->pinst, p, len);
                    220:   /* Ignore possibly different realm. */
                    221:   while (*p && len) p++, len--;
                    222:   if (len == 0) return 0;
                    223:   p++, len--;
                    224:
                    225:   /* Enough space for remaining fixed-length parts? */
                    226:   if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
                    227:     return 0;
                    228:
                    229:   GETLONG(creds->issue_date,p);
                    230:   len -= 4;
                    231:   {
1.3     ! deraadt   232:     unsigned int       endTime;
1.1       deraadt   233:     GETLONG(endTime,p);
                    234:     len -= 4;
                    235:     creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
                    236:   }
                    237:
                    238:   memcpy(&creds->session, p, sizeof(creds->session));
                    239:   p += sizeof(creds->session);
                    240:   len -= sizeof(creds->session);
                    241:
                    242:   GETSHORT(creds->kvno,p);
                    243:   len -= 2;
                    244:   GETLONG(creds->ticket_st.length,p);
                    245:   len -= 4;
                    246:
                    247:   tl = creds->ticket_st.length;
                    248:   if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
                    249:     return 0;
                    250:
                    251:   memcpy(creds->ticket_st.dat, p, tl);
                    252:   p += tl;
                    253:   len -= tl;
                    254:
                    255:   return 1;
                    256: }
                    257:
                    258: #endif /* AFS */