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