Lots of random changes.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@1107 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -8,7 +8,9 @@ lib_LIBRARIES = krb5
|
||||
|
||||
krb5_SOURCES = cache.c config_file.y constants.c context.c data.c \
|
||||
get_addrs.c get_cred.c get_in_tkt.c get_in_tkt_pw.c get_port.c \
|
||||
krbhst.c misc.c principal.c principal_p.c send_to_kdc.c str2key.c
|
||||
krbhst.c misc.c principal.c principal_p.c send_to_kdc.c str2key.c \
|
||||
mit-crc.c build_ap_req.c build_auth.c mk_req.c get_host_realm.c \
|
||||
auth_context.c rd_rep.c keytab.c
|
||||
|
||||
config_file.c: config_file.y
|
||||
$(YACC) -p __k5cf_ $<
|
||||
|
27
lib/krb5/auth_context.c
Normal file
27
lib/krb5/auth_context.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "krb5_locl.h"
|
||||
|
||||
krb5_error_code
|
||||
krb5_auth_con_init(krb5_context context,
|
||||
krb5_auth_context **auth_context)
|
||||
{
|
||||
krb5_auth_context *p;
|
||||
p = ALLOC(1, krb5_auth_context);;
|
||||
if(!p)
|
||||
return ENOMEM;
|
||||
memset(p, 0, sizeof(p));
|
||||
p->authenticator = ALLOC(1, krb5_authenticator);
|
||||
if (!p->authenticator)
|
||||
return ENOMEM;
|
||||
*auth_context = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_auth_con_free(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
krb5_flags flags)
|
||||
{
|
||||
free (auth_context->authenticator);
|
||||
free (auth_context);
|
||||
return 0;
|
||||
}
|
60
lib/krb5/build_ap_req.c
Normal file
60
lib/krb5/build_ap_req.c
Normal file
@@ -0,0 +1,60 @@
|
||||
#include <krb5_locl.h>
|
||||
#include <krb5_error.h>
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_ap_req (krb5_context context,
|
||||
krb5_creds *cred,
|
||||
krb5_flags ap_options,
|
||||
krb5_data authenticator,
|
||||
krb5_data *ret)
|
||||
{
|
||||
AP_REQ ap;
|
||||
Ticket t;
|
||||
des_cblock key;
|
||||
des_key_schedule schedule;
|
||||
u_int32_t crc;
|
||||
unsigned char *p;
|
||||
unsigned char buf[1024];
|
||||
|
||||
ap.pvno = 5;
|
||||
ap.msg_type = krb_ap_req;
|
||||
memset(&ap.ap_options, 0, sizeof(ap.ap_options));
|
||||
if (ap_options & AP_OPTS_USE_SESSION_KEY)
|
||||
ap.ap_options.use_session_key = 1;
|
||||
if (ap_options & AP_OPTS_MUTUAL_REQUIRED)
|
||||
ap.ap_options.mutual_required = 1;
|
||||
|
||||
ap.ticket.tkt_vno = 5;
|
||||
ap.ticket.realm = malloc(cred->server->realm.length + 1);
|
||||
strncpy(ap.ticket.realm, cred->server->realm.data,
|
||||
cred->server->realm.length);
|
||||
ap.ticket.realm[cred->server->realm.length] = '\0';
|
||||
krb5_principal2principalname(&ap.ticket.sname, cred->server);
|
||||
|
||||
decode_Ticket(cred->ticket.data, cred->ticket.length, &t);
|
||||
|
||||
ap.ticket.enc_part.etype = t.enc_part.etype;
|
||||
ap.ticket.enc_part.kvno = NULL;
|
||||
ap.ticket.enc_part.cipher = t.enc_part.cipher;
|
||||
|
||||
memcpy(&key, cred->session.contents.data, sizeof(key));
|
||||
des_set_key (&key, schedule);
|
||||
|
||||
/* authenticator */
|
||||
|
||||
des_cbc_encrypt (authenticator.data,
|
||||
authenticator.data,
|
||||
authenticator.length,
|
||||
schedule, &key, DES_ENCRYPT);
|
||||
|
||||
ap.authenticator.etype = ap.ticket.enc_part.etype;
|
||||
ap.authenticator.kvno = NULL;
|
||||
ap.authenticator.cipher = authenticator;
|
||||
|
||||
ret->length = encode_AP_REQ(buf + sizeof(buf) - 1, sizeof(buf), &ap);
|
||||
|
||||
ret->data = malloc(ret->length);
|
||||
memcpy (ret->data, buf + sizeof(buf) - ret->length, ret->length);
|
||||
|
||||
return 0;
|
||||
}
|
52
lib/krb5/build_auth.c
Normal file
52
lib/krb5/build_auth.c
Normal file
@@ -0,0 +1,52 @@
|
||||
#include <krb5_locl.h>
|
||||
#include <krb5_error.h>
|
||||
#include <md4.h>
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_authenticator (krb5_context context,
|
||||
krb5_principal client,
|
||||
Checksum *cksum,
|
||||
Authenticator **auth_result,
|
||||
krb5_data *result)
|
||||
{
|
||||
struct timeval tv;
|
||||
Authenticator *auth = malloc(sizeof(*auth));
|
||||
char buf[1024];
|
||||
unsigned char *p;
|
||||
int len;
|
||||
struct md4 m;
|
||||
u_int32_t crc;
|
||||
|
||||
if (auth_result)
|
||||
*auth_result = auth;
|
||||
auth->authenticator_vno = 5;
|
||||
auth->crealm = malloc(client->realm.length + 1);
|
||||
strncpy(auth->crealm, client->realm.data, client->realm.length);
|
||||
auth->crealm[client->realm.length] = '\0';
|
||||
krb5_principal2principalname(&auth->cname, client);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
auth->cusec = tv.tv_usec;
|
||||
auth->ctime = tv.tv_sec;
|
||||
auth->subkey = NULL;
|
||||
auth->seq_number = NULL;
|
||||
auth->authorization_data = NULL;
|
||||
auth->cksum = cksum;
|
||||
|
||||
memset (buf, 0, sizeof(buf));
|
||||
len = encode_Authenticator(buf + sizeof(buf) - 9,
|
||||
sizeof(buf) - 8 - 12,
|
||||
auth);
|
||||
p = buf + sizeof(buf) - 8 - len;
|
||||
|
||||
p -= 12;
|
||||
len += 12;
|
||||
len = (len + 7) & ~7;
|
||||
crc_init_table ();
|
||||
crc = crc_update(p, len, 0);
|
||||
memcpy(p + 8, &crc, 4);
|
||||
result->length = len;
|
||||
result->data = malloc(len);
|
||||
memcpy(result->data, p, len);
|
||||
return 0;
|
||||
}
|
@@ -246,7 +246,7 @@ store_keyblock(int fd, krb5_keyblock p)
|
||||
static krb5_error_code
|
||||
ret_keyblock(int fd, krb5_keyblock *p)
|
||||
{
|
||||
ret_int32(fd, (int32_t*)&p->keytype);
|
||||
ret_int32(fd, (int32_t*)&p->keytype); /* keytype + etype */
|
||||
ret_data(fd, &p->contents);
|
||||
return 0;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ ret_times(int fd, krb5_times *times)
|
||||
static krb5_error_code
|
||||
store_address(int fd, krb5_address p)
|
||||
{
|
||||
store_int32(fd, p.type);
|
||||
store_int16(fd, p.type);
|
||||
store_data(fd, p.address);
|
||||
return 0;
|
||||
}
|
||||
@@ -282,7 +282,7 @@ store_address(int fd, krb5_address p)
|
||||
static krb5_error_code
|
||||
ret_address(int fd, krb5_address *adr)
|
||||
{
|
||||
ret_int32(fd, (int32_t*)&adr->type);
|
||||
ret_int16(fd, (int16_t*)&adr->type);
|
||||
ret_data(fd, &adr->address);
|
||||
return 0;
|
||||
}
|
||||
@@ -308,20 +308,6 @@ ret_addrs(int fd, krb5_addresses *adr)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
store_ticket(int fd, krb5_ticket p)
|
||||
{
|
||||
store_data(fd, p.enc_part);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
ret_ticket(int fd, krb5_ticket *tkt)
|
||||
{
|
||||
ret_data(fd, &tkt->enc_part);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
store_authdata(int fd, krb5_data p)
|
||||
{
|
||||
@@ -430,8 +416,8 @@ krb5_cc_store_cred(krb5_context context,
|
||||
store_int32(fd, 0); /* flags */
|
||||
store_addrs(fd, creds->addresses);
|
||||
store_authdata(fd, creds->authdata);
|
||||
store_ticket(fd, creds->ticket);
|
||||
store_ticket(fd, creds->second_ticket);
|
||||
store_data(fd, creds->ticket);
|
||||
store_data(fd, creds->second_ticket);
|
||||
close(fd);
|
||||
return 0; /* XXX */
|
||||
}
|
||||
@@ -440,19 +426,30 @@ static krb5_error_code
|
||||
krb5_cc_read_cred (int fd,
|
||||
krb5_creds *creds)
|
||||
{
|
||||
int ret;
|
||||
int8_t dummy8;
|
||||
int32_t dummy32;
|
||||
|
||||
return ret_principal (fd, &creds->client) ||
|
||||
ret_principal (fd, &creds->server) ||
|
||||
ret_keyblock (fd, &creds->session) ||
|
||||
ret_times (fd, &creds->times) ||
|
||||
ret_int8 (fd, &dummy8) ||
|
||||
ret_int32 (fd, &dummy32) ||
|
||||
ret_addrs (fd, &creds->addresses) ||
|
||||
ret_authdata (fd, &creds->authdata) ||
|
||||
ret_ticket (fd, &creds->ticket) ||
|
||||
ret_ticket (fd, &creds->second_ticket);
|
||||
ret = ret_principal (fd, &creds->client);
|
||||
if(ret) return ret;
|
||||
ret = ret_principal (fd, &creds->server);
|
||||
if(ret) return ret;
|
||||
ret = ret_keyblock (fd, &creds->session);
|
||||
if(ret) return ret;
|
||||
ret = ret_times (fd, &creds->times);
|
||||
if(ret) return ret;
|
||||
ret = ret_int8 (fd, &dummy8);
|
||||
if(ret) return ret;
|
||||
ret = ret_int32 (fd, &dummy32);
|
||||
if(ret) return ret;
|
||||
ret = ret_addrs (fd, &creds->addresses);
|
||||
if(ret) return ret;
|
||||
ret = ret_authdata (fd, &creds->authdata);
|
||||
if(ret) return ret;
|
||||
ret = ret_data (fd, &creds->ticket);
|
||||
if(ret) return ret;
|
||||
ret = ret_data (fd, &creds->second_ticket);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -462,7 +459,17 @@ krb5_cc_retrieve_cred(krb5_context context,
|
||||
krb5_creds *mcreds,
|
||||
krb5_creds *creds)
|
||||
{
|
||||
return 0; /* XXX */
|
||||
krb5_error_code ret;
|
||||
krb5_cc_cursor cursor;
|
||||
krb5_cc_get_first(context, id, &cursor);
|
||||
while((ret = krb5_cc_get_next(context, id, creds, &cursor)) == 0){
|
||||
if(krb5_principal_compare(context, mcreds->server, creds->server)){
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
krb5_cc_end_get(context, id, &cursor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -527,7 +534,15 @@ krb5_cc_get_first(krb5_context context,
|
||||
krb5_ccache id,
|
||||
krb5_cc_cursor *cursor)
|
||||
{
|
||||
return 0; /* XXX */
|
||||
int fd;
|
||||
int16_t tag;
|
||||
krb5_principal principal;
|
||||
|
||||
fd = open(krb5_cc_get_name (context, id), O_RDONLY);
|
||||
cursor->fd = fd;
|
||||
ret_int16(fd, &tag);
|
||||
ret_principal(fd, &principal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -536,7 +551,7 @@ krb5_cc_get_next(krb5_context context,
|
||||
krb5_creds *creds,
|
||||
krb5_cc_cursor *cursor)
|
||||
{
|
||||
return 0; /* XXX */
|
||||
return krb5_cc_read_cred(cursor->fd, creds);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
@@ -544,7 +559,8 @@ krb5_cc_end_get(krb5_context context,
|
||||
krb5_ccache id,
|
||||
krb5_cc_cursor *cursor)
|
||||
{
|
||||
return 0; /* XXX */
|
||||
close(cursor->fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
|
33
lib/krb5/crc.c
Normal file
33
lib/krb5/crc.c
Normal file
@@ -0,0 +1,33 @@
|
||||
#include <stdio.h>
|
||||
#include "crc.h"
|
||||
|
||||
static u_long table[256];
|
||||
|
||||
void
|
||||
crc_init_table( )
|
||||
{
|
||||
unsigned long crc, poly;
|
||||
int i, j;
|
||||
|
||||
poly = 0xEDB88320L;
|
||||
for (i = 0; i < 256; i++) {
|
||||
crc = i;
|
||||
for (j = 8; j > 0; j--) {
|
||||
if (crc & 1) {
|
||||
crc = (crc >> 1) ^ poly;
|
||||
} else {
|
||||
crc >>= 1;
|
||||
}
|
||||
}
|
||||
table[i] = crc;
|
||||
}
|
||||
}
|
||||
|
||||
u_long
|
||||
crc_update (char *p, size_t len, u_long res)
|
||||
{
|
||||
res ^= 0xFFFFFFFF;
|
||||
while (len--)
|
||||
res = table[(res ^ *p++) & 0xFF] ^ (res >> 8);
|
||||
return res & 0xFFFFFFFF;
|
||||
}
|
6
lib/krb5/crc.h
Normal file
6
lib/krb5/crc.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
#define CRC_GEN 0xEDB88320L
|
||||
|
||||
void crc_init_table ();
|
||||
u_long crc_update (char *p, size_t len, u_long res);
|
@@ -1,82 +1,316 @@
|
||||
#include <krb5_locl.h>
|
||||
#include <krb5_error.h>
|
||||
#include <md4.h>
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
key_proc (krb5_context context,
|
||||
krb5_keytype type,
|
||||
krb5_data *salt,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
*key = malloc (sizeof (**key));
|
||||
if (*key == NULL)
|
||||
return ENOMEM;
|
||||
(*key)->keytype = type;
|
||||
(*key)->contents.length = 8;
|
||||
(*key)->contents.data = malloc(8);
|
||||
memcpy((*key)->contents.data, keyseed, 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
extract_ticket(krb5_context context,
|
||||
krb5_kdc_rep *rep,
|
||||
krb5_creds **creds,
|
||||
krb5_key_proc key_proc,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_decrypt_proc decrypt_proc,
|
||||
krb5_const_pointer decryptarg);
|
||||
|
||||
|
||||
krb5_error_code
|
||||
krb5_get_credentials (krb5_context context,
|
||||
krb5_flags options,
|
||||
krb5_ccache ccache,
|
||||
krb5_creds *in_creds,
|
||||
krb5_creds *out_creds)
|
||||
krb5_creds **out_creds)
|
||||
{
|
||||
return 17;
|
||||
}
|
||||
krb5_error_code err;
|
||||
TGS_REQ a;
|
||||
Authenticator auth;
|
||||
krb5_data authenticator;
|
||||
Checksum c;
|
||||
AP_REQ ap;
|
||||
krb5_kdc_rep rep;
|
||||
KRB_ERROR error;
|
||||
krb5_data req, resp;
|
||||
char buf[BUFSIZ];
|
||||
int i;
|
||||
unsigned char data[1024], buf2[1024];
|
||||
int len;
|
||||
|
||||
PA_DATA foo;
|
||||
|
||||
|
||||
des_key_schedule schedule;
|
||||
des_cblock key;
|
||||
|
||||
/*
|
||||
* XXX - Check if cred found in ccache
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prepare Tgs_Req.
|
||||
*/
|
||||
|
||||
err = krb5_get_default_in_tkt_etypes (context,
|
||||
(krb5_enctype**)&a.req_body.etype.val);
|
||||
if (err)
|
||||
return err;
|
||||
a.req_body.etype.len = 1;
|
||||
|
||||
|
||||
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
|
||||
|
||||
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
a.pvno = 5;
|
||||
a.msg_type = krb_tgs_req;
|
||||
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
|
||||
/* a.kdc_options */
|
||||
|
||||
a.req_body.realm = malloc(in_creds->server->realm.length + 1);
|
||||
strncpy (a.req_body.realm, in_creds->server->realm.data,
|
||||
in_creds->server->realm.length);
|
||||
a.req_body.realm[in_creds->server->realm.length] = '\0';
|
||||
|
||||
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
|
||||
krb5_principal2principalname(a.req_body.sname, in_creds->server);
|
||||
a.req_body.from = NULL;
|
||||
a.req_body.till = in_creds->times.endtime;
|
||||
a.req_body.rtime = NULL;
|
||||
a.req_body.nonce = getpid();
|
||||
a.req_body.additional_tickets = NULL;
|
||||
a.req_body.enc_authorization_data = NULL;
|
||||
|
||||
{
|
||||
char buf[1024];
|
||||
int len;
|
||||
struct md4 m;
|
||||
Checksum c;
|
||||
|
||||
len = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
|
||||
&a.req_body);
|
||||
md4_init(&m);
|
||||
md4_update(&m, buf + sizeof(buf) - len, len);
|
||||
c.cksumtype = rsa_md4;
|
||||
c.checksum.length = 16;
|
||||
c.checksum.data = malloc(16);
|
||||
md4_finito(&m, c.checksum.data);
|
||||
krb5_build_authenticator (context, in_creds->client,
|
||||
&c, NULL, &authenticator);
|
||||
}
|
||||
|
||||
#if 0
|
||||
{
|
||||
struct timeval tv;
|
||||
auth.authenticator_vno = 5;
|
||||
krb5_cc_get_principal(context, ccache, &out_creds->client);
|
||||
|
||||
krb5_error_code err;
|
||||
Tgs_Req a;
|
||||
krb5_kdc_rep rep;
|
||||
krb5_data req, resp;
|
||||
char buf[BUFSIZ];
|
||||
int i;
|
||||
Buffer buffer;
|
||||
|
||||
/*
|
||||
* XXX - Check if cred found in ccache
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prepare Tgs_Req.
|
||||
*/
|
||||
|
||||
err = krb5_get_default_in_tkt_etypes (context, &a.etypes);
|
||||
if (err)
|
||||
return err;
|
||||
a.num_etypes = 1;
|
||||
|
||||
err = krb5_get_all_client_addrs (&a.addrs);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
a.pvno = 5;
|
||||
a.msg_type = KRB_TGS_REQ;
|
||||
memset (&a.kdc_options, 0, sizeof(a.kdc_options));
|
||||
/* a.kdc_options */
|
||||
a.realm.length = 0;
|
||||
krb5_data_copy (&a.realm, in_creds->server->realm.data,
|
||||
in_creds->server->realm.length);
|
||||
krb5_copy_principal (context, in_creds->server, &a.sname);
|
||||
a.till = in_creds->times.endtime;
|
||||
a.nonce = 17;
|
||||
a.cname = NULL;
|
||||
|
||||
/*
|
||||
* Encode
|
||||
*/
|
||||
|
||||
req.length = der_put_as_req (buf + sizeof (buf) - 1, &a);
|
||||
req.data = buf + sizeof(buf) - req.length;
|
||||
|
||||
for (i = 0; i < a.addrs.number; ++i)
|
||||
krb5_data_free (&a.addrs.addrs[i].address);
|
||||
free (a.addrs.addrs);
|
||||
|
||||
/*
|
||||
* Send and receive
|
||||
*/
|
||||
|
||||
err = krb5_sendto_kdc (context, &req, &a.realm, &resp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
buf_init (&buffer, resp.data, resp.length);
|
||||
if (der_get_tgs_rep (&buffer, &rep) == -1) {
|
||||
return ASN1_PARSE_ERROR;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
auth.crealm = malloc(out_creds->client->realm.length + 1);
|
||||
strncpy (auth.crealm, out_creds->client->realm.data,
|
||||
out_creds->client->realm.length);
|
||||
auth.crealm[out_creds->client->realm.length] = 0;
|
||||
krb5_principal2principalname(&auth.cname, out_creds->client);
|
||||
gettimeofday(&tv, NULL);
|
||||
{
|
||||
char buf[1024];
|
||||
int len;
|
||||
struct md4 m;
|
||||
len = encode_KDC_REQ_BODY(buf + sizeof(buf) - 1, sizeof(buf),
|
||||
&a.req_body);
|
||||
md4_init(&m);
|
||||
md4_update(&m, buf + sizeof(buf) - len, len);
|
||||
c.cksumtype = rsa_md4;
|
||||
c.checksum.length = 16;
|
||||
c.checksum.data = malloc(16);
|
||||
md4_finito(&m, c.checksum.data);
|
||||
auth.cksum = &c;
|
||||
}
|
||||
auth.cusec = tv.tv_usec;
|
||||
auth.ctime = tv.tv_sec;
|
||||
auth.subkey = NULL;
|
||||
auth.seq_number = NULL;
|
||||
auth.authorization_data = NULL;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/*
|
||||
AP-REQ ::= [APPLICATION 14] SEQUENCE {
|
||||
pvno[0] INTEGER,
|
||||
msg-type[1] INTEGER,
|
||||
ap-options[2] APOptions,
|
||||
ticket[3] Ticket,
|
||||
authenticator[4] EncryptedData
|
||||
}
|
||||
*/
|
||||
{
|
||||
krb5_creds cred, mcred;
|
||||
ap.pvno = 5;
|
||||
ap.msg_type = krb_ap_req;
|
||||
memset(&ap.ap_options, 0, sizeof(ap.ap_options));
|
||||
/* ap.ap_options.use_session_key = 1;*/
|
||||
krb5_build_principal(context, &mcred.server,
|
||||
out_creds->client.realm.length,
|
||||
out_creds->client.realm.data,
|
||||
"krbtgt", a.req_body.realm, NULL);
|
||||
krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
|
||||
|
||||
/*
|
||||
tkt-vno[0] INTEGER,
|
||||
realm[1] Realm,
|
||||
sname[2] PrincipalName,
|
||||
enc-part[3] EncryptedData
|
||||
*/
|
||||
ap.ticket.tkt_vno = 5;
|
||||
ap.ticket.realm = (char*)malloc(cred.server->realm.length + 1);
|
||||
strncpy(ap.ticket.realm, cred.server->realm.data,
|
||||
cred.server->realm.length);
|
||||
ap.ticket.realm[cred.server->realm.length] = 0;
|
||||
krb5_principal2principalname(&ap.ticket.sname, cred.server);
|
||||
|
||||
{
|
||||
Ticket t;
|
||||
decode_Ticket(cred.ticket.data,
|
||||
cred.ticket.length,
|
||||
&t);
|
||||
|
||||
ap.ticket.enc_part.etype = t.enc_part.etype;
|
||||
ap.ticket.enc_part.kvno = NULL;
|
||||
ap.ticket.enc_part.cipher = t.enc_part.cipher;
|
||||
}
|
||||
memcpy(&key, cred.session.contents.data, sizeof(key));
|
||||
des_set_key(cred.session.contents.data, schedule);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
{
|
||||
u_int32_t crc;
|
||||
unsigned char *p;
|
||||
|
||||
memset(data, 0, sizeof(data));
|
||||
len = encode_Authenticator(data + sizeof(data) - 9,
|
||||
sizeof(data) - 8 - 12, &auth);
|
||||
p = data + sizeof(data) - 8 - len;
|
||||
|
||||
p -= 12;
|
||||
len += 12;
|
||||
len = (len + 7) & ~7;
|
||||
crc_init_table();
|
||||
crc = crc_update(p, len, 0);
|
||||
/* crc = htonl(crc); */
|
||||
memcpy(p + 8, &crc, 4);
|
||||
#if 0
|
||||
des_cbc_encrypt((void*)p, (void*)p, len, schedule, &key, DES_ENCRYPT);
|
||||
#endif
|
||||
#if 0
|
||||
ap.authenticator.etype = ap.ticket.enc_part.etype;
|
||||
ap.authenticator.kvno = NULL;
|
||||
ap.authenticator.cipher.data = p; /* p */
|
||||
ap.authenticator.cipher.length = len; /* len */
|
||||
#endif
|
||||
|
||||
authenticator.data = p;
|
||||
authenticator.length = len;
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
krb5_creds cred, mcred;
|
||||
|
||||
krb5_build_principal(context, &mcred.server,
|
||||
in_creds->client->realm.length,
|
||||
in_creds->client->realm.data,
|
||||
"krbtgt", a.req_body.realm, NULL);
|
||||
krb5_cc_retrieve_cred(context, ccache, 0, &mcred, &cred);
|
||||
memcpy(&key, cred.session.contents.data, sizeof(key));
|
||||
|
||||
foo.padata_type = pa_tgs_req;
|
||||
err = krb5_build_ap_req(context, &cred,
|
||||
0,
|
||||
authenticator,
|
||||
&foo.padata_value);
|
||||
if(err)
|
||||
return err;
|
||||
}
|
||||
|
||||
a.padata = malloc(sizeof(*a.padata));
|
||||
a.padata->len = 1;
|
||||
a.padata->val = &foo;
|
||||
|
||||
|
||||
#if 0
|
||||
foo.padata_value.length = encode_AP_REQ(buf2 + sizeof(buf2) - 1,
|
||||
sizeof(buf2), &ap);
|
||||
foo.padata_value.data = buf2 + sizeof(buf2) - foo.padata_value.length;
|
||||
a.padata = malloc(sizeof(*a.padata));
|
||||
a.padata->len = 1;
|
||||
a.padata->val = &foo;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encode
|
||||
*/
|
||||
|
||||
req.length = encode_TGS_REQ (buf + sizeof (buf) - 1, sizeof(buf), &a);
|
||||
req.data = buf + sizeof(buf) - req.length;
|
||||
|
||||
for (i = 0; i < a.req_body.addresses->len; ++i)
|
||||
krb5_data_free (&a.req_body.addresses->val[i].address);
|
||||
free (a.req_body.addresses->val);
|
||||
|
||||
/*
|
||||
* Send and receive
|
||||
*/
|
||||
|
||||
{
|
||||
TGS_REQ xx;
|
||||
decode_TGS_REQ (req.data, req.length, &xx);
|
||||
req.length = req.length;
|
||||
}
|
||||
|
||||
err = krb5_sendto_kdc (context, &req, &in_creds->server->realm, &resp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
switch(((unsigned char*)resp.data)[0] & 0x1f){
|
||||
case krb_error:
|
||||
len = decode_TGS_REP(resp.data, resp.length, &error);
|
||||
if(len < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
break;
|
||||
case krb_tgs_rep:
|
||||
len = decode_TGS_REP(resp.data, resp.length, &rep.part1);
|
||||
if(len < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
out_creds = malloc(sizeof(*out_creds));
|
||||
*out_creds = NULL;
|
||||
err = extract_ticket(context, &rep, *out_creds, key_proc, key, NULL, NULL);
|
||||
if(err)
|
||||
return err;
|
||||
return krb5_cc_store_cred (context, ccache, out_creds);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
12
lib/krb5/get_host_realm.c
Normal file
12
lib/krb5/get_host_realm.c
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "krb5_locl.h"
|
||||
|
||||
krb5_error_code
|
||||
krb5_get_host_realm(krb5_context context,
|
||||
const char *host,
|
||||
char ***realms)
|
||||
{
|
||||
*realms = malloc(2 * sizeof(char*));
|
||||
(*realms)[0] = strdup("FOO.SE");
|
||||
(*realms)[1] = NULL;
|
||||
return 0;
|
||||
}
|
@@ -6,25 +6,25 @@ krb5_get_salt (krb5_principal princ,
|
||||
krb5_data realm,
|
||||
krb5_data *salt)
|
||||
{
|
||||
size_t len;
|
||||
int i;
|
||||
krb5_error_code err;
|
||||
char *p;
|
||||
size_t len;
|
||||
int i;
|
||||
krb5_error_code err;
|
||||
char *p;
|
||||
|
||||
len = realm.length;
|
||||
for (i = 0; i < princ->ncomp; ++i)
|
||||
len += princ->comp[i].length;
|
||||
err = krb5_data_alloc (salt, len);
|
||||
if (err)
|
||||
return err;
|
||||
p = salt->data;
|
||||
strncpy (p, realm.data, realm.length);
|
||||
p += realm.length;
|
||||
for (i = 0; i < princ->ncomp; ++i) {
|
||||
strncpy (p, princ->comp[i].data, princ->comp[i].length);
|
||||
p += princ->comp[i].length;
|
||||
}
|
||||
return 0;
|
||||
len = realm.length;
|
||||
for (i = 0; i < princ->ncomp; ++i)
|
||||
len += princ->comp[i].length;
|
||||
err = krb5_data_alloc (salt, len);
|
||||
if (err)
|
||||
return err;
|
||||
p = salt->data;
|
||||
strncpy (p, realm.data, realm.length);
|
||||
p += realm.length;
|
||||
for (i = 0; i < princ->ncomp; ++i) {
|
||||
strncpy (p, princ->comp[i].data, princ->comp[i].length);
|
||||
p += princ->comp[i].length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
@@ -33,28 +33,28 @@ decrypt_tkt (krb5_context context,
|
||||
krb5_const_pointer decrypt_arg,
|
||||
krb5_kdc_rep *dec_rep)
|
||||
{
|
||||
des_key_schedule sched;
|
||||
char *buf;
|
||||
int i;
|
||||
int len = dec_rep->part1.enc_part.cipher.length;
|
||||
des_key_schedule sched;
|
||||
char *buf;
|
||||
int i;
|
||||
int len = dec_rep->part1.enc_part.cipher.length;
|
||||
|
||||
des_set_key (key->contents.data, sched);
|
||||
buf = malloc (len);
|
||||
if (buf == NULL)
|
||||
return ENOMEM;
|
||||
des_cbc_encrypt ((des_cblock *)dec_rep->part1.enc_part.cipher.data,
|
||||
(des_cblock *)buf,
|
||||
len,
|
||||
sched,
|
||||
key->contents.data,
|
||||
DES_DECRYPT);
|
||||
/* XXX: Check CRC */
|
||||
des_set_key (key->contents.data, sched);
|
||||
buf = malloc (len);
|
||||
if (buf == NULL)
|
||||
return ENOMEM;
|
||||
des_cbc_encrypt ((des_cblock *)dec_rep->part1.enc_part.cipher.data,
|
||||
(des_cblock *)buf,
|
||||
len,
|
||||
sched,
|
||||
key->contents.data,
|
||||
DES_DECRYPT);
|
||||
/* XXX: Check CRC */
|
||||
|
||||
i = decode_EncTGSRepPart((unsigned char*)buf + 12, len - 12, &dec_rep->part2);
|
||||
free (buf);
|
||||
if (i < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
return 0;
|
||||
i = decode_EncTGSRepPart((unsigned char*)buf + 12, len - 12, &dec_rep->part2);
|
||||
free (buf);
|
||||
if (i < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -65,38 +65,149 @@ krb5_error_code
|
||||
krb5_principal2principalname (PrincipalName *p,
|
||||
krb5_principal from)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
|
||||
p->name_type = from->type;
|
||||
p->name_string.len = from->ncomp;
|
||||
p->name_string.val = malloc(from->ncomp * sizeof(*p->name_string.val));
|
||||
for (i = 0; i < from->ncomp; ++i) {
|
||||
int len = from->comp[i].length;
|
||||
p->name_string.val[i] = malloc(len + 1);
|
||||
strncpy (p->name_string.val[i], from->comp[i].data, len);
|
||||
p->name_string.val[i][len] = '\0';
|
||||
}
|
||||
return 0;
|
||||
p->name_type = from->type;
|
||||
p->name_string.len = from->ncomp;
|
||||
p->name_string.val = malloc(from->ncomp * sizeof(*p->name_string.val));
|
||||
for (i = 0; i < from->ncomp; ++i) {
|
||||
int len = from->comp[i].length;
|
||||
p->name_string.val[i] = malloc(len + 1);
|
||||
strncpy (p->name_string.val[i], from->comp[i].data, len);
|
||||
p->name_string.val[i][len] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
principalname2krb5_principal (krb5_principal p,
|
||||
principalname2krb5_principal (krb5_principal *principal,
|
||||
PrincipalName from,
|
||||
krb5_data realm)
|
||||
char *realm)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
krb5_principal p;
|
||||
p = malloc (sizeof(*p));
|
||||
p->type = from.name_type;
|
||||
p->ncomp = from.name_string.len;
|
||||
p->comp = malloc (p->ncomp * sizeof(*p->comp));
|
||||
for (i = 0; i < p->ncomp; ++i) {
|
||||
int len = strlen(from.name_string.val[i]);
|
||||
p->comp[i].length = len;
|
||||
p->comp[i].data = strdup(from.name_string.val[i]);
|
||||
}
|
||||
p->realm.data = strdup(realm);
|
||||
p->realm.length = strlen(realm);
|
||||
*principal = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = malloc (sizeof(*p));
|
||||
p->type = from.name_type;
|
||||
p->ncomp = from.name_string.len;
|
||||
p->comp = malloc (p->ncomp * sizeof(*p->comp));
|
||||
for (i = 0; i < p->ncomp; ++i) {
|
||||
int len = strlen(from.name_string.val[i]) + 1;
|
||||
p->comp[i].length = len;
|
||||
p->comp[i].data = strdup(from.name_string.val[i]);
|
||||
}
|
||||
p->realm = realm;
|
||||
return 0;
|
||||
|
||||
int
|
||||
extract_ticket(krb5_context context,
|
||||
krb5_kdc_rep *rep,
|
||||
krb5_creds *creds,
|
||||
krb5_key_proc key_proc,
|
||||
krb5_const_pointer keyseed,
|
||||
krb5_decrypt_proc decrypt_proc,
|
||||
krb5_const_pointer decryptarg)
|
||||
{
|
||||
krb5_keyblock *key;
|
||||
krb5_error_code err;
|
||||
krb5_data salt;
|
||||
|
||||
principalname2krb5_principal(&creds->client,
|
||||
rep->part1.cname,
|
||||
rep->part1.crealm);
|
||||
free (rep->part1.crealm);
|
||||
/* krb5_principal_free (rep.part1.cname);*/
|
||||
{
|
||||
char buf[1024];
|
||||
int len;
|
||||
len = encode_Ticket(buf + sizeof(buf) - 1, sizeof(buf),
|
||||
&rep->part1.ticket);
|
||||
creds->ticket.data = malloc(len);
|
||||
memcpy(creds->ticket.data, buf + sizeof(buf) - len, len);
|
||||
creds->ticket.length = len;
|
||||
creds->second_ticket.length = 0;
|
||||
}
|
||||
/* krb5_free_principal (rep->part1.ticket.sprinc);*/
|
||||
|
||||
salt.length = 0;
|
||||
salt.data = NULL;
|
||||
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = (*key_proc)(context, rep->part1.enc_part.etype, &salt,
|
||||
keyseed, &key);
|
||||
krb5_data_free (&salt);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (decrypt_proc == NULL)
|
||||
decrypt_proc = decrypt_tkt;
|
||||
|
||||
err = (*decrypt_proc)(context, key, decryptarg, rep);
|
||||
if (err)
|
||||
return err;
|
||||
memset (key->contents.data, 0, key->contents.length);
|
||||
krb5_data_free (&key->contents);
|
||||
free (key);
|
||||
|
||||
principalname2krb5_principal(&creds->server,
|
||||
rep->part1.ticket.sname,
|
||||
rep->part1.ticket.realm);
|
||||
|
||||
if (rep->part2.key_expiration)
|
||||
free (rep->part2.key_expiration);
|
||||
if (rep->part2.starttime) {
|
||||
creds->times.starttime = *rep->part2.starttime;
|
||||
free (rep->part2.starttime);
|
||||
} else
|
||||
creds->times.starttime = rep->part2.authtime;
|
||||
if (rep->part2.renew_till) {
|
||||
creds->times.renew_till = *rep->part2.renew_till;
|
||||
free (rep->part2.renew_till);
|
||||
} else
|
||||
creds->times.renew_till = 0;
|
||||
creds->times.authtime = rep->part2.authtime;
|
||||
creds->times.endtime = rep->part2.endtime;
|
||||
creds->addresses.number = 0;
|
||||
creds->addresses.addrs = NULL;
|
||||
#if 0 /* What? */
|
||||
if (rep->part2.req.values)
|
||||
free (rep->part2.req.values);
|
||||
#endif
|
||||
#if 0
|
||||
if (rep->part2.caddr.addrs) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rep->part2.caddr.number; ++i) {
|
||||
krb5_data_free (&rep->part2.caddr.addrs[i].address);
|
||||
}
|
||||
free (rep->part2.caddr.addrs);
|
||||
}
|
||||
krb5_principal_free (rep->part2.sname);
|
||||
krb5_data_free (&rep->part2.srealm);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
creds->session.contents.length = 0;
|
||||
creds->session.contents.data = NULL;
|
||||
creds->session.keytype = rep->part2.key.keytype;
|
||||
err = krb5_data_copy (&creds->session.contents,
|
||||
rep->part2.key.keyvalue.data,
|
||||
rep->part2.key.keyvalue.length);
|
||||
memset (rep->part2.key.keyvalue.data, 0,
|
||||
rep->part2.key.keyvalue.length);
|
||||
krb5_data_free (&rep->part2.key.keyvalue);
|
||||
creds->authdata.length = 0;
|
||||
creds->authdata.data = NULL;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -117,155 +228,72 @@ krb5_get_in_tkt(krb5_context context,
|
||||
krb5_ccache ccache,
|
||||
krb5_kdc_rep **ret_as_reply)
|
||||
{
|
||||
krb5_error_code err;
|
||||
AS_REQ a;
|
||||
krb5_kdc_rep rep;
|
||||
krb5_data req, resp;
|
||||
char buf[BUFSIZ];
|
||||
krb5_data salt;
|
||||
krb5_keyblock *key;
|
||||
krb5_error_code err;
|
||||
AS_REQ a;
|
||||
krb5_kdc_rep rep;
|
||||
krb5_data req, resp;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
a.pvno = 5;
|
||||
a.msg_type = krb_as_req;
|
||||
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
|
||||
/* a.kdc_options */
|
||||
a.req_body.cname = malloc(sizeof(*a.req_body.cname));
|
||||
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
|
||||
krb5_principal2principalname (a.req_body.cname, creds->client);
|
||||
krb5_principal2principalname (a.req_body.sname, creds->server);
|
||||
a.req_body.realm = malloc(creds->client->realm.length + 1);
|
||||
strncpy (a.req_body.realm, creds->client->realm.data,
|
||||
creds->client->realm.length);
|
||||
a.req_body.realm[creds->client->realm.length] = '\0';
|
||||
a.pvno = 5;
|
||||
a.msg_type = krb_as_req;
|
||||
memset (&a.req_body.kdc_options, 0, sizeof(a.req_body.kdc_options));
|
||||
/* a.kdc_options */
|
||||
a.req_body.cname = malloc(sizeof(*a.req_body.cname));
|
||||
a.req_body.sname = malloc(sizeof(*a.req_body.sname));
|
||||
krb5_principal2principalname (a.req_body.cname, creds->client);
|
||||
krb5_principal2principalname (a.req_body.sname, creds->server);
|
||||
a.req_body.realm = malloc(creds->client->realm.length + 1);
|
||||
strncpy (a.req_body.realm, creds->client->realm.data,
|
||||
creds->client->realm.length);
|
||||
a.req_body.realm[creds->client->realm.length] = '\0';
|
||||
|
||||
a.req_body.till = creds->times.endtime;
|
||||
a.req_body.nonce = 17;
|
||||
if (etypes)
|
||||
abort ();
|
||||
else {
|
||||
err = krb5_get_default_in_tkt_etypes (context,
|
||||
(krb5_enctype**)&a.req_body.etype.val);
|
||||
if (err)
|
||||
return err;
|
||||
a.req_body.etype.len = 1;
|
||||
}
|
||||
if (addrs){
|
||||
} else {
|
||||
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
|
||||
a.req_body.till = creds->times.endtime;
|
||||
a.req_body.nonce = 17;
|
||||
if (etypes)
|
||||
abort ();
|
||||
else {
|
||||
err = krb5_get_default_in_tkt_etypes (context,
|
||||
(krb5_enctype**)&a.req_body.etype.val);
|
||||
if (err)
|
||||
return err;
|
||||
a.req_body.etype.len = 1;
|
||||
}
|
||||
if (addrs){
|
||||
} else {
|
||||
a.req_body.addresses = malloc(sizeof(*a.req_body.addresses));
|
||||
|
||||
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
a.req_body.enc_authorization_data = NULL;
|
||||
a.req_body.additional_tickets = NULL;
|
||||
a.padata = NULL;
|
||||
err = krb5_get_all_client_addrs ((krb5_addresses*)a.req_body.addresses);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
a.req_body.enc_authorization_data = NULL;
|
||||
a.req_body.additional_tickets = NULL;
|
||||
a.padata = NULL;
|
||||
|
||||
req.length = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
|
||||
sizeof(buf),
|
||||
&a);
|
||||
if (req.length < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
req.data = buf + sizeof(buf) - req.length;
|
||||
if (addrs == NULL) {
|
||||
int i;
|
||||
req.length = encode_AS_REQ ((unsigned char*)buf + sizeof(buf) - 1,
|
||||
sizeof(buf),
|
||||
&a);
|
||||
if (req.length < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
req.data = buf + sizeof(buf) - req.length;
|
||||
if (addrs == NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < a.req_body.addresses->len; ++i)
|
||||
krb5_data_free (&a.req_body.addresses->val[i].address);
|
||||
free (a.req_body.addresses->val);
|
||||
}
|
||||
for (i = 0; i < a.req_body.addresses->len; ++i)
|
||||
krb5_data_free (&a.req_body.addresses->val[i].address);
|
||||
free (a.req_body.addresses->val);
|
||||
}
|
||||
|
||||
err = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
if(decode_AS_REP(resp.data, resp.length, &rep.part1) < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
err = krb5_sendto_kdc (context, &req, &creds->client->realm, &resp);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
if(decode_AS_REP(resp.data, resp.length, &rep.part1) < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
|
||||
free (rep.part1.crealm);
|
||||
/* krb5_principal_free (rep.part1.cname);*/
|
||||
creds->ticket.kvno = rep.part1.ticket.tkt_vno;
|
||||
creds->ticket.etype = rep.part1.enc_part.etype;
|
||||
creds->ticket.enc_part.length = 0;
|
||||
creds->ticket.enc_part.data = NULL;
|
||||
krb5_data_copy (&creds->ticket.enc_part,
|
||||
rep.part1.ticket.enc_part.cipher.data,
|
||||
rep.part1.ticket.enc_part.cipher.length);
|
||||
krb5_data_free (&rep.part1.ticket.enc_part.cipher);
|
||||
|
||||
principalname2krb5_principal (creds->ticket.sprinc,
|
||||
rep.part1.ticket.sname,
|
||||
creds->client->realm);
|
||||
/* krb5_free_principal (rep.part1.ticket.sprinc);*/
|
||||
|
||||
salt.length = 0;
|
||||
salt.data = NULL;
|
||||
err = krb5_get_salt (creds->client, creds->client->realm, &salt);
|
||||
if (err)
|
||||
return err;
|
||||
err = (*key_proc)(context, rep.part1.enc_part.etype, &salt,
|
||||
keyseed, &key);
|
||||
krb5_data_free (&salt);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (decrypt_proc == NULL)
|
||||
decrypt_proc = decrypt_tkt;
|
||||
|
||||
err = (*decrypt_proc)(context, key, decryptarg, &rep);
|
||||
if (err)
|
||||
return err;
|
||||
memset (key->contents.data, 0, key->contents.length);
|
||||
krb5_data_free (&key->contents);
|
||||
free (key);
|
||||
if (rep.part2.key_expiration)
|
||||
free (rep.part2.key_expiration);
|
||||
if (rep.part2.starttime) {
|
||||
creds->times.starttime = *rep.part2.starttime;
|
||||
free (rep.part2.starttime);
|
||||
} else
|
||||
creds->times.starttime = rep.part2.authtime;
|
||||
if (rep.part2.renew_till) {
|
||||
creds->times.renew_till = *rep.part2.renew_till;
|
||||
free (rep.part2.renew_till);
|
||||
} else
|
||||
creds->times.renew_till = rep.part2.endtime;
|
||||
creds->times.authtime = rep.part2.authtime;
|
||||
creds->times.endtime = rep.part2.endtime;
|
||||
#if 0 /* What? */
|
||||
if (rep.part2.req.values)
|
||||
free (rep.part2.req.values);
|
||||
#endif
|
||||
#if 0
|
||||
if (rep.part2.caddr.addrs) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < rep.part2.caddr.number; ++i) {
|
||||
krb5_data_free (&rep.part2.caddr.addrs[i].address);
|
||||
}
|
||||
free (rep.part2.caddr.addrs);
|
||||
}
|
||||
krb5_principal_free (rep.part2.sname);
|
||||
krb5_data_free (&rep.part2.srealm);
|
||||
#endif
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
creds->session.contents.length = 0;
|
||||
creds->session.contents.data = NULL;
|
||||
creds->session.keytype = rep.part2.key.keytype;
|
||||
err = krb5_data_copy (&creds->session.contents,
|
||||
rep.part2.key.keyvalue.data,
|
||||
rep.part2.key.keyvalue.length);
|
||||
memset (rep.part2.key.keyvalue.data, 0,
|
||||
rep.part2.key.keyvalue.length);
|
||||
krb5_data_free (&rep.part2.key.keyvalue);
|
||||
creds->authdata.length = 0;
|
||||
creds->authdata.data = NULL;
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return krb5_cc_store_cred (context, ccache, creds);
|
||||
err = extract_ticket(context, &rep, creds, key_proc, keyseed,
|
||||
decrypt_proc, decryptarg);
|
||||
if(err)
|
||||
return err;
|
||||
return krb5_cc_store_cred (context, ccache, creds);
|
||||
}
|
||||
|
124
lib/krb5/keytab.c
Normal file
124
lib/krb5/keytab.c
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "krb5_locl.h"
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_resolve(krb5_context context,
|
||||
const char *name,
|
||||
krb5_keytab *id)
|
||||
{
|
||||
krb5_keytab k;
|
||||
|
||||
if (strncmp (name, "FILE:", 5) != 0)
|
||||
return -1;
|
||||
|
||||
k = ALLOC(1, krb5_keytab);
|
||||
if (k == NULL)
|
||||
return ENOMEM;
|
||||
k->filename = strdup(name + 5);
|
||||
if (k->filename == NULL)
|
||||
return ENOMEM;
|
||||
*id = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define KEYTAB_DEFAULT "FILE:/etc/v5srvtab"
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_default_name(krb5_context context,
|
||||
char *name,
|
||||
int namesize)
|
||||
{
|
||||
strncpy (name, KEYTAB_DEFAULT, namesize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_default(krb5_context context,
|
||||
krb5_keytab *id)
|
||||
{
|
||||
return krb5_kt_resolve (context, KEYTAB_DEFAULT, id);
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_read_service_key(krb5_context context,
|
||||
krb5_pointer keyprocarg,
|
||||
krb5_principal principal,
|
||||
krb5_kvno vno,
|
||||
krb5_keytype keytype,
|
||||
krb5_keyblock **key)
|
||||
{
|
||||
krb5_keytab keytab;
|
||||
krb5_keytab_entry entry;
|
||||
krb5_error_code r;
|
||||
|
||||
if (keyprocarg)
|
||||
r = krb5_kt_resolve (context, keyprocarg, &keytab);
|
||||
else
|
||||
r = krb5_kt_default (context, &keytab);
|
||||
|
||||
r = krb5_kt_get_entry (context, keytab, principal, vno, keytype, &entry);
|
||||
|
||||
krb5_kt_close (context, keytab);
|
||||
return r;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_add_entry(krb5_context context,
|
||||
krb5_keytab id,
|
||||
krb5_keytab_entry *entry)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_remove_entry(krb5_context context,
|
||||
krb5_keytab id,
|
||||
krb5_keytab_entry *entry)
|
||||
{
|
||||
abort ();
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_get_name(krb5_context context,
|
||||
krb5_keytab keytab,
|
||||
char *name,
|
||||
int namesize)
|
||||
{
|
||||
strncpy (name, keytab->filename, namesize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_close(krb5_context context,
|
||||
krb5_keytab id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_get_entry(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_principal,
|
||||
krb5_kvno,
|
||||
krb5_keytype,
|
||||
krb5_keytab_entry *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_free_entry(krb5_context,
|
||||
krb5_keytab_entry *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_start_seq_get(krb5_context,
|
||||
krb5_keytab id,
|
||||
krb5_kt_cursor *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_next_entry(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_keytab_entry *,
|
||||
krb5_kt_cursor *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_end_seq_get(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_kt_cursor *);
|
||||
|
74
lib/krb5/keytab.h
Normal file
74
lib/krb5/keytab.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#ifndef __KEYTAB_H__
|
||||
#define __KEYTAB_H__
|
||||
|
||||
#if 0
|
||||
krb5_error_code
|
||||
krb5_kt_register(krb5_context, krb5_kt_ops *);
|
||||
#endif
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_resolve(krb5_context, const char *, krb5_keytab *id);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_default_name(krb5_context, char *name, int namesize);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_default(krb5_context, krb5_keytab *id);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_read_service_key(krb5_context,
|
||||
krb5_pointer keyprocarg,
|
||||
krb5_principal principal,
|
||||
krb5_kvno vno,
|
||||
krb5_keytype keytype,
|
||||
krb5_keyblock **key);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_add_entry(krb5_context,
|
||||
krb5_keytab id,
|
||||
krb5_keytab_entry *entry);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_remove_entry(krb5_context,
|
||||
krb5_keytab id,
|
||||
krb5_keytab_entry *entry);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_get_name(krb5_context,
|
||||
krb5_keytab,
|
||||
char *name,
|
||||
int namesize);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_close(krb5_context,
|
||||
krb5_keytab id);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_get_entry(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_principal,
|
||||
krb5_kvno,
|
||||
krb5_keytype,
|
||||
krb5_keytab_entry *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_free_entry(krb5_context,
|
||||
krb5_keytab_entry *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_start_seq_get(krb5_context,
|
||||
krb5_keytab id,
|
||||
krb5_kt_cursor *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_next_entry(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_keytab_entry *,
|
||||
krb5_kt_cursor *);
|
||||
|
||||
krb5_error_code
|
||||
krb5_kt_end_seq_get(krb5_context,
|
||||
krb5_keytab,
|
||||
krb5_kt_cursor *);
|
||||
|
||||
#endif /* __KEYTAB_H__ */
|
@@ -28,7 +28,7 @@ typedef int krb5_boolean;
|
||||
|
||||
typedef int32_t krb5_error_code;
|
||||
|
||||
|
||||
typedef int krb5_kvno;
|
||||
|
||||
typedef void *krb5_pointer;
|
||||
typedef const void *krb5_const_pointer;
|
||||
@@ -70,17 +70,22 @@ typedef enum krb5_preauthtype {
|
||||
|
||||
|
||||
typedef enum krb5_address_type {
|
||||
KRB5_ADDRESS_INET = 2
|
||||
KRB5_ADDRESS_INET = 2
|
||||
} krb5_address_type;
|
||||
|
||||
enum {
|
||||
AP_OPTS_USE_SESSION_KEY = 1,
|
||||
AP_OPTS_MUTUAL_REQUIRED = 2
|
||||
};
|
||||
|
||||
typedef struct krb5_address{
|
||||
krb5_address_type type;
|
||||
krb5_data address;
|
||||
int16_t type;
|
||||
krb5_data address;
|
||||
} krb5_address;
|
||||
|
||||
typedef struct krb5_addresses {
|
||||
int number;
|
||||
krb5_address *addrs;
|
||||
int number;
|
||||
krb5_address *addrs;
|
||||
} krb5_addresses;
|
||||
|
||||
typedef enum krb5_keytype { KEYTYPE_DES } krb5_keytype;
|
||||
@@ -130,28 +135,27 @@ typedef const krb5_principal_data *krb5_const_principal;
|
||||
|
||||
typedef krb5_data krb5_realm;
|
||||
|
||||
typedef struct krb5_ticket{
|
||||
int kvno;
|
||||
krb5_principal sprinc;
|
||||
krb5_data enc_part;
|
||||
krb5_data enc_part2;
|
||||
krb5_enctype etype;
|
||||
}krb5_ticket;
|
||||
typedef struct krb5_ticket {
|
||||
krb5_principal server;
|
||||
krb5_data enc_part;
|
||||
krb5_data enc_part2;
|
||||
} krb5_ticket;
|
||||
|
||||
|
||||
#define KRB5_PARSE_MALFORMED 17
|
||||
#define KRB5_PROG_ETYPE_NOSUPP 4711
|
||||
|
||||
typedef struct krb5_creds {
|
||||
krb5_principal client;
|
||||
krb5_principal server;
|
||||
krb5_keyblock session;
|
||||
krb5_times times;
|
||||
krb5_ticket ticket;
|
||||
krb5_principal client;
|
||||
krb5_principal server;
|
||||
krb5_keyblock session;
|
||||
krb5_times times;
|
||||
krb5_data ticket;
|
||||
|
||||
krb5_ticket second_ticket; /* ? */
|
||||
krb5_data authdata; /* ? */
|
||||
krb5_addresses addresses;
|
||||
|
||||
krb5_data second_ticket; /* ? */
|
||||
krb5_data authdata; /* ? */
|
||||
krb5_addresses addresses;
|
||||
|
||||
} krb5_creds;
|
||||
|
||||
|
||||
@@ -184,10 +188,19 @@ typedef struct krb5_cc_cursor{
|
||||
int fd;
|
||||
}krb5_cc_cursor;
|
||||
|
||||
typedef struct krb5_keytab{
|
||||
int dummy;
|
||||
}krb5_keytab;
|
||||
struct krb5_keytab_data {
|
||||
char *filename;
|
||||
};
|
||||
|
||||
typedef struct krb5_keytab_data *krb5_keytab;
|
||||
|
||||
typedef struct krb5_keytab_entry {
|
||||
int foo;
|
||||
} krb5_keytab_entry;
|
||||
|
||||
typedef struct krb5_kt_cursor {
|
||||
int foo;
|
||||
} krb5_kt_cursor;
|
||||
|
||||
typedef struct krb5_auth_context{
|
||||
int32_t flags;
|
||||
@@ -223,6 +236,14 @@ typedef struct {
|
||||
krb5_error_code
|
||||
krb5_init_context(krb5_context *context);
|
||||
|
||||
krb5_error_code
|
||||
krb5_auth_con_init(krb5_context context,
|
||||
krb5_auth_context **auth_context);
|
||||
|
||||
krb5_error_code
|
||||
krb5_auth_con_free(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
krb5_flags flags);
|
||||
|
||||
krb5_error_code
|
||||
krb5_get_cred_from_kdc(krb5_context,
|
||||
@@ -237,7 +258,7 @@ krb5_get_credentials(krb5_context context,
|
||||
krb5_flags options,
|
||||
krb5_ccache ccache,
|
||||
krb5_creds *in_creds,
|
||||
krb5_creds *out_creds);
|
||||
krb5_creds **out_creds);
|
||||
|
||||
typedef krb5_error_code (*krb5_key_proc)(krb5_context context,
|
||||
krb5_keytype type,
|
||||
@@ -299,6 +320,17 @@ krb5_rd_req(krb5_context context,
|
||||
krb5_flags *ap_req_options,
|
||||
krb5_ticket **ticket);
|
||||
|
||||
typedef EncAPRepPart krb5_ap_rep_enc_part;
|
||||
|
||||
krb5_error_code
|
||||
krb5_rd_rep(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_data *inbuf,
|
||||
krb5_ap_rep_enc_part **repl);
|
||||
|
||||
void
|
||||
krb5_free_ap_rep_enc_part (krb5_context context,
|
||||
krb5_ap_rep_enc_part *val);
|
||||
|
||||
krb5_error_code
|
||||
krb5_parse_name(krb5_context context,
|
||||
@@ -408,6 +440,7 @@ krb5_string_to_key (char *str,
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
#include "keytab.h"
|
||||
|
||||
#endif /* __KRB5_H__ */
|
||||
|
||||
|
@@ -57,7 +57,19 @@ krb5_sendto_kdc (krb5_context context,
|
||||
const krb5_data *realm,
|
||||
krb5_data *receive);
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_ap_req (krb5_context context,
|
||||
krb5_creds *cred,
|
||||
krb5_flags ap_options,
|
||||
krb5_data authenticator,
|
||||
krb5_data *ret);
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_authenticator (krb5_context context,
|
||||
krb5_principal client,
|
||||
Checksum *cksum,
|
||||
Authenticator **auth,
|
||||
krb5_data *result);
|
||||
|
||||
#define ALLOC(N, X) ((X*)malloc((N) * sizeof(X)))
|
||||
#define FREE(X) do{if(X)free(X);}while(0)
|
||||
|
@@ -8,8 +8,12 @@ krb5_get_krbhst (krb5_context context,
|
||||
krb5_error_code err;
|
||||
char buf[BUFSIZ];
|
||||
char *val;
|
||||
|
||||
sprintf (buf, "realms %.*s kdc", (int)realm->length, (char*)realm->data);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
strcpy(buf, "realms ");
|
||||
strncat(buf, (char*)realm->data, realm->length);
|
||||
strcat(buf, " kdc");
|
||||
|
||||
err = krb5_get_config_tag (context->cf, buf, &val);
|
||||
if (err)
|
||||
return err;
|
||||
|
141
lib/krb5/mit-crc.c
Normal file
141
lib/krb5/mit-crc.c
Normal file
@@ -0,0 +1,141 @@
|
||||
#include <krb5_locl.h>
|
||||
|
||||
/* This table and block of comments are taken from code labeled: */
|
||||
/*
|
||||
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*/
|
||||
|
||||
/* First, the polynomial itself and its table of feedback terms. The */
|
||||
/* polynomial is */
|
||||
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||
/* Note that we take it "backwards" and put the highest-order term in */
|
||||
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||
/* the MSB being 1. */
|
||||
|
||||
/* Note that the usual hardware shift register implementation, which */
|
||||
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||
/* implementation, that means shifting towards the right. Why do we */
|
||||
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||
/* shuffling on our part. Reception works similarly. */
|
||||
|
||||
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||
/* */
|
||||
/* 1. The table can be generated at runtime if desired; code to do so */
|
||||
/* is shown later. It might not be obvious, but the feedback */
|
||||
/* terms simply represent the results of eight shift/xor opera- */
|
||||
/* tions for all combinations of data and CRC register values. */
|
||||
/* */
|
||||
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
|
||||
/* be they sixteen or thirty-two bits wide. You simply choose the */
|
||||
/* appropriate table. Alternatively, because the table can be */
|
||||
/* generated at runtime, you can start by generating the table for */
|
||||
/* the polynomial in question and use exactly the same "updcrc", */
|
||||
/* if your application needn't simultaneously handle two CRC */
|
||||
/* polynomials. (Note, however, that XMODEM is strange.) */
|
||||
/* */
|
||||
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
|
||||
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
|
||||
/* */
|
||||
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
|
||||
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||
/* hardware you could probably optimize the shift in assembler by */
|
||||
/* using byte-swap instructions. */
|
||||
|
||||
static u_long const crc_table[256] = {
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
|
||||
0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
|
||||
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
|
||||
0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
|
||||
0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
|
||||
0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
|
||||
0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
|
||||
0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
|
||||
0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
|
||||
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
|
||||
0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
|
||||
0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
|
||||
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
|
||||
0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
|
||||
0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
|
||||
0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
|
||||
0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
|
||||
0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
|
||||
0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
|
||||
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
|
||||
0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
|
||||
0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
|
||||
void
|
||||
crc_init_table()
|
||||
{
|
||||
}
|
||||
|
||||
u_long
|
||||
crc_update(void *in, size_t in_length, u_long crc)
|
||||
{
|
||||
u_char *data;
|
||||
u_int32_t c = 0;
|
||||
int idx;
|
||||
size_t i;
|
||||
|
||||
data = (u_char *)in;
|
||||
for (i = 0; i < in_length; i++) {
|
||||
idx = (int) (data[i] ^ c);
|
||||
idx &= 0xff;
|
||||
c >>= 8;
|
||||
c ^= crc_table[idx];
|
||||
}
|
||||
return c & 0xffffffff;
|
||||
}
|
63
lib/krb5/mk_req.c
Normal file
63
lib/krb5/mk_req.c
Normal file
@@ -0,0 +1,63 @@
|
||||
#include <krb5_locl.h>
|
||||
#include <krb5_error.h>
|
||||
|
||||
krb5_error_code
|
||||
krb5_mk_req(krb5_context context,
|
||||
krb5_auth_context **auth_context,
|
||||
const krb5_flags ap_req_options,
|
||||
char *service,
|
||||
char *hostname,
|
||||
krb5_data *in_data,
|
||||
krb5_ccache ccache,
|
||||
krb5_data *outbuf)
|
||||
{
|
||||
krb5_error_code r;
|
||||
krb5_creds this_cred, cred;
|
||||
char **realms;
|
||||
Authenticator *auth;
|
||||
krb5_data realm_data, authenticator;
|
||||
|
||||
if (*auth_context == NULL) {
|
||||
r = krb5_auth_con_init(context, auth_context);
|
||||
if (r)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = krb5_get_host_realm(context, hostname, &realms);
|
||||
if (r)
|
||||
return r;
|
||||
realm_data.length = strlen(*realms);
|
||||
realm_data.data = *realms;
|
||||
|
||||
r = krb5_build_principal (context, &this_cred.server,
|
||||
strlen(*realms),
|
||||
*realms,
|
||||
service,
|
||||
hostname,
|
||||
NULL);
|
||||
if (r)
|
||||
return r;
|
||||
this_cred.times.endtime = time (NULL) + 4711;
|
||||
|
||||
r = krb5_get_credentials (context, 0, ccache, &this_cred, &cred);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
(*auth_context)->key.keytype = cred.session.keytype;
|
||||
krb5_data_copy (&(*auth_context)->key.contents,
|
||||
cred.session.contents.data,
|
||||
cred.session.contents.length);
|
||||
|
||||
r = krb5_build_authenticator (context, cred.client,
|
||||
NULL, &auth,
|
||||
&authenticator);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
(*auth_context)->authenticator->cusec = auth->cusec;
|
||||
(*auth_context)->authenticator->ctime = auth->ctime;
|
||||
|
||||
r = krb5_build_ap_req (context, &cred, ap_req_options,
|
||||
authenticator, outbuf);
|
||||
return r;
|
||||
}
|
@@ -228,16 +228,51 @@ krb5_principal_set_component(krb5_principal p, int n, void *data, size_t len)
|
||||
}
|
||||
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_principal_va(krb5_context context,
|
||||
krb5_principal *principal,
|
||||
int rlen,
|
||||
const char *realm,
|
||||
va_list ap)
|
||||
static void
|
||||
va_ext_princ(krb5_principal p, va_list ap)
|
||||
{
|
||||
int n = 0;
|
||||
while(1){
|
||||
char *s;
|
||||
int len;
|
||||
len = va_arg(ap, int);
|
||||
if(len == 0)
|
||||
break;
|
||||
s = va_arg(ap, char*);
|
||||
krb5_principal_set_component(p, n, s, len);
|
||||
n++;
|
||||
}
|
||||
p->ncomp = n;
|
||||
}
|
||||
|
||||
static void
|
||||
va_princ(krb5_principal p, va_list ap)
|
||||
{
|
||||
int n = 0;
|
||||
while(1){
|
||||
char *s;
|
||||
int len;
|
||||
s = va_arg(ap, char*);
|
||||
if(s == NULL)
|
||||
break;
|
||||
len = strlen(s);
|
||||
krb5_principal_set_component(p, n, s, len);
|
||||
n++;
|
||||
}
|
||||
p->ncomp = n;
|
||||
}
|
||||
|
||||
|
||||
static krb5_error_code
|
||||
build_principal(krb5_context context,
|
||||
krb5_principal *principal,
|
||||
int rlen,
|
||||
const char *realm,
|
||||
void (*func)(krb5_principal, va_list),
|
||||
va_list ap)
|
||||
{
|
||||
krb5_principal p;
|
||||
int n;
|
||||
char *s;
|
||||
|
||||
if(krb5_principal_alloc(&p))
|
||||
return ENOMEM;
|
||||
@@ -248,19 +283,32 @@ krb5_build_principal_va(krb5_context context,
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
n = 0;
|
||||
while(1){
|
||||
s = va_arg(ap, char*);
|
||||
if(s == NULL)
|
||||
break;
|
||||
krb5_principal_set_component(p, n, s, strlen(s));
|
||||
n++;
|
||||
}
|
||||
p->ncomp = n;
|
||||
(*func)(p, ap);
|
||||
*principal = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_principal_va(krb5_context context,
|
||||
krb5_principal *principal,
|
||||
int rlen,
|
||||
const char *realm,
|
||||
va_list ap)
|
||||
{
|
||||
return build_principal(context, principal, rlen, realm, va_princ, ap);
|
||||
}
|
||||
|
||||
/* Not part of MIT K5 API */
|
||||
krb5_error_code
|
||||
krb5_build_principal_va_ext(krb5_context context,
|
||||
krb5_principal *principal,
|
||||
int rlen,
|
||||
const char *realm,
|
||||
va_list ap)
|
||||
{
|
||||
return build_principal(context, principal, rlen, realm, va_ext_princ, ap);
|
||||
}
|
||||
|
||||
|
||||
krb5_error_code
|
||||
krb5_build_principal_ext(krb5_context context,
|
||||
@@ -269,8 +317,12 @@ krb5_build_principal_ext(krb5_context context,
|
||||
const char *realm,
|
||||
...)
|
||||
{
|
||||
fprintf(stderr, "krb5_build_principal_ext: not implemented\n");
|
||||
abort();
|
||||
krb5_error_code ret;
|
||||
va_list ap;
|
||||
va_start(ap, realm);
|
||||
ret = krb5_build_principal_va_ext(context, principal, rlen, realm, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
65
lib/krb5/rd_rep.c
Normal file
65
lib/krb5/rd_rep.c
Normal file
@@ -0,0 +1,65 @@
|
||||
#include <krb5_locl.h>
|
||||
#include <krb5_error.h>
|
||||
|
||||
krb5_error_code
|
||||
krb5_rd_rep(krb5_context context,
|
||||
krb5_auth_context *auth_context,
|
||||
const krb5_data *inbuf,
|
||||
krb5_ap_rep_enc_part **repl)
|
||||
{
|
||||
AP_REP ap_rep;
|
||||
int len;
|
||||
des_key_schedule schedule;
|
||||
char *buf;
|
||||
int i;
|
||||
|
||||
len = decode_AP_REP(inbuf->data, inbuf->length, &ap_rep);
|
||||
if (len < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
if (ap_rep.pvno != 5)
|
||||
return KRB_AP_ERR_BADVERSION;
|
||||
if (ap_rep.msg_type != krb_ap_rep)
|
||||
return KRB_AP_ERR_MSG_TYPE;
|
||||
|
||||
des_set_key (auth_context->key.contents.data, &schedule);
|
||||
len = ap_rep.enc_part.cipher.length;
|
||||
buf = malloc (len);
|
||||
if (buf == NULL)
|
||||
return ENOMEM;
|
||||
des_cbc_encrypt ((des_cblock *)ap_rep.enc_part.cipher.data,
|
||||
(des_cblock *)buf,
|
||||
len,
|
||||
schedule,
|
||||
auth_context->key.contents.data,
|
||||
DES_DECRYPT);
|
||||
|
||||
/* XXX - Check CRC */
|
||||
|
||||
*repl = malloc(sizeof(**repl));
|
||||
if (*repl == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
i = decode_EncAPRepPart((unsigned char *)buf + 12, len - 12, *repl);
|
||||
if (i < 0)
|
||||
return ASN1_PARSE_ERROR;
|
||||
if ((*repl)->ctime != auth_context->authenticator->ctime ||
|
||||
(*repl)->cusec != auth_context->authenticator->cusec) {
|
||||
printf("KRB_AP_ERR_MUT_FAIL\n");
|
||||
printf ("(%u, %u) != (%u, %u)\n",
|
||||
(*repl)->ctime, (*repl)->cusec,
|
||||
auth_context->authenticator->ctime,
|
||||
auth_context->authenticator->cusec);
|
||||
}
|
||||
#if 0
|
||||
return KRB_AP_ERR_MUT_FAIL;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
krb5_free_ap_rep_enc_part (krb5_context context,
|
||||
krb5_ap_rep_enc_part *val)
|
||||
{
|
||||
free (val);
|
||||
}
|
Reference in New Issue
Block a user