version 1.17, 2001/11/19 19:02:16 |
version 1.17.2.2, 2002/05/18 04:50:38 |
|
|
/* |
/* |
* Copyright (c) 1999 Dug Song. All rights reserved. |
* Copyright (c) 1999 Dug Song. All rights reserved. |
|
* Copyright (c) 2002 Markus Friedl. All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* modification, are permitted provided that the following conditions |
|
|
#include <krb.h> |
#include <krb.h> |
|
|
#include <radix.h> |
#include <radix.h> |
|
#include "bufaux.h" |
|
|
typedef u_char my_u_char; |
|
typedef u_int my_u_int32_t; |
|
typedef u_short my_u_short; |
|
|
|
/* Nasty macros from BIND-4.9.2 */ |
|
|
|
#define GETSHORT(s, cp) { \ |
|
my_u_char *t_cp = (my_u_char *)(cp); \ |
|
(s) = (((my_u_short)t_cp[0]) << 8) \ |
|
| (((my_u_short)t_cp[1])) \ |
|
; \ |
|
(cp) += 2; \ |
|
} |
|
|
|
#define GETLONG(l, cp) { \ |
|
my_u_char *t_cp = (my_u_char *)(cp); \ |
|
(l) = (((my_u_int32_t)t_cp[0]) << 24) \ |
|
| (((my_u_int32_t)t_cp[1]) << 16) \ |
|
| (((my_u_int32_t)t_cp[2]) << 8) \ |
|
| (((my_u_int32_t)t_cp[3])) \ |
|
; \ |
|
(cp) += 4; \ |
|
} |
|
|
|
#define PUTSHORT(s, cp) { \ |
|
my_u_short t_s = (my_u_short)(s); \ |
|
my_u_char *t_cp = (my_u_char *)(cp); \ |
|
*t_cp++ = t_s >> 8; \ |
|
*t_cp = t_s; \ |
|
(cp) += 2; \ |
|
} |
|
|
|
#define PUTLONG(l, cp) { \ |
|
my_u_int32_t t_l = (my_u_int32_t)(l); \ |
|
my_u_char *t_cp = (my_u_char *)(cp); \ |
|
*t_cp++ = t_l >> 24; \ |
|
*t_cp++ = t_l >> 16; \ |
|
*t_cp++ = t_l >> 8; \ |
|
*t_cp = t_l; \ |
|
(cp) += 4; \ |
|
} |
|
|
|
#define GETSTRING(s, p, p_l) { \ |
|
char *p_targ = (p) + p_l; \ |
|
char *s_c = (s); \ |
|
char *p_c = (p); \ |
|
while (*p_c && (p_c < p_targ)) { \ |
|
*s_c++ = *p_c++; \ |
|
} \ |
|
if (p_c == p_targ) { \ |
|
return 1; \ |
|
} \ |
|
*s_c = *p_c++; \ |
|
(p_l) = (p_l) - (p_c - (p)); \ |
|
(p) = p_c; \ |
|
} |
|
|
|
|
|
int |
int |
creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) |
creds_to_radix(CREDENTIALS *creds, u_char *buf, size_t buflen) |
{ |
{ |
char *p, *s; |
Buffer b; |
int len; |
int ret; |
char temp[2048]; |
|
|
|
p = temp; |
buffer_init(&b); |
*p++ = 1; /* version */ |
|
s = creds->service; |
|
while (*s) |
|
*p++ = *s++; |
|
*p++ = *s; |
|
s = creds->instance; |
|
while (*s) |
|
*p++ = *s++; |
|
*p++ = *s; |
|
s = creds->realm; |
|
while (*s) |
|
*p++ = *s++; |
|
*p++ = *s; |
|
|
|
s = creds->pname; |
buffer_put_char(&b, 1); /* version */ |
while (*s) |
|
*p++ = *s++; |
|
*p++ = *s; |
|
s = creds->pinst; |
|
while (*s) |
|
*p++ = *s++; |
|
*p++ = *s; |
|
/* Null string to repeat the realm. */ |
|
*p++ = '\0'; |
|
|
|
PUTLONG(creds->issue_date, p); |
buffer_append(&b, creds->service, strlen(creds->service)); |
{ |
buffer_put_char(&b, '\0'); |
u_int endTime; |
buffer_append(&b, creds->instance, strlen(creds->instance)); |
endTime = (u_int) krb_life_to_time(creds->issue_date, |
buffer_put_char(&b, '\0'); |
creds->lifetime); |
buffer_append(&b, creds->realm, strlen(creds->realm)); |
PUTLONG(endTime, p); |
buffer_put_char(&b, '\0'); |
} |
buffer_append(&b, creds->pname, strlen(creds->pname)); |
|
buffer_put_char(&b, '\0'); |
|
buffer_append(&b, creds->pinst, strlen(creds->pinst)); |
|
buffer_put_char(&b, '\0'); |
|
|
memcpy(p, &creds->session, sizeof(creds->session)); |
/* Null string to repeat the realm. */ |
p += sizeof(creds->session); |
buffer_put_char(&b, '\0'); |
|
|
PUTSHORT(creds->kvno, p); |
buffer_put_int(&b, creds->issue_date); |
PUTLONG(creds->ticket_st.length, p); |
buffer_put_int(&b, krb_life_to_time(creds->issue_date, |
|
creds->lifetime)); |
|
buffer_append(&b, creds->session, sizeof(creds->session)); |
|
buffer_put_short(&b, creds->kvno); |
|
|
memcpy(p, creds->ticket_st.dat, creds->ticket_st.length); |
/* 32 bit size + data */ |
p += creds->ticket_st.length; |
buffer_put_string(&b, creds->ticket_st.dat, creds->ticket_st.length); |
len = p - temp; |
|
|
|
return (uuencode((u_char *)temp, len, (char *)buf, buflen)); |
ret = uuencode(buffer_ptr(&b), buffer_len(&b), (char *)buf, buflen); |
|
|
|
buffer_free(&b); |
|
return ret; |
} |
} |
|
|
|
#define GETSTRING(b, t, tlen) \ |
|
do { \ |
|
int i, found = 0; \ |
|
for (i = 0; i < tlen; i++) { \ |
|
if (buffer_len(b) == 0) \ |
|
goto done; \ |
|
t[i] = buffer_get_char(b); \ |
|
if (t[i] == '\0') { \ |
|
found = 1; \ |
|
break; \ |
|
} \ |
|
} \ |
|
if (!found) \ |
|
goto done; \ |
|
} while(0) |
|
|
int |
int |
radix_to_creds(const char *buf, CREDENTIALS *creds) |
radix_to_creds(const char *buf, CREDENTIALS *creds) |
{ |
{ |
|
Buffer b; |
|
char c, version, *space, *p; |
|
u_int endTime; |
|
int len, blen, ret; |
|
|
char *p; |
ret = 0; |
int len, tl; |
blen = strlen(buf); |
char version; |
|
char temp[2048]; |
|
|
|
len = uudecode(buf, (u_char *)temp, sizeof(temp)); |
/* sanity check for size */ |
if (len < 0) |
if (blen > 8192) |
return 0; |
return 0; |
|
|
p = temp; |
buffer_init(&b); |
|
space = buffer_append_space(&b, blen); |
|
|
/* check version and length! */ |
/* check version and length! */ |
|
len = uudecode(buf, space, blen); |
if (len < 1) |
if (len < 1) |
return 0; |
goto done; |
version = *p; |
|
p++; |
|
len--; |
|
|
|
GETSTRING(creds->service, p, len); |
version = buffer_get_char(&b); |
GETSTRING(creds->instance, p, len); |
|
GETSTRING(creds->realm, p, len); |
|
|
|
GETSTRING(creds->pname, p, len); |
GETSTRING(&b, creds->service, sizeof creds->service); |
GETSTRING(creds->pinst, p, len); |
GETSTRING(&b, creds->instance, sizeof creds->instance); |
/* Ignore possibly different realm. */ |
GETSTRING(&b, creds->realm, sizeof creds->realm); |
while (*p && len) |
GETSTRING(&b, creds->pname, sizeof creds->pname); |
p++, len--; |
GETSTRING(&b, creds->pinst, sizeof creds->pinst); |
if (len == 0) |
|
return 0; |
|
p++, len--; |
|
|
|
/* Enough space for remaining fixed-length parts? */ |
if (buffer_len(&b) == 0) |
if (len < (4 + 4 + sizeof(creds->session) + 2 + 4)) |
goto done; |
return 0; |
|
|
|
GETLONG(creds->issue_date, p); |
/* Ignore possibly different realm. */ |
len -= 4; |
while (buffer_len(&b) > 0 && (c = buffer_get_char(&b)) != '\0') |
{ |
; |
u_int endTime; |
|
GETLONG(endTime, p); |
|
len -= 4; |
|
creds->lifetime = krb_time_to_life(creds->issue_date, endTime); |
|
} |
|
|
|
memcpy(&creds->session, p, sizeof(creds->session)); |
if (buffer_len(&b) == 0) |
p += sizeof(creds->session); |
goto done; |
len -= sizeof(creds->session); |
|
|
|
GETSHORT(creds->kvno, p); |
creds->issue_date = buffer_get_int(&b); |
len -= 2; |
|
GETLONG(creds->ticket_st.length, p); |
|
len -= 4; |
|
|
|
tl = creds->ticket_st.length; |
endTime = buffer_get_int(&b); |
if (tl < 0 || tl > len || tl > sizeof(creds->ticket_st.dat)) |
creds->lifetime = krb_time_to_life(creds->issue_date, endTime); |
return 0; |
|
|
|
memcpy(creds->ticket_st.dat, p, tl); |
len = buffer_len(&b); |
p += tl; |
if (len < sizeof(creds->session)) |
len -= tl; |
goto done; |
|
memcpy(&creds->session, buffer_ptr(&b), sizeof(creds->session)); |
|
buffer_consume(&b, sizeof(creds->session)); |
|
|
return 1; |
creds->kvno = buffer_get_short(&b); |
|
|
|
p = buffer_get_string(&b, &len); |
|
if (len < 0 || len > sizeof(creds->ticket_st.dat)) |
|
goto done; |
|
memcpy(&creds->ticket_st.dat, p, len); |
|
creds->ticket_st.length = len; |
|
|
|
ret = 1; |
|
done: |
|
buffer_free(&b); |
|
return ret; |
} |
} |
#endif /* AFS */ |
#endif /* AFS */ |