diff options
Diffstat (limited to 'radix.c')
-rw-r--r-- | radix.c | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/radix.c b/radix.c new file mode 100644 index 000000000..1c497945e --- /dev/null +++ b/radix.c | |||
@@ -0,0 +1,258 @@ | |||
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 */ | ||