]>
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 | ||
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); | |
8efc0c15 | 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 | ||
5260325f | 163 | int |
164 | creds_to_radix(CREDENTIALS *creds, unsigned char *buf) | |
8efc0c15 | 165 | { |
5260325f | 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; | |
213 | ||
214 | return (uuencode(temp, len, buf)); | |
8efc0c15 | 215 | } |
216 | ||
5260325f | 217 | int |
218 | radix_to_creds(const char *buf, CREDENTIALS *creds) | |
8efc0c15 | 219 | { |
220 | ||
5260325f | 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--; | |
8efc0c15 | 250 | |
5260325f | 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; | |
282 | } | |
8efc0c15 | 283 | #endif /* AFS */ |