aboutsummaryrefslogtreecommitdiff
path: root/src/lib/krb5/krb
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/krb')
-rw-r--r--src/lib/krb5/krb/Imakefile3
-rw-r--r--src/lib/krb5/krb/copy_tick.c15
-rw-r--r--src/lib/krb5/krb/gc_via_tgt.c7
-rw-r--r--src/lib/krb5/krb/get_in_tkt.c49
-rw-r--r--src/lib/krb5/krb/in_tkt_pwd.c50
-rw-r--r--src/lib/krb5/krb/in_tkt_sky.c8
-rw-r--r--src/lib/krb5/krb/mk_priv.c38
-rw-r--r--src/lib/krb5/krb/mk_req.c2
-rw-r--r--src/lib/krb5/krb/mk_req_ext.c21
-rw-r--r--src/lib/krb5/krb/mk_safe.c37
-rw-r--r--src/lib/krb5/krb/pr_to_salt.c2
-rw-r--r--src/lib/krb5/krb/rd_priv.c63
-rw-r--r--src/lib/krb5/krb/rd_req_dec.c14
-rw-r--r--src/lib/krb5/krb/rd_safe.c48
-rw-r--r--src/lib/krb5/krb/send_tgs.c127
15 files changed, 337 insertions, 147 deletions
diff --git a/src/lib/krb5/krb/Imakefile b/src/lib/krb5/krb/Imakefile
index f2f8555..885bead 100644
--- a/src/lib/krb5/krb/Imakefile
+++ b/src/lib/krb5/krb/Imakefile
@@ -40,6 +40,7 @@ OBJS= addr_comp.o \
mk_req_ext.o \
mk_safe.o \
parse.o \
+ pr_to_salt.o \
princ_comp.o \
rd_error.o \
rd_priv.o \
@@ -84,6 +85,7 @@ SRCS= addr_comp.c \
mk_req_ext.c \
mk_safe.c \
parse.c \
+ pr_to_salt.c \
princ_comp.c \
rd_error.c \
rd_priv.c \
@@ -98,3 +100,4 @@ SRCS= addr_comp.c \
walk_rtree.c
OtherdirLibraryTarget($(TOP)/lib,krb5,$(OBJS))
+INCLUDES=-I../../include
diff --git a/src/lib/krb5/krb/copy_tick.c b/src/lib/krb5/krb/copy_tick.c
index c66d082..ec6a9d4 100644
--- a/src/lib/krb5/krb/copy_tick.c
+++ b/src/lib/krb5/krb/copy_tick.c
@@ -27,7 +27,6 @@ krb5_enc_tkt_part **partto;
{
krb5_error_code retval;
krb5_enc_tkt_part *tempto;
- krb5_data *scratch;
if (!(tempto = (krb5_enc_tkt_part *)malloc(sizeof(*tempto))))
return ENOMEM;
@@ -48,16 +47,20 @@ krb5_enc_tkt_part **partto;
xfree(tempto);
return retval;
}
- if (retval = krb5_copy_data(&partfrom->transited, &scratch)) {
+ tempto->transited = partfrom->transited;
+ tempto->transited.tr_contents.data =
+ malloc(sizeof(partfrom->transited.tr_contents.length));
+ if (!tempto->transited.tr_contents.data) {
krb5_free_principal(tempto->client);
krb5_free_keyblock(tempto->session);
xfree(tempto);
return retval;
}
- tempto->transited = *scratch;
- xfree(scratch);
+ memcpy((char *)tempto->transited.tr_contents.data,
+ (char *)partfrom->transited.tr_contents.data,
+ partfrom->transited.tr_contents.length);
if (retval = krb5_copy_addresses(partfrom->caddrs, &tempto->caddrs)) {
- xfree(tempto->transited.data);
+ xfree(tempto->transited.tr_contents.data);
krb5_free_principal(tempto->client);
krb5_free_keyblock(tempto->session);
xfree(tempto);
@@ -67,7 +70,7 @@ krb5_enc_tkt_part **partto;
if (retval = krb5_copy_authdata(partfrom->authorization_data,
&tempto->authorization_data)) {
krb5_free_address(tempto->caddrs);
- xfree(tempto->transited.data);
+ xfree(tempto->transited.tr_contents.data);
krb5_free_principal(tempto->client);
krb5_free_keyblock(tempto->session);
xfree(tempto);
diff --git a/src/lib/krb5/krb/gc_via_tgt.c b/src/lib/krb5/krb/gc_via_tgt.c
index b05c6fd..99efd79 100644
--- a/src/lib/krb5/krb/gc_via_tgt.c
+++ b/src/lib/krb5/krb/gc_via_tgt.c
@@ -66,6 +66,7 @@ OLDDECLARG(krb5_creds *, cred)
cred->server,
tgt->addresses,
cred->authdata,
+ 0, /* no padata */
0, /* no second ticket */
tgt, &tgsrep))
return retval;
@@ -116,6 +117,12 @@ OLDDECLARG(krb5_creds *, cred)
dec_rep->enc_part2->session->length);\
krb5_free_kdc_rep(dec_rep); }
+ if (dec_rep->msg_type != KRB5_TGS_REP) {
+ retval = KRB5KRB_AP_ERR_MSG_TYPE;
+ cleanup();
+ return retval;
+ }
+
/* now it's decrypted and ready for prime time */
if (!krb5_principal_compare(dec_rep->client, tgt->client)) {
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
index e690f36..4571f66 100644
--- a/src/lib/krb5/krb/get_in_tkt.c
+++ b/src/lib/krb5/krb/get_in_tkt.c
@@ -52,7 +52,7 @@ static char rcsid_get_in_tkt_c[] =
extern krb5_deltat krb5_clockskew;
-#define in_clock_skew(date) (abs((date)-request.ctime) < krb5_clockskew)
+#define in_clock_skew(date) (abs((date)-request.nonce) < krb5_clockskew)
/* some typedef's for the function args to make things look a bit cleaner */
@@ -60,7 +60,8 @@ extern krb5_deltat krb5_clockskew;
#include <krb5/widen.h>
typedef krb5_error_code (*git_key_proc) PROTOTYPE((const krb5_keytype,
krb5_keyblock **,
- krb5_const_pointer ));
+ krb5_const_pointer,
+ krb5_pa_data **));
#include <krb5/narrow.h>
typedef krb5_error_code (*git_decrypt_proc) PROTOTYPE((const krb5_keyblock *,
@@ -95,13 +96,13 @@ OLDDECLARG(krb5_ccache, ccache)
krb5_data *packet;
krb5_data reply;
krb5_keyblock *decrypt_key;
+ krb5_enctype etypes[1];
+ krb5_timestamp time_now;
request.msg_type = KRB5_AS_REQ;
/* AS_REQ has no pre-authentication. */
- request.padata_type = 0;
- request.padata.data = 0;
- request.padata.length = 0;
+ request.padata = 0;
request.kdc_options = options;
request.client = creds->client;
@@ -110,14 +111,20 @@ OLDDECLARG(krb5_ccache, ccache)
request.from = creds->times.starttime;
request.till = creds->times.endtime;
request.rtime = creds->times.renew_till;
- if (retval = krb5_timeofday(&request.ctime))
+ if (retval = krb5_timeofday(&time_now))
return(retval);
+
/* XXX we know they are the same size... */
- request.nonce = (krb5_int32) request.ctime;
- request.etype = etype;
+ request.nonce = (krb5_int32) time_now;
+
+ etypes[0] = etype;
+ request.etype = etypes;
+ request.netypes = 1;
request.addresses = (krb5_address **) addrs;
request.second_ticket = 0;
- request.authorization_data = 0;
+ request.authorization_data.ciphertext.length = 0;
+ request.authorization_data.ciphertext.data = 0;
+ request.unenc_authdata = 0;
/* encode & send to KDC */
if (retval = encode_krb5_as_req(&request, &packet))
@@ -129,14 +136,12 @@ OLDDECLARG(krb5_ccache, ccache)
/* now decode the reply...could be error or as_rep */
- if (!krb5_is_as_rep(&reply) && !krb5_is_krb_error(&reply))
- return KRB5KRB_AP_ERR_MSG_TYPE;
- if (retval = decode_krb5_as_rep(&reply, &as_reply)) {
- if (decode_krb5_error(&reply, &err_reply))
- return retval; /* some other reply--??? */
+ if (krb5_is_krb_error(&reply)) {
+ if (retval = decode_krb5_error(&reply, &err_reply))
+ return retval; /* some other reply--??? */
/* it was an error */
- if ((err_reply->ctime != request.ctime) ||
+ if ((err_reply->ctime != request.nonce) ||
!krb5_principal_compare(err_reply->server, request.server) ||
!krb5_principal_compare(err_reply->client, request.client))
retval = KRB5_KDCREP_MODIFIED;
@@ -149,10 +154,19 @@ OLDDECLARG(krb5_ccache, ccache)
return retval;
}
+ if (!krb5_is_as_rep(&reply))
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+ if (retval = decode_krb5_as_rep(&reply, &as_reply))
+ return retval; /* some other reply--??? */
+
+ if (as_reply->msg_type != KRB5_AS_REP)
+ return KRB5KRB_AP_ERR_MSG_TYPE;
+
/* it was a kdc_rep--decrypt & check */
/* generate the key */
- if (retval = (*key_proc)(keytype, &decrypt_key, keyseed)) {
+ if (retval = (*key_proc)(keytype, &decrypt_key, keyseed,
+ as_reply->padata)) {
krb5_free_kdc_rep(as_reply);
return retval;
}
@@ -166,6 +180,9 @@ OLDDECLARG(krb5_ccache, ccache)
}
/* check the contents for sanity: */
+ if (!as_reply->enc_part2->times.starttime)
+ as_reply->enc_part2->times.starttime =
+ as_reply->enc_part2->times.authtime;
if (!krb5_principal_compare(as_reply->client, request.client)
|| !krb5_principal_compare(as_reply->enc_part2->server, request.server)
|| !krb5_principal_compare(as_reply->ticket->server, request.server)
diff --git a/src/lib/krb5/krb/in_tkt_pwd.c b/src/lib/krb5/krb/in_tkt_pwd.c
index 8c610e9..78b9ed6 100644
--- a/src/lib/krb5/krb/in_tkt_pwd.c
+++ b/src/lib/krb5/krb/in_tkt_pwd.c
@@ -34,42 +34,74 @@ extern char *krb5_default_pwd_prompt1;
static krb5_error_code
pwd_keyproc(DECLARG(const krb5_keytype, type),
DECLARG(krb5_keyblock **, key),
- DECLARG(krb5_const_pointer, keyseed))
+ DECLARG(krb5_const_pointer, keyseed),
+ DECLARG(krb5_pa_data **,padata))
OLDDECLARG(const krb5_keytype, type)
OLDDECLARG(krb5_keyblock **, key)
OLDDECLARG(krb5_const_pointer, keyseed)
+OLDDECLARG(krb5_pa_data **,padata)
{
+ krb5_data salt;
krb5_error_code retval;
- struct pwd_keyproc_arg *arg, arg2;
+ const struct pwd_keyproc_arg *arg;
+ struct pwd_keyproc_arg arg2;
char pwdbuf[BUFSIZ];
int pwsize = sizeof(pwdbuf);
+ char f_salt = 0, use_salt = 0;
if (!valid_keytype(type))
return KRB5_PROG_KEYTYPE_NOSUPP;
- arg = (struct pwd_keyproc_arg *)keyseed;
+ if (padata) {
+ krb5_pa_data **ptr;
+
+ for (ptr = padata; *ptr; ptr++)
+ {
+ if ((*ptr)->pa_type == KRB5_PADATA_PW_SALT)
+ {
+ /* use KDC-supplied salt, instead of default */
+ salt.length = (*ptr)->length;
+ salt.data = (char *)(*ptr)->contents;
+ use_salt = 1;
+ break;
+ }
+ }
+ }
+ arg = (const struct pwd_keyproc_arg *)keyseed;
+ if (!use_salt) {
+ /* need to use flattened principal */
+ if (retval = krb5_principal2salt(arg->who, &salt))
+ return(retval);
+ f_salt = 1;
+ }
+
if (!arg->password.length) {
if (retval = krb5_read_password(krb5_default_pwd_prompt1,
0,
- pwdbuf, &pwsize))
+ pwdbuf, &pwsize)) {
+ if (f_salt) xfree(salt.data);
return retval;
+ }
arg2 = *arg;
+ arg2.password.length = pwsize;
+ arg2.password.data = pwdbuf;
arg = &arg2;
- arg->password.length = pwsize;
- arg->password.data = pwdbuf;
}
*key = (krb5_keyblock *)malloc(sizeof(**key));
- if (!*key)
+ if (!*key) {
+ if (f_salt) xfree(salt.data);
return ENOMEM;
-
+ }
if (retval = (*krb5_keytype_array[type]->system->
string_to_key)(type,
*key,
&arg->password,
- arg->who)) {
+ &salt)) {
free((char *) *key);
+ if (f_salt) xfree(salt.data);
return(retval);
}
+ if (f_salt) xfree(salt.data);
return 0;
}
diff --git a/src/lib/krb5/krb/in_tkt_sky.c b/src/lib/krb5/krb/in_tkt_sky.c
index 136188d..904ef62 100644
--- a/src/lib/krb5/krb/in_tkt_sky.c
+++ b/src/lib/krb5/krb/in_tkt_sky.c
@@ -22,7 +22,7 @@ static char rcsid_in_tkt_skey_c [] =
#include <krb5/ext-proto.h>
struct skey_keyproc_arg {
- krb5_keyblock *key;
+ const krb5_keyblock *key;
krb5_principal server; /* it's a pointer, really! */
};
@@ -34,10 +34,12 @@ struct skey_keyproc_arg {
static krb5_error_code
skey_keyproc(DECLARG(const krb5_keytype, type),
DECLARG(krb5_keyblock **, key),
- DECLARG(krb5_const_pointer, keyseed))
+ DECLARG(krb5_const_pointer, keyseed),
+ DECLARG(krb5_pa_data **, padata))
OLDDECLARG(const krb5_keytype, type)
OLDDECLARG(krb5_keyblock **, key)
OLDDECLARG(krb5_const_pointer, keyseed)
+OLDDECLARG(krb5_pa_data **,padata)
{
krb5_keyblock *realkey;
const struct skey_keyproc_arg *arg;
@@ -129,7 +131,7 @@ OLDDECLARG(krb5_creds *, creds)
krb5_keytype keytype;
if (key) {
- arg.key = (krb5_keyblock *)key;
+ arg.key = key;
arg.server = 0;
keytype = key->keytype;
} else {
diff --git a/src/lib/krb5/krb/mk_priv.c b/src/lib/krb5/krb/mk_priv.c
index 5a89400..483b100 100644
--- a/src/lib/krb5/krb/mk_priv.c
+++ b/src/lib/krb5/krb/mk_priv.c
@@ -42,15 +42,19 @@ krb5_error_code
krb5_mk_priv(DECLARG(const krb5_data *, userdata),
DECLARG(const krb5_enctype, etype),
DECLARG(const krb5_keyblock *, key),
- DECLARG(const krb5_fulladdr *, sender_addr),
- DECLARG(const krb5_fulladdr *, recv_addr),
+ DECLARG(const krb5_address *, sender_addr),
+ DECLARG(const krb5_address *, recv_addr),
+ DECLARG(krb5_int32, seq_number),
+ DECLARG(krb5_int32, priv_flags),
DECLARG(krb5_pointer, i_vector),
DECLARG(krb5_data *, outbuf))
OLDDECLARG(const krb5_data *, userdata)
OLDDECLARG(const krb5_enctype, etype)
OLDDECLARG(const krb5_keyblock *, key)
-OLDDECLARG(const krb5_fulladdr *, sender_addr)
-OLDDECLARG(const krb5_fulladdr *, recv_addr)
+OLDDECLARG(const krb5_address *, sender_addr)
+OLDDECLARG(const krb5_address *, recv_addr)
+OLDDECLARG(krb5_int32, seq_number)
+OLDDECLARG(krb5_int32, priv_flags)
OLDDECLARG(krb5_pointer, i_vector)
OLDDECLARG(krb5_data *, outbuf)
{
@@ -66,19 +70,21 @@ OLDDECLARG(krb5_data *, outbuf)
privmsg.enc_part.kvno = 0; /* XXX allow user-set? */
privmsg_enc_part.user_data = *userdata;
- privmsg_enc_part.s_address = sender_addr->address;
- privmsg_enc_part.r_address = recv_addr->address;
-
- if (retval = krb5_ms_timeofday(&privmsg_enc_part.timestamp,
- &privmsg_enc_part.msec))
- return retval;
-
- if (krb5_fulladdr_order(sender_addr, recv_addr) > 0)
- privmsg_enc_part.msec =
- (privmsg_enc_part.msec & MSEC_VAL_MASK) | MSEC_DIRBIT;
+ privmsg_enc_part.s_address = (krb5_address *)sender_addr;
+ if (recv_addr)
+ privmsg_enc_part.r_address = (krb5_address *)recv_addr;
else
- /* this should be a no-op, but just to be sure... */
- privmsg_enc_part.msec = privmsg_enc_part.msec & MSEC_VAL_MASK;
+ privmsg_enc_part.r_address = 0;
+
+ if (!(priv_flags & KRB5_PRIV_NOTIME)) {
+ if (retval = krb5_us_timeofday(&privmsg_enc_part.timestamp,
+ &privmsg_enc_part.usec))
+ return retval;
+ }
+ if (priv_flags & KRB5_PRIV_DOSEQUENCE) {
+ privmsg_enc_part.seq_number = seq_number;
+ } else
+ privmsg_enc_part.seq_number = 0;
/* start by encoding to-be-encrypted part of the message */
diff --git a/src/lib/krb5/krb/mk_req.c b/src/lib/krb5/krb/mk_req.c
index c539d64..24e5bc7 100644
--- a/src/lib/krb5/krb/mk_req.c
+++ b/src/lib/krb5/krb/mk_req.c
@@ -73,6 +73,8 @@ krb5_data *outbuf;
checksum,
&creds.times,
krb5_kdc_default_options,
+ 0, /* no sequence number */
+ 0, /* no sub-key */
ccache,
&creds,
0, /* We don't need the authenticator */
diff --git a/src/lib/krb5/krb/mk_req_ext.c b/src/lib/krb5/krb/mk_req_ext.c
index 1041fdc..6a5ce9c 100644
--- a/src/lib/krb5/krb/mk_req_ext.c
+++ b/src/lib/krb5/krb/mk_req_ext.c
@@ -58,15 +58,19 @@ static char rcsid_mk_req_ext_c[] =
*/
static krb5_error_code generate_authenticator PROTOTYPE((krb5_authenticator *,
const krb5_creds *,
- const krb5_checksum *));
+ const krb5_checksum *,
+ krb5_keyblock *,
+ krb5_int32 ));
krb5_error_code
-krb5_mk_req_extended(ap_req_options, checksum, times, kdc_options, ccache,
- creds, authentp, outbuf)
+krb5_mk_req_extended(ap_req_options, checksum, times, kdc_options,
+ sequence, newkey, ccache, creds, authentp, outbuf)
const krb5_flags ap_req_options;
const krb5_checksum *checksum;
const krb5_ticket_times *times;
const krb5_flags kdc_options;
+krb5_int32 sequence;
+krb5_keyblock *newkey;
krb5_ccache ccache;
krb5_creds *creds;
krb5_authenticator *authentp;
@@ -107,7 +111,8 @@ krb5_data *outbuf;
return(retval);
#define cleanup_ticket() krb5_free_ticket(request.ticket)
- if (retval = generate_authenticator(&authent, creds, checksum)) {
+ if (retval = generate_authenticator(&authent, creds, checksum, newkey,
+ sequence)) {
cleanup_ticket();
return retval;
}
@@ -203,13 +208,17 @@ request.authenticator.ciphertext.data = 0;}
}
static krb5_error_code
-generate_authenticator(authent, creds, cksum)
+generate_authenticator(authent, creds, cksum, key, seq_number)
krb5_authenticator *authent;
const krb5_creds *creds;
const krb5_checksum *cksum;
+krb5_keyblock *key;
+krb5_int32 seq_number;
{
authent->client = creds->client;
authent->checksum = (krb5_checksum *)cksum;
+ authent->subkey = key;
+ authent->seq_number = seq_number;
- return(krb5_ms_timeofday(&authent->ctime, &authent->cmsec));
+ return(krb5_us_timeofday(&authent->ctime, &authent->cusec));
}
diff --git a/src/lib/krb5/krb/mk_safe.c b/src/lib/krb5/krb/mk_safe.c
index 975d0cb..12fb963 100644
--- a/src/lib/krb5/krb/mk_safe.c
+++ b/src/lib/krb5/krb/mk_safe.c
@@ -41,14 +41,18 @@ krb5_error_code
krb5_mk_safe(DECLARG(const krb5_data *, userdata),
DECLARG(const krb5_cksumtype, sumtype),
DECLARG(const krb5_keyblock *, key),
- DECLARG(const krb5_fulladdr *, sender_addr),
- DECLARG(const krb5_fulladdr *, recv_addr),
+ DECLARG(const krb5_address *, sender_addr),
+ DECLARG(const krb5_address *, recv_addr),
+ DECLARG(krb5_int32, seq_number),
+ DECLARG(krb5_int32, safe_flags),
DECLARG(krb5_data *, outbuf))
OLDDECLARG(const krb5_data *, userdata)
OLDDECLARG(const krb5_cksumtype, sumtype)
OLDDECLARG(const krb5_keyblock *, key)
-OLDDECLARG(const krb5_fulladdr *, sender_addr)
-OLDDECLARG(const krb5_fulladdr *, recv_addr)
+OLDDECLARG(const krb5_address *, sender_addr)
+OLDDECLARG(const krb5_address *, recv_addr)
+OLDDECLARG(krb5_int32, seq_number)
+OLDDECLARG(krb5_int32, safe_flags)
OLDDECLARG(krb5_data *, outbuf)
{
krb5_error_code retval;
@@ -59,20 +63,25 @@ OLDDECLARG(krb5_data *, outbuf)
if (!valid_cksumtype(sumtype))
return KRB5_PROG_SUMTYPE_NOSUPP;
+ if (!is_coll_proof_cksum(sumtype) || !is_keyed_cksum(sumtype))
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
safemsg.user_data = *userdata;
- safemsg.s_address = sender_addr->address;
- safemsg.r_address = recv_addr->address;
-
- if (retval = krb5_ms_timeofday(&safemsg.timestamp, &safemsg.msec))
- return retval;
-
- if (krb5_fulladdr_order(sender_addr, recv_addr) > 0)
- safemsg.msec = (safemsg.msec & MSEC_VAL_MASK) | MSEC_DIRBIT;
+ safemsg.s_address = (krb5_address *)sender_addr;
+ if (recv_addr)
+ safemsg.r_address = (krb5_address *)recv_addr;
else
- /* this should be a no-op, but just to be sure... */
- safemsg.msec = safemsg.msec & MSEC_VAL_MASK;
+ safemsg.r_address = 0;
+ if (!(safe_flags & KRB5_SAFE_NOTIME)) {
+ if (retval = krb5_us_timeofday(&safemsg.timestamp, &safemsg.usec))
+ return retval;
+ }
+ if (safe_flags & KRB5_SAFE_DOSEQUENCE) {
+ safemsg.seq_number = seq_number;
+ } else
+ safemsg.seq_number = 0;
+
/* to do the checksum stuff, we need to encode the message with a
zero-length zero-type checksum, then checksum the encoding, then
re-encode with the
diff --git a/src/lib/krb5/krb/pr_to_salt.c b/src/lib/krb5/krb/pr_to_salt.c
index 4060202..74013fb 100644
--- a/src/lib/krb5/krb/pr_to_salt.c
+++ b/src/lib/krb5/krb/pr_to_salt.c
@@ -30,7 +30,7 @@ krb5_const_principal pr;
krb5_data *ret;
{
int size, offset;
- krb5_data **prp;
+ krb5_data * const * prp;
if (pr == 0) {
diff --git a/src/lib/krb5/krb/rd_priv.c b/src/lib/krb5/krb/rd_priv.c
index 8cc22df..78607bf 100644
--- a/src/lib/krb5/krb/rd_priv.c
+++ b/src/lib/krb5/krb/rd_priv.c
@@ -49,14 +49,18 @@ Returns system errors, integrity errors.
krb5_error_code
krb5_rd_priv(DECLARG(const krb5_data *, inbuf),
DECLARG(const krb5_keyblock *, key),
- DECLARG(const krb5_fulladdr *, sender_addr),
- DECLARG(const krb5_fulladdr *, recv_addr),
+ DECLARG(const krb5_address *, sender_addr),
+ DECLARG(const krb5_address *, recv_addr),
+ DECLARG(krb5_int32, seq_number),
+ DECLARG(krb5_int32, priv_flags),
DECLARG(krb5_pointer, i_vector),
DECLARG(krb5_data *, outbuf))
OLDDECLARG(const krb5_data *, inbuf)
OLDDECLARG(const krb5_keyblock *, key)
-OLDDECLARG(const krb5_fulladdr *, sender_addr)
-OLDDECLARG(const krb5_fulladdr *, recv_addr)
+OLDDECLARG(const krb5_address *, sender_addr)
+OLDDECLARG(const krb5_address *, recv_addr)
+OLDDECLARG(krb5_int32, seq_number)
+OLDDECLARG(krb5_int32, priv_flags)
OLDDECLARG(krb5_pointer, i_vector)
OLDDECLARG(krb5_data *, outbuf)
{
@@ -66,7 +70,6 @@ OLDDECLARG(krb5_data *, outbuf)
krb5_priv_enc_part *privmsg_enc_part;
krb5_data scratch;
krb5_timestamp currenttime;
- krb5_ui_2 computed_direction;
if (!krb5_is_krb_priv(inbuf))
return KRB5KRB_AP_ERR_MSG_TYPE;
@@ -142,25 +145,28 @@ OLDDECLARG(krb5_data *, outbuf)
#define cleanup_data() {(void)memset(privmsg_enc_part->user_data.data,0,privmsg_enc_part->user_data.length); (void)xfree(privmsg_enc_part->user_data.data);}
#define cleanup_mesg() {(void)xfree(privmsg_enc_part);}
- if (retval = krb5_timeofday(&currenttime)) {
- cleanup_data();
- cleanup_mesg();
- return retval;
- }
- if (!in_clock_skew(privmsg_enc_part->timestamp)) {
- cleanup_data();
- cleanup_mesg();
- return KRB5KRB_AP_ERR_SKEW;
+ if (!(priv_flags & KRB5_PRIV_NOTIME)) {
+ if (retval = krb5_timeofday(&currenttime)) {
+ cleanup_data();
+ cleanup_mesg();
+ return retval;
+ }
+ if (!in_clock_skew(privmsg_enc_part->timestamp)) {
+ cleanup_data();
+ cleanup_mesg();
+ return KRB5KRB_AP_ERR_SKEW;
+ }
+ /* replay detection goes here... XXX */
}
- /*
- * check with the replay cache should be inserted here !!!!
- */
-
+ if (priv_flags & KRB5_PRIV_DOSEQUENCE)
+ if (privmsg_enc_part->seq_number != seq_number) {
+ cleanup_data();
+ cleanup_mesg();
+ return KRB5KRB_AP_ERR_BADSEQ;
+ }
- if (sender_addr) {
- krb5_fulladdr temp_sender;
- krb5_fulladdr temp_recip;
+ if (privmsg_enc_part->r_address) {
krb5_address **our_addrs;
if (retval = krb5_os_localaddr(&our_addrs)) {
@@ -175,21 +181,8 @@ OLDDECLARG(krb5_data *, outbuf)
return KRB5KRB_AP_ERR_BADADDR;
}
krb5_free_address(our_addrs);
-
- temp_recip = *recv_addr;
- temp_recip.address = privmsg_enc_part->r_address;
-
- temp_sender = *sender_addr;
- temp_sender.address = privmsg_enc_part->s_address;
-
- computed_direction = ((krb5_fulladdr_order(&temp_sender, &temp_recip) >
- 0) ? MSEC_DIRBIT : 0);
- if (computed_direction != (privmsg_enc_part->msec & MSEC_DIRBIT)) {
- cleanup_data();
- cleanup_mesg();
- return KRB5KRB_AP_ERR_BADDIRECTION;
- }
}
+ /* XXX check sender's address */
/* everything is ok - return data to the user */
diff --git a/src/lib/krb5/krb/rd_req_dec.c b/src/lib/krb5/krb/rd_req_dec.c
index cce02cb..0028ca7 100644
--- a/src/lib/krb5/krb/rd_req_dec.c
+++ b/src/lib/krb5/krb/rd_req_dec.c
@@ -81,11 +81,10 @@ krb5_tkt_authent *tktauthent;
krb5_error_code retval;
krb5_keyblock *tkt_key;
krb5_keyblock tkt_key_real;
- krb5_timestamp currenttime;
+ krb5_timestamp currenttime, starttime;
- if ((server != NULL) &&
- (!krb5_principal_compare(server, req->ticket->server)))
+ if (server && !krb5_principal_compare(server, req->ticket->server))
return KRB5KRB_AP_WRONG_PRINC;
/* if (req->ap_options & AP_OPTS_USE_SESSION_KEY)
@@ -162,7 +161,14 @@ krb5_tkt_authent *tktauthent;
return retval;
}
tktauthent->ticket = 0;
- if (req->ticket->enc_part2->times.starttime - currenttime > krb5_clockskew) {
+
+ /* if starttime is not in ticket, then treat it as authtime */
+ if (req->ticket->enc_part2->times.starttime != 0)
+ starttime = req->ticket->enc_part2->times.starttime;
+ else
+ starttime = req->ticket->enc_part2->times.authtime;
+
+ if (starttime - currenttime > krb5_clockskew) {
clean_authenticator();
return KRB5KRB_AP_ERR_TKT_NYV; /* ticket not yet valid */
}
diff --git a/src/lib/krb5/krb/rd_safe.c b/src/lib/krb5/krb/rd_safe.c
index cd194e5..b6ab7dd 100644
--- a/src/lib/krb5/krb/rd_safe.c
+++ b/src/lib/krb5/krb/rd_safe.c
@@ -38,16 +38,17 @@ extern krb5_deltat krb5_clockskew;
returns system errors, integrity errors
*/
krb5_error_code
-krb5_rd_safe(inbuf, key, sender_addr, recv_addr, outbuf)
+krb5_rd_safe(inbuf, key, sender_addr, recv_addr, seq_number, safe_flags, outbuf)
const krb5_data *inbuf;
const krb5_keyblock *key;
-const krb5_fulladdr *sender_addr;
-const krb5_fulladdr *recv_addr;
+const krb5_address *sender_addr;
+const krb5_address *recv_addr;
+krb5_int32 seq_number;
+krb5_int32 safe_flags;
krb5_data *outbuf;
{
krb5_error_code retval;
krb5_safe *message;
- krb5_ui_2 computed_direction;
krb5_checksum our_cksum, *his_cksum;
krb5_octet zero_octet = 0;
krb5_data *scratch;
@@ -63,22 +64,30 @@ krb5_data *outbuf;
if (!valid_cksumtype(message->checksum->checksum_type))
return KRB5_PROG_SUMTYPE_NOSUPP;
+ if (!is_coll_proof_cksum(message->checksum->checksum_type) ||
+ !is_keyed_cksum(message->checksum->checksum_type))
+ return KRB5KRB_AP_ERR_INAPP_CKSUM;
if (retval = krb5_timeofday(&currenttime)) {
cleanup();
return retval;
}
- /* in_clock_skew #defined above */
- if (!in_clock_skew(message->timestamp)) {
- cleanup();
- return KRB5KRB_AP_ERR_SKEW;
+ if (!(safe_flags & KRB5_SAFE_NOTIME)) {
+ /* in_clock_skew #defined above */
+ if (!in_clock_skew(message->timestamp)) {
+ cleanup();
+ return KRB5KRB_AP_ERR_SKEW;
+ }
+ /* replay detection goes here... XXX */
}
- /* replay detection goes here... XXX */
+ if (safe_flags & KRB5_SAFE_DOSEQUENCE)
+ if (message->seq_number != seq_number) {
+ cleanup();
+ return KRB5KRB_AP_ERR_BADSEQ;
+ }
- if (sender_addr) {
- krb5_fulladdr temp_sender;
- krb5_fulladdr temp_recip;
+ if (message->r_address) {
krb5_address **our_addrs;
if (retval = krb5_os_localaddr(&our_addrs)) {
@@ -91,21 +100,10 @@ krb5_data *outbuf;
return KRB5KRB_AP_ERR_BADADDR;
}
krb5_free_address(our_addrs);
-
- temp_recip = *recv_addr;
- temp_recip.address = message->r_address;
-
- temp_sender = *sender_addr;
- temp_sender.address = message->s_address;
-
- computed_direction = ((krb5_fulladdr_order(&temp_sender, &temp_recip) >
- 0) ? MSEC_DIRBIT : 0);
- if (computed_direction != (message->msec & MSEC_DIRBIT)) {
- cleanup();
- return KRB5KRB_AP_ERR_BADDIRECTION;
- }
}
+ /* XXX check sender's address */
+
/* verify the checksum */
/* to do the checksum stuff, we need to re-encode the message with a
zero-length zero-type checksum, then checksum the encoding, and verify.
diff --git a/src/lib/krb5/krb/send_tgs.c b/src/lib/krb5/krb/send_tgs.c
index 9e8d159..164c677 100644
--- a/src/lib/krb5/krb/send_tgs.c
+++ b/src/lib/krb5/krb/send_tgs.c
@@ -24,7 +24,7 @@ static char rcsid_send_tgs_c[] =
Sends a request to the TGS and waits for a response.
options is used for the options in the KRB_TGS_REQ.
timestruct values are used for from, till, rtime " " "
- etype is used for etype " " "
+ etype is used for etype " " ", and to encrypt the authorization data, if present
sumtype is used for the checksum in the AP_REQ in the KRB_TGS_REQ
sname is used for sname " " "
addrs, if non-NULL, is used for addresses " " "
@@ -47,6 +47,7 @@ krb5_send_tgs(DECLARG(const krb5_flags, kdcoptions),
DECLARG(krb5_const_principal, sname),
DECLARG(krb5_address * const *, addrs),
DECLARG(krb5_authdata * const *,authorization_data),
+ DECLARG(krb5_pa_data * const *, padata),
DECLARG(const krb5_data *,second_ticket),
DECLARG(krb5_creds *,usecred),
DECLARG(krb5_response *,rep))
@@ -57,6 +58,7 @@ OLDDECLARG(const krb5_cksumtype, sumtype)
OLDDECLARG(krb5_const_principal, sname)
OLDDECLARG(krb5_address * const *, addrs)
OLDDECLARG(krb5_authdata * const *,authorization_data)
+OLDDECLARG(krb5_pa_data * const *, padata)
OLDDECLARG(const krb5_data *,second_ticket)
OLDDECLARG(krb5_creds *,usecred)
OLDDECLARG(krb5_response *,rep)
@@ -64,9 +66,16 @@ OLDDECLARG(krb5_response *,rep)
krb5_error_code retval;
krb5_kdc_req tgsreq;
krb5_checksum ap_checksum;
- krb5_data *scratch;
+ krb5_data *scratch, scratch2;
krb5_ticket *sec_ticket = 0;
krb5_ticket *sec_ticket_arr[2];
+ krb5_enctype etypes[1];
+ krb5_timestamp time_now;
+ krb5_pa_data **combined_padata;
+ krb5_pa_data ap_req_padata;
+
+ if (!valid_etype(etype))
+ return KRB5_PROG_ETYPE_NOSUPP;
memset((char *)&tgsreq, 0, sizeof(tgsreq));
@@ -76,17 +85,73 @@ OLDDECLARG(krb5_response *,rep)
tgsreq.from = timestruct->starttime;
tgsreq.till = timestruct->endtime;
tgsreq.rtime = timestruct->renew_till;
- if (retval = krb5_timeofday(&tgsreq.ctime))
+ if (retval = krb5_timeofday(&time_now))
return(retval);
/* XXX we know they are the same size... */
- tgsreq.nonce = (krb5_int32) tgsreq.ctime;
+ tgsreq.nonce = (krb5_int32) time_now;
+
+ etypes[0] = etype;
+ tgsreq.etype = etypes;
+ tgsreq.netypes = 1;
- tgsreq.etype = etype;
tgsreq.addresses = (krb5_address **) addrs;
- tgsreq.authorization_data = (krb5_authdata **)authorization_data;
+
+ if (authorization_data) {
+ /* need to encrypt it in the request */
+
+ krb5_encrypt_block eblock;
+
+ if (retval = encode_krb5_authdata(authorization_data, &scratch))
+ return(retval);
+ krb5_use_cstype(&eblock, etype);
+ tgsreq.authorization_data.ciphertext.length =
+ krb5_encrypt_size(scratch->length,
+ eblock.crypto_entry);
+ /* add padding area, and zero it */
+ if (!(scratch->data = realloc(scratch->data,
+ tgsreq.authorization_data.ciphertext.length))) {
+ /* may destroy scratch->data */
+ xfree(scratch);
+ return ENOMEM;
+ }
+ memset(scratch->data + scratch->length, 0,
+ tgsreq.authorization_data.ciphertext.length - scratch->length);
+ if (!(tgsreq.authorization_data.ciphertext.data =
+ malloc(tgsreq.authorization_data.ciphertext.length))) {
+ krb5_free_data(scratch);
+ return ENOMEM;
+ }
+ if (retval = krb5_process_key(&eblock, &usecred->keyblock)) {
+ krb5_free_data(scratch);
+ return retval;
+ }
+ /* call the encryption routine */
+ if (retval = krb5_encrypt((krb5_pointer) scratch->data,
+ (krb5_pointer) tgsreq.authorization_data.ciphertext.data,
+ scratch->length, &eblock, 0)) {
+ (void) krb5_finish_key(&eblock);
+ xfree(tgsreq.authorization_data.ciphertext.data);
+ krb5_free_data(scratch);
+ return retval;
+ }
+ krb5_free_data(scratch);
+ if (retval = krb5_finish_key(&eblock)) {
+ xfree(tgsreq.authorization_data.ciphertext.data);
+ return retval;
+ }
+ }
+#define cleanup_authdata() { if (tgsreq.authorization_data.ciphertext.data) {\
+ (void) memset(tgsreq.authorization_data.ciphertext.data, 0,\
+ tgsreq.authorization_data.ciphertext.length); \
+ xfree(tgsreq.authorization_data.ciphertext.data);}}
+
+
+
if (second_ticket) {
- if (retval = decode_krb5_ticket(second_ticket, &sec_ticket))
+ if (retval = decode_krb5_ticket(second_ticket, &sec_ticket)) {
+ cleanup_authdata();
return retval;
+ }
sec_ticket_arr[0] = sec_ticket;
sec_ticket_arr[1] = 0;
tgsreq.second_ticket = sec_ticket_arr;
@@ -100,6 +165,7 @@ OLDDECLARG(krb5_response *,rep)
if (retval) {
if (sec_ticket)
krb5_free_ticket(sec_ticket);
+ cleanup_authdata();
return(retval);
}
@@ -108,6 +174,7 @@ OLDDECLARG(krb5_response *,rep)
if (sec_ticket)
krb5_free_ticket(sec_ticket);
krb5_free_data(scratch);
+ cleanup_authdata();
return ENOMEM;
}
@@ -121,6 +188,7 @@ OLDDECLARG(krb5_response *,rep)
krb5_free_ticket(sec_ticket);
xfree(ap_checksum.contents);
krb5_free_data(scratch);
+ cleanup_authdata();
return retval;
}
/* done with body */
@@ -130,8 +198,6 @@ OLDDECLARG(krb5_response *,rep)
if (sec_ticket) krb5_free_ticket(sec_ticket);}
/* attach ap_req to the tgsreq */
- tgsreq.padata_type = KRB5_PADATA_AP_REQ;
-
/*
* Get an ap_req.
*/
@@ -139,25 +205,62 @@ OLDDECLARG(krb5_response *,rep)
&ap_checksum,
0, /* don't need times */
0L, /* don't need kdc_options for this */
+ 0, /* no initial sequence */
+ 0, /* no new key */
0, /* no ccache--already have creds */
usecred,
0, /* don't need authenticator */
- &tgsreq.padata)) {
+ &scratch2)) {
cleanup();
+ cleanup_authdata();
return retval;
}
+ ap_req_padata.pa_type = KRB5_PADATA_AP_REQ;
+ ap_req_padata.length = scratch2.length;
+ ap_req_padata.contents = (krb5_octet *)scratch2.data;
+
+ /* combine in any other supplied padata */
+ if (padata) {
+ krb5_pa_data * const * counter;
+ register int i = 0;
+ for (counter = padata; *counter; counter++, i++);
+ combined_padata = (krb5_pa_data **)malloc(i+2);
+ if (!combined_padata) {
+ cleanup();
+ cleanup_authdata();
+ return ENOMEM;
+ }
+ combined_padata[0] = &ap_req_padata;
+ for (i = 1, counter = padata; *counter; counter++, i++)
+ combined_padata[i] = (krb5_pa_data *) *counter;
+ combined_padata[i] = 0;
+ } else {
+ combined_padata = (krb5_pa_data **)malloc(2*sizeof(*combined_padata));
+ if (!combined_padata) {
+ cleanup();
+ cleanup_authdata();
+ return ENOMEM;
+ }
+ combined_padata[0] = &ap_req_padata;
+ combined_padata[1] = 0;
+ }
+ tgsreq.padata = combined_padata;
/* the TGS_REQ is assembled in tgsreq, so encode it */
if (retval = encode_krb5_tgs_req(&tgsreq, &scratch)) {
cleanup();
+ cleanup_authdata();
+ xfree(combined_padata);
return(retval);
}
if (sec_ticket)
krb5_free_ticket(sec_ticket);
+ cleanup_authdata();
+ xfree(combined_padata);
+#undef cleanup_authdata
#undef cleanup
-#define cleanup() {(void) free(tgsreq.padata.data); \
- xfree(ap_checksum.contents);}
+#define cleanup() {xfree(ap_checksum.contents);}
/* now send request & get response from KDC */
retval = krb5_sendto_kdc(scratch, krb5_princ_realm(sname),