]>
Commit | Line | Data |
---|---|---|
8efc0c15 | 1 | /* |
5260325f | 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 | */ | |
8efc0c15 | 10 | |
8efc0c15 | 11 | #include "includes.h" |
12 | ||
13 | #ifdef AFS | |
14 | #include <krb.h> | |
15 | ||
16 | char six2pr[64] = { | |
5260325f | 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', '+', '/' | |
8efc0c15 | 22 | }; |
23 | ||
24 | unsigned char pr2six[256]; | |
25 | ||
5260325f | 26 | int |
27 | uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded) | |
8efc0c15 | 28 | { |
5260325f | 29 | /* ENC is the basic 1 character encoding function to make a char printing */ |
8efc0c15 | 30 | #define ENC(c) six2pr[c] |
5260325f | 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); | |
8efc0c15 | 50 | } |
51 | ||
5260325f | 52 | int |
53 | uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize) | |
8efc0c15 | 54 | { |
5260325f | 55 | /* single character decode */ |
8efc0c15 | 56 | #define DEC(c) pr2six[(unsigned char)c] |
57 | #define MAXVAL 63 | |
5260325f | 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 | ||
aa3378df | 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 | */ | |
5260325f | 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); | |
8efc0c15 | 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 | ||
5260325f | 165 | int |
166 | creds_to_radix(CREDENTIALS *creds, unsigned char *buf) | |
8efc0c15 | 167 | { |
5260325f | 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; | |
215 | ||
216 | return (uuencode(temp, len, buf)); | |
8efc0c15 | 217 | } |
218 | ||
5260325f | 219 | int |
220 | radix_to_creds(const char *buf, CREDENTIALS *creds) | |
8efc0c15 | 221 | { |
222 | ||
5260325f | 223 | char *p; |
224 | int len, tl; | |
225 | char version; | |
226 | char temp[2048]; | |
227 | ||
228 | if (!(len = uudecode(buf, temp, sizeof(temp)))) | |
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--; | |
8efc0c15 | 252 | |
5260325f | 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; | |
284 | } | |
8efc0c15 | 285 | #endif /* AFS */ |