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

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:
                     77:        /* Figure out how many characters are in the input buffer. If this
                     78:           would decode into more bytes than would fit into the output
                     79:           buffer, adjust the number of input bytes downwards. */
                     80:        bufin = bufcoded;
                     81:        while (DEC(*(bufin++)) <= MAXVAL);
                     82:        nprbytes = bufin - bufcoded - 1;
                     83:        nbytesdecoded = ((nprbytes + 3) / 4) * 3;
                     84:        if (nbytesdecoded > outbufsize)
                     85:                nprbytes = (outbufsize * 4) / 3;
                     86:
                     87:        bufin = bufcoded;
                     88:
                     89:        while (nprbytes > 0) {
                     90:                *(bufout++) = (unsigned char) (DEC(*bufin)   << 2 | DEC(bufin[1]) >> 4);
                     91:                *(bufout++) = (unsigned char) (DEC(bufin[1]) << 4 | DEC(bufin[2]) >> 2);
                     92:                *(bufout++) = (unsigned char) (DEC(bufin[2]) << 6 | DEC(bufin[3]));
                     93:                bufin += 4;
                     94:                nprbytes -= 4;
                     95:        }
                     96:        if (nprbytes & 03) {
                     97:                if (DEC(bufin[-2]) > MAXVAL)
                     98:                        nbytesdecoded -= 2;
                     99:                else
                    100:                        nbytesdecoded -= 1;
                    101:        }
                    102:        return (nbytesdecoded);
1.1       deraadt   103: }
                    104:
                    105: typedef unsigned char my_u_char;
                    106: typedef unsigned int my_u_int32_t;
                    107: typedef unsigned short my_u_short;
                    108:
                    109: /* Nasty macros from BIND-4.9.2 */
                    110:
                    111: #define GETSHORT(s, cp) { \
                    112:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    113:        (s) = (((my_u_short)t_cp[0]) << 8) \
                    114:            | (((my_u_short)t_cp[1])) \
                    115:            ; \
                    116:        (cp) += 2; \
                    117: }
                    118:
                    119: #define GETLONG(l, cp) { \
                    120:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    121:        (l) = (((my_u_int32_t)t_cp[0]) << 24) \
                    122:            | (((my_u_int32_t)t_cp[1]) << 16) \
                    123:            | (((my_u_int32_t)t_cp[2]) << 8) \
                    124:            | (((my_u_int32_t)t_cp[3])) \
                    125:            ; \
                    126:        (cp) += 4; \
                    127: }
                    128:
                    129: #define PUTSHORT(s, cp) { \
                    130:        register my_u_short t_s = (my_u_short)(s); \
                    131:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    132:        *t_cp++ = t_s >> 8; \
                    133:        *t_cp   = t_s; \
                    134:        (cp) += 2; \
                    135: }
                    136:
                    137: #define PUTLONG(l, cp) { \
                    138:        register my_u_int32_t t_l = (my_u_int32_t)(l); \
                    139:        register my_u_char *t_cp = (my_u_char*)(cp); \
                    140:        *t_cp++ = t_l >> 24; \
                    141:        *t_cp++ = t_l >> 16; \
                    142:        *t_cp++ = t_l >> 8; \
                    143:        *t_cp   = t_l; \
                    144:        (cp) += 4; \
                    145: }
                    146:
                    147: #define GETSTRING(s, p, p_l) {                 \
                    148:     register char* p_targ = (p) + p_l;         \
                    149:     register char* s_c = (s);                  \
                    150:     register char* p_c = (p);                  \
                    151:     while (*p_c && (p_c < p_targ)) {           \
                    152:        *s_c++ = *p_c++;                        \
                    153:     }                                          \
                    154:     if (p_c == p_targ) {                       \
                    155:        return 1;                               \
                    156:     }                                          \
                    157:     *s_c = *p_c++;                             \
                    158:     (p_l) = (p_l) - (p_c - (p));               \
                    159:     (p) = p_c;                                 \
                    160: }
                    161:
                    162:
1.4       markus    163: int
                    164: creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
