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.
8 Dug Song <dugsong@UMICH.EDU>
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','+','/'
24 unsigned char pr2six[256];
26 int uuencode(unsigned char *bufin, unsigned int nbytes, char *bufcoded)
28 /* ENC is the basic 1 character encoding function to make a char printing */
29 #define ENC(c) six2pr[c]
31 register char *outptr = bufcoded;
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 */
43 } else if (i == nbytes+2) {
48 return(outptr - bufcoded);
51 int uudecode(const char *bufcoded, unsigned char *bufplain, int outbufsize)
53 /* single character decode */
54 #define DEC(c) pr2six[(unsigned char)c]
59 const char *bufin = bufcoded;
60 register unsigned char *bufout = bufplain;
61 register int nprbytes;
63 /* If this is the first call, initialize the mapping table. */
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;
70 /* Strip leading whitespace. */
71 while (*bufcoded==' ' || *bufcoded == '\t') bufcoded++;
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. */
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;
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]));
93 if (DEC(bufin[-2]) > MAXVAL)
98 return(nbytesdecoded);
101 typedef unsigned char my_u_char;
102 typedef unsigned int my_u_int32_t;
103 typedef unsigned short my_u_short;
105 /* Nasty macros from BIND-4.9.2 */
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])) \
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])) \
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; \
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; \
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)) { \
150 if (p_c == p_targ) { \
154 (p_l) = (p_l) - (p_c - (p)); \
159 int creds_to_radix(CREDENTIALS *creds, unsigned char *buf)
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;
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. */
176 PUTLONG(creds->issue_date,p);
178 unsigned int endTime ;
179 endTime = (unsigned int)krb_life_to_time(creds->issue_date,
184 memcpy(p,&creds->session, sizeof(creds->session));
185 p += sizeof(creds->session);
187 PUTSHORT(creds->kvno,p);
188 PUTLONG(creds->ticket_st.length,p);
190 memcpy(p,creds->ticket_st.dat, creds->ticket_st.length);
191 p += creds->ticket_st.length;
194 return(uuencode(temp, len, buf));
197 int radix_to_creds(const char *buf, CREDENTIALS *creds)
205 if (!(len = uudecode(buf, temp, sizeof(temp))))
210 /* check version and length! */
211 if (len < 1) return 0;
212 version = *p; p++; len--;
214 GETSTRING(creds->service, p, len);
215 GETSTRING(creds->instance, p, len);
216 GETSTRING(creds->realm, p, len);
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;
225 /* Enough space for remaining fixed-length parts? */
226 if (len < (4 + 4 + sizeof(creds->session) + 2 + 4))
229 GETLONG(creds->issue_date,p);
232 unsigned int endTime;
235 creds->lifetime = krb_time_to_life(creds->issue_date, endTime);
238 memcpy(&creds->session, p, sizeof(creds->session));
239 p += sizeof(creds->session);
240 len -= sizeof(creds->session);
242 GETSHORT(creds->kvno,p);
244 GETLONG(creds->ticket_st.length,p);
247 tl = creds->ticket_st.length;
248 if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat))
251 memcpy(creds->ticket_st.dat, p, tl);