[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.7

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