RFC1510 - The Kerberos Network Authentication Service (V5)(5)

时间:2005-02-14 来源: 作者: 点击:
endif if (!server) then /* no server in Database */ error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN); endif if(client.pa_enc_timestamp_required and pa_enc_timestamp not present) then error_out(KDC_ERR_PREAUTH_
  
endif
if (!server) then
/* no server in Database */
error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
endif

if(client.pa_enc_timestamp_required and
pa_enc_timestamp not present) then
error_out(KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP));
endif

if(pa_enc_timestamp present) then
decrypt req.padata-value into decrypted_enc_timestamp
using client.key;
using auth_hdr.authenticator.subkey;
if (decrypt_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
if(decrypted_enc_timestamp is not within allowable
skew) then error_out(KDC_ERR_PREAUTH_FAILED);
endif
if(decrypted_enc_timestamp and usec is replay)
error_out(KDC_ERR_PREAUTH_FAILED);
endif
add decrypted_enc_timestamp and usec to replay cache;
endif

use_etype := first supported etype in req.etypes;

if (no support for req.etypes) then
error_out(KDC_ERR_ETYPE_NOSUPP);
endif

new_tkt.vno := ticket version; /* = 5 */
new_tkt.sname := req.sname;
new_tkt.srealm := req.srealm;
reset all flags in new_tkt.flags;

/* It should be noted that local policy may affect the */
/* processing of any of these flags. For example, some */
/* realms may refuse to issue renewable tickets */

if (req.kdc-options.FORWARDABLE is set) then
set new_tkt.flags.FORWARDABLE;
endif
if (req.kdc-options.PROXIABLE is set) then
set new_tkt.flags.PROXIABLE;
endif
if (req.kdc-options.ALLOW-POSTDATE is set) then
set new_tkt.flags.ALLOW-POSTDATE;
endif
if ((req.kdc-options.RENEW is set) or
(req.kdc-options.VALIDATE is set) or
(req.kdc-options.PROXY is set) or
(req.kdc-options.FORWARDED is set) or
(req.kdc-options.ENC-TKT-IN-SKEY is set)) then
error_out(KDC_ERR_BADOPTION);
endif

new_tkt.session := random_session_key();
new_tkt.cname := req.cname;
new_tkt.crealm := req.crealm;
new_tkt.transited := empty_transited_field();

new_tkt.authtime := kdc_time;

if (req.kdc-options.POSTDATED is set) then
if (against_postdate_policy(req.from)) then
error_out(KDC_ERR_POLICY);
endif
set new_tkt.flags.INVALID;
new_tkt.starttime := req.from;
else
omit new_tkt.starttime; /* treated as authtime when
omitted */
endif
if (req.till = 0) then
till := infinity;
else
till := req.till;
endif

new_tkt.endtime := min(till,
new_tkt.starttime+client.max_life,
new_tkt.starttime+server.max_life,
new_tkt.starttime+max_life_for_realm);

if ((req.kdc-options.RENEWABLE-OK is set) and
(new_tkt.endtime < req.till)) then
/* we set the RENEWABLE option for later processing */
set req.kdc-options.RENEWABLE;
req.rtime := req.till;
endif

if (req.rtime = 0) then
rtime := infinity;
else
rtime := req.rtime;
endif

if (req.kdc-options.RENEWABLE is set) then
set new_tkt.flags.RENEWABLE;
new_tkt.renew-till := min(rtime,
new_tkt.starttime+client.max_rlife,
new_tkt.starttime+server.max_rlife,
new_tkt.starttime+max_rlife_for_realm);
else
omit new_tkt.renew-till; /* only present if RENEWABLE */
endif

if (req.addresses) then
new_tkt.caddr := req.addresses;
else
omit new_tkt.caddr;
endif

new_tkt.authorization_data := empty_authorization_data();

encode to-be-encrypted part of ticket into OCTET STRING;
new_tkt.enc-part := encrypt OCTET STRING
using etype_for_key(server.key), server.key, server.p_kvno;

/* Start processing the response */

resp.pvno := 5;
resp.msg-type := KRB_AS_REP;
resp.cname := req.cname;
resp.crealm := req.realm;
resp.ticket := new_tkt;

resp.key := new_tkt.session;
resp.last-req := fetch_last_request_info(client);
resp.nonce := req.nonce;
resp.key-expiration := client.expiration;

resp.flags := new_tkt.flags;

resp.authtime := new_tkt.authtime;
resp.starttime := new_tkt.starttime;
resp.endtime := new_tkt.endtime;

if (new_tkt.flags.RENEWABLE) then
resp.renew-till := new_tkt.renew-till;
endif

resp.realm := new_tkt.realm;
resp.sname := new_tkt.sname;

resp.caddr := new_tkt.caddr;

encode body of reply into OCTET STRING;

resp.enc-part := encrypt OCTET STRING
using use_etype, client.key, client.p_kvno;
send(resp);

A.3. KRB_AS_REP verification
decode response into resp;

if (resp.msg-type = KRB_ERROR) then
if(error = KDC_ERR_PREAUTH_REQUIRED(PA_ENC_TIMESTAMP))
then set pa_enc_timestamp_required;
goto KRB_AS_REQ;
endif
process_error(resp);
return;
endif

/* On error, discard the response, and zero the session key */
/* from the response immediately */

key = get_decryption_key(resp.enc-part.kvno, resp.enc-part.etype,
resp.padata);
unencrypted part of resp := decode of decrypt of resp.enc-part
using resp.enc-part.etype and key;
zero(key);

if (common_as_rep_tgs_rep_checks fail) then
destroy resp.key;
return error;
endif

if near(resp.princ_exp) then

print(warning message);
endif
save_for_later(ticket,session,client,server,times,flags);

A.4. KRB_AS_REP and KRB_TGS_REP common checks
if (decryption_error() or
(req.cname != resp.cname) or
(req.realm != resp.crealm) or
(req.sname != resp.sname) or
(req.realm != resp.realm) or
(req.nonce != resp.nonce) or
(req.addresses != resp.caddr)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif

/* make sure no flags are set that shouldn't be, and that */
/* all that should be are set */
if (!check_flags_for_compatability(req.kdc-options,resp.flags))
then destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif

if ((req.from = 0) and
(resp.starttime is not within allowable skew)) then
destroy resp.key;
return KRB_AP_ERR_SKEW;
endif
if ((req.from != 0) and (req.from != resp.starttime)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.till != 0) and (resp.endtime > req.till)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif

if ((req.kdc-options.RENEWABLE is set) and
(req.rtime != 0) and (resp.renew-till > req.rtime)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;
endif
if ((req.kdc-options.RENEWABLE-OK is set) and
(resp.flags.RENEWABLE) and
(req.till != 0) and
(resp.renew-till > req.till)) then
destroy resp.key;
return KRB_AP_ERR_MODIFIED;

endif

A.5. KRB_TGS_REQ generation
/* Note that make_application_request might have to */
/* recursivly call this routine to get the appropriate */
/* ticket-granting ticket */

request.pvno := protocol version; /* pvno = 5 */
request.msg-type := message type; /* type = KRB_TGS_REQ */

body.kdc-options := users's preferences;
/* If the TGT is not for the realm of the end-server */
/* then the sname will be for a TGT for the end-realm */
/* and the realm of the requested ticket (body.realm) */
/* will be that of the TGS to which the TGT we are */
/* sending applies */
body.sname := service's name;
body.realm := service's realm;

if (body.kdc-options.POSTDATED is set) then
body.from := requested starting time;
else
omit body.from;
endif
body.till := requested end time;
if (body.kdc-options.RENEWABLE is set) then
body.rtime := requested final renewal time;
endif
body.nonce := random_nonce();
body.etype := requested etypes;
if (user supplied addresses) then
body.addresses := user's addresses;
else
omit body.addresses;
endif

body.enc-authorization-data := user-supplied data;
if (body.kdc-options.ENC-TKT-IN-SKEY) then
body.additional-tickets_ticket := second TGT;
endif

request.req-body := body;
check := generate_checksum (req.body,checksumtype);

request.padata[0].padata-type := PA-TGS-REQ;
request.padata[0].padata-value := create a KRB_AP_REQ using
the TGT and checksum

/* add in any other padata as required/supplied */

kerberos := lookup(name of local kerberose server (or servers));
send(packet,kerberos);

wait(for response);
if (timed_out) then
retry or use alternate server;
endif

A.6. KRB_TGS_REQ verification and KRB_TGS_REP generation
/* note that reading the application request requires first
determining the server for which a ticket was issued, and
choosing the correct key for decryption. The name of the
server appears in the plaintext part of the ticket. */

if (no KRB_AP_REQ in req.padata) then
error_out(KDC_ERR_PADATA_TYPE_NOSUPP);
endif
verify KRB_AP_REQ in req.padata;

/* Note that the realm in which the Kerberos server is
operating is determined by the instance from the
ticket-granting ticket. The realm in the ticket-granting
ticket is the realm under which the ticket granting ticket was
issued. It is possible for a single Kerberos server to
support more than one realm. */

auth_hdr := KRB_AP_REQ;
tgt := auth_hdr.ticket;

if (tgt.sname is not a TGT for local realm and is not
req.sname) then error_out(KRB_AP_ERR_NOT_US);

realm := realm_tgt_is_for(tgt);

decode remainder of request;

if (auth_hdr.authenticator.cksum is missing) then
error_out(KRB_AP_ERR_INAPP_CKSUM);
endif
if (auth_hdr.authenticator.cksum type is not supported) then
error_out(KDC_ERR_SUMTYPE_NOSUPP);
endif
if (auth_hdr.authenticator.cksum is not both collision-proof
and keyed) then
error_out(KRB_AP_ERR_INAPP_CKSUM);
endif

set computed_checksum := checksum(req);
if (computed_checksum != auth_hdr.authenticatory.cksum) then
error_out(KRB_AP_ERR_MODIFIED);
endif

server := lookup(req.sname,realm);

if (!server) then
if (is_foreign_tgt_name(server)) then
server := best_intermediate_tgs(server);
else
/* no server in Database */
error_out(KDC_ERR_S_PRINCIPAL_UNKNOWN);
endif
endif

session := generate_random_session_key();

use_etype := first supported etype in req.etypes;

if (no support for req.etypes) then
error_out(KDC_ERR_ETYPE_NOSUPP);
endif

new_tkt.vno := ticket version; /* = 5 */
new_tkt.sname := req.sname;
new_tkt.srealm := realm;
reset all flags in new_tkt.flags;

/* It should be noted that local policy may affect the */
/* processing of any of these flags. For example, some */
/* realms may refuse to issue renewable tickets */

new_tkt.caddr := tgt.caddr;
resp.caddr := NULL; /* We only include this if they change */
if (req.kdc-options.FORWARDABLE is set) then
if (tgt.flags.FORWARDABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.FORWARDABLE;
endif
if (req.kdc-options.FORWARDED is set) then
if (tgt.flags.FORWARDABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.FORWARDED;
new_tkt.caddr := req.addresses;

resp.caddr := req.addresses;
endif
if (tgt.flags.FORWARDED is set) then
set new_tkt.flags.FORWARDED;
endif

if (req.kdc-options.PROXIABLE is set) then
if (tgt.flags.PROXIABLE is reset)
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.PROXIABLE;
endif
if (req.kdc-options.PROXY is set) then
if (tgt.flags.PROXIABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.PROXY;
new_tkt.caddr := req.addresses;
resp.caddr := req.addresses;
endif

if (req.kdc-options.POSTDATE is set) then
if (tgt.flags.POSTDATE is reset)
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.POSTDATE;
endif
if (req.kdc-options.POSTDATED is set) then
if (tgt.flags.POSTDATE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
set new_tkt.flags.POSTDATED;
set new_tkt.flags.INVALID;
if (against_postdate_policy(req.from)) then
error_out(KDC_ERR_POLICY);
endif
new_tkt.starttime := req.from;
endif

if (req.kdc-options.VALIDATE is set) then
if (tgt.flags.INVALID is reset) then
error_out(KDC_ERR_POLICY);
endif
if (tgt.starttime > kdc_time) then
error_out(KRB_AP_ERR_NYV);
endif
if (check_hot_list(tgt)) then

error_out(KRB_AP_ERR_REPEAT);
endif
tkt := tgt;
reset new_tkt.flags.INVALID;
endif

if (req.kdc-options.(any flag except ENC-TKT-IN-SKEY, RENEW,
and those already processed) is set) then
error_out(KDC_ERR_BADOPTION);
endif

new_tkt.authtime := tgt.authtime;

if (req.kdc-options.RENEW is set) then
/* Note that if the endtime has already passed, the ticket */
/* would have been rejected in the initial authentication */
/* stage, so there is no need to check again here */
if (tgt.flags.RENEWABLE is reset) then
error_out(KDC_ERR_BADOPTION);
endif
if (tgt.renew-till >= kdc_time) then
error_out(KRB_AP_ERR_TKT_EXPIRED);
endif
tkt := tgt;
new_tkt.starttime := kdc_time;
old_life := tgt.endttime - tgt.starttime;
new_tkt.endtime := min(tgt.renew-till,
new_tkt.starttime + old_life);
else
new_tkt.starttime := kdc_time;
if (req.till = 0) then
till := infinity;
else
till := req.till;
endif
new_tkt.endtime := min(till,
new_tkt.starttime+client.max_life,
new_tkt.starttime+server.max_life,
new_tkt.starttime+max_life_for_realm,
tgt.endtime);

if ((req.kdc-options.RENEWABLE-OK is set) and
(new_tkt.endtime < req.till) and
(tgt.flags.RENEWABLE is set) then
/* we set the RENEWABLE option for later */
/* processing */
set req.kdc-options.RENEWABLE;
req.rtime := min(req.till, tgt.renew-till);

endif
endif

if (req.rtime = 0) then
rtime := infinity;
else
rtime := req.rtime;
endif

if ((req.kdc-options.RENEWABLE is set) and
(tgt.flags.RENEWABLE is set)) then
set new_tkt.flags.RENEWABLE;
new_tkt.renew-till := min(rtime,
new_tkt.starttime+client.max_rlife,
new_tkt.starttime+server.max_rlife,
new_tkt.starttime+max_rlife_for_realm,
tgt.renew-till);
else
new_tkt.renew-till := OMIT;
/* leave the renew-till field out */
endif
if (req.enc-authorization-data is present) then
decrypt req.enc-authorization-data
into decrypted_authorization_data
using auth_hdr.authenticator.subkey;
if (decrypt_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
endif
new_tkt.authorization_data :=
req.auth_hdr.ticket.authorization_data +
decrypted_authorization_data;

new_tkt.key := session;
new_tkt.crealm := tgt.crealm;
new_tkt.cname := req.auth_hdr.ticket.cname;

if (realm_tgt_is_for(tgt) := tgt.realm) then
/* tgt issued by local realm */
new_tkt.transited := tgt.transited;
else
/* was issued for this realm by some other realm */
if (tgt.transited.tr-type not supported) then
error_out(KDC_ERR_TRTYPE_NOSUPP);
endif
new_tkt.transited
:= compress_transited(tgt.transited + tgt.realm)
endif

encode encrypted part of new_tkt into OCTET STRING;
if (req.kdc-options.ENC-TKT-IN-SKEY is set) then
if (server not specified) then
server = req.second_ticket.client;
endif
if ((req.second_ticket is not a TGT) or
(req.second_ticket.client != server)) then
error_out(KDC_ERR_POLICY);
endif

new_tkt.enc-part := encrypt OCTET STRING using
using etype_for_key(second-ticket.key),
second-ticket.key;
else
new_tkt.enc-part := encrypt OCTET STRING
using etype_for_key(server.key), server.key,
server.p_kvno;
endif

resp.pvno := 5;
resp.msg-type := KRB_TGS_REP;
resp.crealm := tgt.crealm;
resp.cname := tgt.cname;
resp.ticket := new_tkt;

resp.key := session;
resp.nonce := req.nonce;
resp.last-req := fetch_last_request_info(client);
resp.flags := new_tkt.flags;

resp.authtime := new_tkt.authtime;
resp.starttime := new_tkt.starttime;
resp.endtime := new_tkt.endtime;

omit resp.key-expiration;

resp.sname := new_tkt.sname;
resp.realm := new_tkt.realm;

if (new_tkt.flags.RENEWABLE) then
resp.renew-till := new_tkt.renew-till;
endif

encode body of reply into OCTET STRING;

if (req.padata.authenticator.subkey)
resp.enc-part := encrypt OCTET STRING using use_etype,

req.padata.authenticator.subkey;
else resp.enc-part := encrypt OCTET STRING
using use_etype, tgt.key;

send(resp);

A.7. KRB_TGS_REP verification
decode response into resp;

if (resp.msg-type = KRB_ERROR) then
process_error(resp);
return;
endif

/* On error, discard the response, and zero the session key from
the response immediately */

if (req.padata.authenticator.subkey)
unencrypted part of resp :=
decode of decrypt of resp.enc-part
using resp.enc-part.etype and subkey;
else unencrypted part of resp :=
decode of decrypt of resp.enc-part
using resp.enc-part.etype and tgt's session key;
if (common_as_rep_tgs_rep_checks fail) then
destroy resp.key;
return error;
endif

check authorization_data as necessary;
save_for_later(ticket,session,client,server,times,flags);

A.8. Authenticator generation
body.authenticator-vno := authenticator vno; /* = 5 */
body.cname, body.crealm := client name;
if (supplying checksum) then
body.cksum := checksum;
endif
get system_time;
body.ctime, body.cusec := system_time;
if (selecting sub-session key) then
select sub-session key;
body.subkey := sub-session key;
endif
if (using sequence numbers) then
select initial sequence number;
body.seq-number := initial sequence;
endif

A.9. KRB_AP_REQ generation
obtain ticket and session_key from cache;

packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_AP_REQ */

if (desired(MUTUAL_AUTHENTICATION)) then
set packet.ap-options.MUTUAL-REQUIRED;
else
reset packet.ap-options.MUTUAL-REQUIRED;
endif
if (using session key for ticket) then
set packet.ap-options.USE-SESSION-KEY;
else
reset packet.ap-options.USE-SESSION-KEY;
endif
packet.ticket := ticket; /* ticket */
generate authenticator;
encode authenticator into OCTET STRING;
encrypt OCTET STRING into packet.authenticator
using session_key;

A.10. KRB_AP_REQ verification
receive packet;
if (packet.pvno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.msg-type != KRB_AP_REQ) then
error_out(KRB_AP_ERR_MSG_TYPE);
endif
if (packet.ticket.tkt_vno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.ap_options.USE-SESSION-KEY is set) then
retrieve session key from ticket-granting ticket for
packet.ticket.{sname,srealm,enc-part.etype};
else
retrieve service key for
packet.ticket.{sname,srealm,enc-part.etype,enc-part.skvno};
endif
if (no_key_available) then
if (cannot_find_specified_skvno) then
error_out(KRB_AP_ERR_BADKEYVER);
else
error_out(KRB_AP_ERR_NOKEY);
endif

endif
decrypt packet.ticket.enc-part into decr_ticket
using retrieved key;
if (decryption_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
decrypt packet.authenticator into decr_authenticator
using decr_ticket.key;
if (decryption_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
if (decr_authenticator.{cname,crealm} !=
decr_ticket.{cname,crealm}) then
error_out(KRB_AP_ERR_BADMATCH);
endif
if (decr_ticket.caddr is present) then
if (sender_address(packet) is not in decr_ticket.caddr)
then error_out(KRB_AP_ERR_BADADDR);
endif
elseif (application requires addresses) then
error_out(KRB_AP_ERR_BADADDR);
endif
if (not in_clock_skew(decr_authenticator.ctime,
decr_authenticator.cusec)) then
error_out(KRB_AP_ERR_SKEW);
endif
if (repeated(decr_authenticator.{ctime,cusec,cname,crealm}))
then error_out(KRB_AP_ERR_REPEAT);
endif
save_identifier(decr_authenticator.{ctime,cusec,cname,crealm});
get system_time;
if ((decr_ticket.starttime-system_time > CLOCK_SKEW) or
(decr_ticket.flags.INVALID is set)) then
/* it hasn't yet become valid */
error_out(KRB_AP_ERR_TKT_NYV);
endif
if (system_time-decr_ticket.endtime > CLOCK_SKEW) then
error_out(KRB_AP_ERR_TKT_EXPIRED);
endif
/* caller must check decr_ticket.flags for any pertinent */
/* details */
return(OK, decr_ticket, packet.ap_options.MUTUAL-REQUIRED);

A.11. KRB_AP_REP generation
packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_AP_REP */
body.ctime := packet.ctime;
body.cusec := packet.cusec;

if (selecting sub-session key) then
select sub-session key;
body.subkey := sub-session key;
endif
if (using sequence numbers) then
select initial sequence number;
body.seq-number := initial sequence;
endif

encode body into OCTET STRING;

select encryption type;
encrypt OCTET STRING into packet.enc-part;

A.12. KRB_AP_REP verification
receive packet;
if (packet.pvno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.msg-type != KRB_AP_REP) then
error_out(KRB_AP_ERR_MSG_TYPE);
endif
cleartext := decrypt(packet.enc-part)
using ticket's session key;
if (decryption_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
if (cleartext.ctime != authenticator.ctime) then
error_out(KRB_AP_ERR_MUT_FAIL);
endif
if (cleartext.cusec != authenticator.cusec) then
error_out(KRB_AP_ERR_MUT_FAIL);
endif
if (cleartext.subkey is present) then
save cleartext.subkey for future use;
endif
if (cleartext.seq-number is present) then
save cleartext.seq-number for future verifications;
endif
return(AUTHENTICATION_SUCCEEDED);

A.13. KRB_SAFE generation
collect user data in buffer;

/* assemble packet: */
packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_SAFE */

body.user-data := buffer; /* DATA */
if (using timestamp) then
get system_time;
body.timestamp, body.usec := system_time;
endif
if (using sequence numbers) then
body.seq-number := sequence number;
endif
body.s-address := sender host addresses;
if (only one recipient) then
body.r-address := recipient host address;
endif
checksum.cksumtype := checksum type;
compute checksum over body;
checksum.checksum := checksum value; /* checksum.checksum */
packet.cksum := checksum;
packet.safe-body := body;

A.14. KRB_SAFE verification
receive packet;
if (packet.pvno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.msg-type != KRB_SAFE) then
error_out(KRB_AP_ERR_MSG_TYPE);
endif
if (packet.checksum.cksumtype is not both collision-proof
and keyed) then
error_out(KRB_AP_ERR_INAPP_CKSUM);
endif
if (safe_priv_common_checks_ok(packet)) then
set computed_checksum := checksum(packet.body);
if (computed_checksum != packet.checksum) then
error_out(KRB_AP_ERR_MODIFIED);
endif
return (packet, PACKET_IS_GENUINE);
else
return common_checks_error;
endif

A.15. KRB_SAFE and KRB_PRIV common checks
if (packet.s-address != O/S_sender(packet)) then
/* O/S report of sender not who claims to have sent it */
error_out(KRB_AP_ERR_BADADDR);
endif
if ((packet.r-address is present) and
(packet.r-address != local_host_address)) then

/* was not sent to proper place */
error_out(KRB_AP_ERR_BADADDR);
endif
if (((packet.timestamp is present) and
(not in_clock_skew(packet.timestamp,packet.usec))) or
(packet.timestamp is not present and timestamp expected))
then error_out(KRB_AP_ERR_SKEW);
endif
if (repeated(packet.timestamp,packet.usec,packet.s-address))
then error_out(KRB_AP_ERR_REPEAT);
endif
if (((packet.seq-number is present) and
((not in_sequence(packet.seq-number)))) or
(packet.seq-number is not present and sequence expected))
then error_out(KRB_AP_ERR_BADORDER);
endif
if (packet.timestamp not present and
packet.seq-number not present) then
error_out(KRB_AP_ERR_MODIFIED);
endif

save_identifier(packet.{timestamp,usec,s-address},
sender_principal(packet));

return PACKET_IS_OK;

A.16. KRB_PRIV generation
collect user data in buffer;

/* assemble packet: */
packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_PRIV */

packet.enc-part.etype := encryption type;

body.user-data := buffer;
if (using timestamp) then
get system_time;
body.timestamp, body.usec := system_time;
endif
if (using sequence numbers) then
body.seq-number := sequence number;
endif
body.s-address := sender host addresses;
if (only one recipient) then
body.r-address := recipient host address;
endif

encode body into OCTET STRING;

select encryption type;
encrypt OCTET STRING into packet.enc-part.cipher;

A.17. KRB_PRIV verification
receive packet;
if (packet.pvno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.msg-type != KRB_PRIV) then
error_out(KRB_AP_ERR_MSG_TYPE);
endif

cleartext := decrypt(packet.enc-part) using negotiated key;
if (decryption_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif

if (safe_priv_common_checks_ok(cleartext)) then
return(cleartext.DATA, PACKET_IS_GENUINE_AND_UNMODIFIED);
else
return common_checks_error;
endif

A.18. KRB_CRED generation
invoke KRB_TGS; /* obtain tickets to be provided to peer */

/* assemble packet: */
packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_CRED */

for (tickets[n] in tickets to be forwarded) do
packet.tickets[n] = tickets[n].ticket;
done

packet.enc-part.etype := encryption type;

for (ticket[n] in tickets to be forwarded) do
body.ticket-info[n].key = tickets[n].session;
body.ticket-info[n].prealm = tickets[n].crealm;
body.ticket-info[n].pname = tickets[n].cname;
body.ticket-info[n].flags = tickets[n].flags;
body.ticket-info[n].authtime = tickets[n].authtime;
body.ticket-info[n].starttime = tickets[n].starttime;
body.ticket-info[n].endtime = tickets[n].endtime;
body.ticket-info[n].renew-till = tickets[n].renew-till;

body.ticket-info[n].srealm = tickets[n].srealm;
body.ticket-info[n].sname = tickets[n].sname;
body.ticket-info[n].caddr = tickets[n].caddr;
done

get system_time;
body.timestamp, body.usec := system_time;

if (using nonce) then
body.nonce := nonce;
endif

if (using s-address) then
body.s-address := sender host addresses;
endif
if (limited recipients) then
body.r-address := recipient host address;
endif

encode body into OCTET STRING;

select encryption type;
encrypt OCTET STRING into packet.enc-part.cipher
using negotiated encryption key;

A.19. KRB_CRED verification
receive packet;
if (packet.pvno != 5) then
either process using other protocol spec
or error_out(KRB_AP_ERR_BADVERSION);
endif
if (packet.msg-type != KRB_CRED) then
error_out(KRB_AP_ERR_MSG_TYPE);
endif

cleartext := decrypt(packet.enc-part) using negotiated key;
if (decryption_error()) then
error_out(KRB_AP_ERR_BAD_INTEGRITY);
endif
if ((packet.r-address is present or required) and
(packet.s-address != O/S_sender(packet)) then
/* O/S report of sender not who claims to have sent it */
error_out(KRB_AP_ERR_BADADDR);
endif
if ((packet.r-address is present) and
(packet.r-address != local_host_address)) then
/* was not sent to proper place */
error_out(KRB_AP_ERR_BADADDR);

endif
if (not in_clock_skew(packet.timestamp,packet.usec)) then
error_out(KRB_AP_ERR_SKEW);
endif
if (repeated(packet.timestamp,packet.usec,packet.s-address))
then error_out(KRB_AP_ERR_REPEAT);
endif
if (packet.nonce is required or present) and
(packet.nonce != expected-nonce) then
error_out(KRB_AP_ERR_MODIFIED);
endif

for (ticket[n] in tickets that were forwarded) do
save_for_later(ticket[n],key[n],principal[n],
server[n],times[n],flags[n]);
return

A.20. KRB_ERROR generation

/* assemble packet: */
packet.pvno := protocol version; /* 5 */
packet.msg-type := message type; /* KRB_ERROR */

get system_time;
packet.stime, packet.susec := system_time;
packet.realm, packet.sname := server name;

if (client time available) then
packet.ctime, packet.cusec := client_time;
endif
packet.error-code := error code;
if (client name available) then
packet.cname, packet.crealm := client name;
endif
if (error text available) then
packet.e-text := error text;
endif
if (error data available) then
packet.e-data := error data;
endif
------分隔线----------------------------
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容