]>
Commit | Line | Data |
---|---|---|
8efc0c15 | 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 | Dug Song <dugsong@UMICH.EDU> | |
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 */ | |
54 | #define DEC(c) pr2six[(unsigned char)c] | |
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; | |
77 | while (DEC(*(bufin++)) <= MAXVAL); | |
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) { | |
93 | if (DEC(bufin[-2]) > MAXVAL) | |
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 int endTime ; | |
179 | endTime = (unsigned int)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 int 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 */ |