Annotation of src/usr.bin/ssh/radix.c, Revision 1.2
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: {
178: unsigned long endTime ;
179: endTime = (unsigned long)krb_life_to_time(creds->issue_date,
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: {
232: unsigned long endTime;
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 */