1.1       deraadt   165: {
1.4       markus    166:        char *p, *s;
                    167:        int len;
                    168:        char temp[2048];
                    169:
                    170:        p = temp;
                    171:        *p++ = 1;               /* version */
                    172:        s = creds->service;
                    173:        while (*s)
                    174:                *p++ = *s++;
                    175:        *p++ = *s;
                    176:        s = creds->instance;
                    177:        while (*s)
                    178:                *p++ = *s++;
                    179:        *p++ = *s;
                    180:        s = creds->realm;
                    181:        while (*s)
                    182:                *p++ = *s++;
                    183:        *p++ = *s;
                    184:
                    185:        s = creds->pname;
                    186:        while (*s)
                    187:                *p++ = *s++;
                    188:        *p++ = *s;
                    189:        s = creds->pinst;
                    190:        while (*s)
                    191:                *p++ = *s++;
                    192:        *p++ = *s;
                    193:        /* Null string to repeat the realm. */
                    194:        *p++ = '\0';
                    195:
                    196:        PUTLONG(creds->issue_date, p);
                    197:        {
                    198:                unsigned int endTime;
                    199:                endTime = (unsigned int) krb_life_to_time(creds->issue_date,
                    200:                                                          creds->lifetime);
                    201:                PUTLONG(endTime, p);
                    202:        }
                    203:
                    204:        memcpy(p, &creds->session, sizeof(creds->session));
                    205:        p += sizeof(creds->session);
                    206:
                    207:        PUTSHORT(creds->kvno, p);
                    208:        PUTLONG(creds->ticket_st.length, p);
                    209:
                    210:        memcpy(p, creds->ticket_st.dat, creds->ticket_st.length);
                    211:        p += creds->ticket_st.length;
                    212:        len = p - temp;
1.1       deraadt   213:
1.4       markus    214:        return (uuencode(temp, len, buf));
1.1       deraadt   215: }
                    216:
1.4       markus    217: int
                    218: radix_to_creds(const char *buf, CREDENTIALS *creds)
1.1       deraadt   219: {
                    220:
1.4       markus    221:        char *p;
                    222:        int len, tl;
                    223:        char version;
                    224:        char temp[2048];
                    225:
                    226:        if (!(len = uudecode(buf, temp, sizeof(temp))))
                    227:                return 0;
                    228:
                    229:        p = temp;
                    230:
                    231:        /* check version and length! */
                    232:        if (len < 1)
                    233:                return 0;
                    234:        version = *p;
                    235:        p++;
                    236:        len--;
                    237:
                    238:        GETSTRING(creds->service, p, len);
                    239:        GETSTRING(creds->instance, p, len);
                    240:        GETSTRING(creds->realm, p, len);
                    241:
                    242:        GETSTRING(creds->pname, p, len);
                    243:        GETSTRING(creds->pinst, p, len);
                    244:        /* Ignore possibly different realm. */
                    245:        while (*p && len)
                    246:                p++, len--;
                    247:        if (len == 0)
                    248:                return 0;
                    249:        p++, len--;
                    250:
                    251:        /* Enough space for remaining fixed-length parts? */
                    252:        if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
                    253:                return 0;
                    254:
                    255:        GETLONG(creds->issue_date, p);
                    256:        len -= 4;
                    257:        {
                    258:                unsigned int endTime;
                    259:                GETLONG(endTime, p);
                    260:                len -= 4;
                    261:                creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
                    262:        }
                    263:
                    264:        memcpy(&creds->session, p, sizeof(creds->session));
                    265:        p += sizeof(creds->session);
                    266:        len -= sizeof(creds->session);
                    267:
                    268:        GETSHORT(creds->kvno, p);
                    269:        len -= 2;
                    270:        GETLONG(creds->ticket_st.length, p);
                    271:        len -= 4;
                    272:
                    273:        tl = creds->ticket_st.length;
                    274:        if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
                    275:                return 0;
                    276:
                    277:        memcpy(creds->ticket_st.dat, p, tl);
                    278:        p += tl;
                    279:        len -= tl;
                    280:
                    281:        return 1;
1.1       deraadt   282: }
                    283: #endif /* AFS */