]> andersk Git - openssh.git/blob - radix.c
1c497945e52186bdc487a3a171789eebd660b109
[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 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 */
This page took 0.044113 seconds and 3 git commands to generate.