decode message into req; client := lookup(req.cname,req.realm); server := lookup(req.sname,req.realm); get system_time; kdc_time := system_time.seconds; if (!client) then /* no client in Database */ error_out(KDC_ERR_C_PRINCIPAL_UNKNOWN); 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);