]> andersk Git - openssh.git/blob - radix.c
ea7f5ba2bcac16714d88a5085b8e2c12e8b36228
[openssh.git] / radix.c
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 
27 uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
28 {
29         /* ENC is the basic 1 character encoding function to make a char printing */
30 #define ENC(c) six2pr[c]
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);
50 }
51
52 int 
53 uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
54 {
55         /* single character decode */
56 #define DEC(c) pr2six[(unsigned char)c]
57 #define MAXVAL 63
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         /*
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          */
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);
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
165 int 
166 creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
167 {
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((unsigned char *)temp, len, (char *)buf));
217 }
218
219 int 
220 radix_to_creds(const char *buf, CREDENTIALS *creds)
221 {
222
223         char *p;
224         int len, tl;
225         char version;
226         char temp[2048];
227
228         if (!(len = uudecode(buf, (unsigned char *)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--;
252
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 }
285 #endif /* AFS */
This page took 0.056474 seconds and 3 git commands to generate.