#ifndef __KRB5_KDC_UTIL__
#define __KRB5_KDC_UTIL__
#include <krb5/kdcpreauth_plugin.h>
#include "kdb.h"
#include "net-server.h"
#include "realm_data.h"
#include "reqstate.h"
krb5_boolean krb5_is_tgs_principal (krb5_const_principal);
krb5_boolean is_cross_tgs_principal(krb5_const_principal);
krb5_boolean is_local_tgs_principal(krb5_const_principal);
krb5_error_code
add_to_transited (krb5_data *,
krb5_data *,
krb5_principal,
krb5_principal,
krb5_principal);
krb5_error_code
compress_transited (krb5_data *,
krb5_principal,
krb5_data *);
krb5_error_code
fetch_last_req_info (krb5_db_entry *, krb5_last_req_entry ***);
krb5_error_code
kdc_convert_key (krb5_keyblock *, krb5_keyblock *, int);
krb5_error_code
kdc_process_tgs_req (kdc_realm_t *, krb5_kdc_req *,
const struct sockaddr *,
krb5_data *,
krb5_ticket **,
krb5_db_entry **krbtgt_ptr,
krb5_keyblock **, krb5_keyblock **,
krb5_pa_data **pa_tgs_req);
krb5_error_code
kdc_get_server_key (krb5_context, krb5_ticket *, unsigned int,
krb5_boolean match_enctype,
krb5_db_entry **, krb5_keyblock **, krb5_kvno *);
krb5_error_code
get_first_current_key(krb5_context context, krb5_db_entry *entry,
krb5_keyblock *key_out);
krb5_error_code
get_local_tgt(krb5_context context, const krb5_data *realm,
krb5_db_entry *candidate, krb5_db_entry **alias_out,
krb5_db_entry **storage_out, krb5_keyblock *kb_out);
krb5_error_code
validate_as_request (kdc_realm_t *, krb5_kdc_req *, krb5_db_entry *,
krb5_db_entry *, krb5_timestamp,
const char **, krb5_pa_data ***);
krb5_error_code
check_tgs_constraints(kdc_realm_t *realm, krb5_kdc_req *request,
krb5_db_entry *server, krb5_ticket *ticket, krb5_pac pac,
const krb5_ticket *stkt, krb5_pac stkt_pac,
krb5_db_entry *stkt_server, krb5_timestamp kdc_time,
krb5_pa_s4u_x509_user *s4u_x509_user,
krb5_db_entry *s4u2self_client,
krb5_boolean is_crossrealm, krb5_boolean is_referral,
const char **status, krb5_pa_data ***e_data);
krb5_error_code
check_tgs_policy(kdc_realm_t *realm, krb5_kdc_req *request,
krb5_db_entry *server, krb5_ticket *ticket,
krb5_pac pac, const krb5_ticket *stkt, krb5_pac stkt_pac,
krb5_principal stkt_pac_client, krb5_db_entry *stkt_server,
krb5_timestamp kdc_time, krb5_boolean is_crossrealm,
krb5_boolean is_referral, const char **status,
krb5_pa_data ***e_data);
krb5_flags
get_ticket_flags(krb5_flags reqflags, krb5_db_entry *client,
krb5_db_entry *server, krb5_enc_tkt_part *header_enc);
krb5_error_code
check_indicators(krb5_context context, krb5_db_entry *server,
krb5_data *const *indicators);
int
fetch_asn1_field (unsigned char *, unsigned int, unsigned int, krb5_data *);
krb5_enctype
select_session_keytype (krb5_context context, krb5_db_entry *server,
int nktypes, krb5_enctype *ktypes);
void limit_string (char *name);
char *ktypes2str(krb5_enctype *ktype, int nktypes);
char *rep_etypes2str(krb5_kdc_rep *rep);
krb5_boolean
authind_contains(krb5_data *const *indicators, const char *ind);
krb5_error_code
authind_add(krb5_context context, const char *ind, krb5_data ***indicators);
krb5_error_code
authind_extract(krb5_context context, krb5_authdata **authdata,
krb5_data ***indicators);
krb5_error_code
cammac_create(krb5_context context, krb5_enc_tkt_part *enc_tkt_reply,
krb5_keyblock *server_key, krb5_db_entry *tgt,
krb5_keyblock *tgt_key, krb5_authdata **contents,
krb5_authdata ***cammac_out);
krb5_boolean
cammac_check_kdcver(krb5_context context, krb5_cammac *cammac,
krb5_enc_tkt_part *enc_tkt, krb5_db_entry *tgt,
krb5_keyblock *tgt_key);
void
process_as_req (krb5_kdc_req *, krb5_data *,
const struct sockaddr *, const struct sockaddr *,
kdc_realm_t *, verto_ctx *, loop_respond_fn, void *);
krb5_error_code
process_tgs_req (krb5_kdc_req *, krb5_data *, const struct sockaddr *,
kdc_realm_t *, krb5_data ** );
void
dispatch (void *,
const struct sockaddr *,
const struct sockaddr *,
krb5_data *,
int,
verto_ctx *,
loop_respond_fn,
void *);
void
kdc_err(krb5_context call_context, errcode_t code, const char *fmt, ...)
#if !defined(__cplusplus) && (__GNUC__ > 2)
__attribute__((__format__(__printf__, 3, 4)))
#endif
;
krb5_boolean
enctype_requires_etype_info_2(krb5_enctype enctype);
const char *
missing_required_preauth (krb5_db_entry *client,
krb5_db_entry *server,
krb5_enc_tkt_part *enc_tkt_reply);
typedef void (*kdc_hint_respond_fn)(void *arg);
void
get_preauth_hint_list(krb5_kdc_req *request,
krb5_kdcpreauth_rock rock, krb5_pa_data ***e_data_out,
kdc_hint_respond_fn respond, void *arg);
void
load_preauth_plugins(struct server_handle * handle, krb5_context context,
verto_ctx *ctx);
void
unload_preauth_plugins(krb5_context context);
typedef void (*kdc_preauth_respond_fn)(void *arg, krb5_error_code code);
void
check_padata(krb5_context context, krb5_kdcpreauth_rock rock,
krb5_data *req_pkt, krb5_kdc_req *request,
krb5_enc_tkt_part *enc_tkt_reply, void **padata_context,
krb5_pa_data ***e_data, krb5_boolean *typed_e_data,
kdc_preauth_respond_fn respond, void *state);
krb5_error_code
return_padata(krb5_context context, krb5_kdcpreauth_rock rock,
krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_keyblock *encrypting_key, void **padata_context);
void
free_padata_context(krb5_context context, void *padata_context);
krb5_error_code
kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
int min_ver, krb5_plugin_vtable vtable);
krb5_error_code
kdcpreauth_encrypted_timestamp_initvt(krb5_context context, int maj_ver,
int min_ver, krb5_plugin_vtable vtable);
krb5_error_code
load_authdata_plugins(krb5_context context);
krb5_error_code
unload_authdata_plugins(krb5_context context);
krb5_error_code
get_auth_indicators(krb5_context context, krb5_enc_tkt_part *enc_tkt,
krb5_db_entry *local_tgt, krb5_keyblock *local_tgt_key,
krb5_data ***indicators_out);
krb5_error_code
handle_authdata(kdc_realm_t *realm, unsigned int flags, krb5_db_entry *client,
krb5_db_entry *server, krb5_db_entry *subject_server,
krb5_db_entry *local_tgt, krb5_keyblock *local_tgt_key,
krb5_keyblock *client_key, krb5_keyblock *server_key,
krb5_keyblock *header_key, krb5_keyblock *replaced_reply_key,
krb5_data *req_pkt, krb5_kdc_req *request,
krb5_const_principal altcprinc, krb5_pac subject_pac,
krb5_enc_tkt_part *enc_tkt_request,
krb5_data ***auth_indicators,
krb5_enc_tkt_part *enc_tkt_reply);
krb5_error_code kdc_init_lookaside(krb5_context context);
krb5_boolean kdc_check_lookaside (krb5_context, krb5_data *, krb5_data **);
void kdc_insert_lookaside (krb5_context, krb5_data *, krb5_data *);
void kdc_remove_lookaside (krb5_context kcontext, krb5_data *);
void kdc_free_lookaside(krb5_context);
void reset_for_hangup(void *);
krb5_error_code
pac_privsvr_key(krb5_context context, krb5_db_entry *server,
const krb5_keyblock *tgt_key, krb5_keyblock **key_out);
krb5_error_code
get_verified_pac(krb5_context context, const krb5_enc_tkt_part *enc_tkt,
krb5_db_entry *server, krb5_keyblock *server_key,
krb5_db_entry *tgt, krb5_keyblock *tgt_key,
krb5_pac *pac_out);
krb5_error_code
get_pac_princ_with_realm(krb5_context context, krb5_pac pac,
krb5_principal *princ_out,
krb5_timestamp *authtime_out);
krb5_boolean
include_pac_p(krb5_context context, krb5_kdc_req *request);
krb5_error_code
return_enc_padata(krb5_context context,
krb5_data *req_pkt, krb5_kdc_req *request,
krb5_keyblock *reply_key,
krb5_db_entry *server,
krb5_enc_kdc_rep_part *reply_encpart,
krb5_boolean is_referral);
krb5_error_code
kdc_process_s4u2self_req(krb5_context context, krb5_kdc_req *request,
const krb5_db_entry *server,
krb5_keyblock *tgs_subkey, krb5_keyblock *tgs_session,
krb5_pa_s4u_x509_user **s4u2self_req,
krb5_db_entry **princ_ptr, const char **status);
krb5_error_code
s4u2self_forwardable(krb5_context context, krb5_db_entry *server,
krb5_flags *tktflags);
krb5_error_code
kdc_make_s4u2self_rep (krb5_context context,
krb5_keyblock *tgs_subkey,
krb5_keyblock *tgs_session,
krb5_pa_s4u_x509_user *req_s4u_user,
krb5_kdc_rep *reply,
krb5_enc_kdc_rep_part *reply_encpart);
krb5_error_code
kdc_check_transited_list(krb5_context context, const krb5_data *trans,
const krb5_data *realm1, const krb5_data *realm2);
void
kdc_get_ticket_endtime(kdc_realm_t *realm, krb5_timestamp now,
krb5_timestamp endtime, krb5_timestamp till,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp *out_endtime);
void
kdc_get_ticket_renewtime(kdc_realm_t *realm, krb5_kdc_req *request,
krb5_enc_tkt_part *tgt, krb5_db_entry *client,
krb5_db_entry *server, krb5_flags *tktflags,
krb5_ticket_times *times);
void
log_as_req(krb5_context context,
const struct sockaddr *local_addr,
const struct sockaddr *remote_addr,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_db_entry *client, const char *cname,
krb5_db_entry *server, const char *sname,
krb5_timestamp authtime,
const char *status, krb5_error_code errcode, const char *emsg);
void
log_tgs_req(krb5_context ctx, const struct sockaddr *from,
krb5_kdc_req *request, krb5_kdc_rep *reply,
krb5_principal cprinc, krb5_principal sprinc,
krb5_principal altcprinc,
krb5_timestamp authtime,
unsigned int c_flags,
const char *status, krb5_error_code errcode, const char *emsg);
void
log_tgs_badtrans(krb5_context ctx, krb5_principal cprinc,
krb5_principal sprinc, krb5_data *trcont,
krb5_error_code errcode);
void
log_tgs_alt_tgt(krb5_context context, krb5_principal p);
krb5_boolean
is_client_db_alias(krb5_context context, const krb5_db_entry *entry,
krb5_const_principal princ);
enum krb5_fast_kdc_flags {
KRB5_FAST_REPLY_KEY_USED = 0x1,
KRB5_FAST_REPLY_KEY_REPLACED = 0x02
};
krb5_error_code
kdc_find_fast (krb5_kdc_req **requestptr, krb5_data *checksummed_data,
krb5_keyblock *tgs_subkey, krb5_keyblock *tgs_session,
struct kdc_request_state *state, krb5_data **inner_body_out);
krb5_error_code
kdc_fast_response_handle_padata (struct kdc_request_state *state,
krb5_kdc_req *request,
krb5_kdc_rep *rep,
krb5_enctype enctype);
krb5_error_code
kdc_fast_handle_error (krb5_context context,
struct kdc_request_state *state,
krb5_kdc_req *request,
krb5_pa_data **in_padata, krb5_error *err,
krb5_data **fast_edata_out);
krb5_error_code kdc_fast_handle_reply_key(struct kdc_request_state *state,
krb5_keyblock *existing_key,
krb5_keyblock **out_key);
krb5_boolean
kdc_fast_hide_client(struct kdc_request_state *state);
krb5_error_code
kdc_handle_protected_negotiation( krb5_context context,
krb5_data *req_pkt, krb5_kdc_req *request,
const krb5_keyblock *reply_key,
krb5_pa_data ***out_enc_padata);
krb5_error_code
kdc_fast_read_cookie(krb5_context context, struct kdc_request_state *state,
krb5_kdc_req *req, krb5_db_entry *local_tgt,
krb5_keyblock *local_tgt_key);
krb5_boolean kdc_fast_search_cookie(struct kdc_request_state *state,
krb5_preauthtype pa_type, krb5_data *out);
krb5_error_code kdc_fast_set_cookie(struct kdc_request_state *state,
krb5_preauthtype pa_type,
const krb5_data *data);
krb5_error_code
kdc_fast_make_cookie(krb5_context context, struct kdc_request_state *state,
krb5_db_entry *local_tgt, krb5_keyblock *local_tgt_key,
krb5_const_principal client_princ,
krb5_pa_data **cookie_out);
krb5_error_code
kdc_add_pa_pac_options(krb5_context context, krb5_kdc_req *request,
krb5_pa_data ***out_enc_padata);
krb5_error_code
kdc_get_pa_pac_options(krb5_context context, krb5_pa_data **in_padata,
krb5_pa_pac_options **pac_options_out);
krb5_error_code
kdc_get_pa_pac_rbcd(krb5_context context, krb5_pa_data **in_padata,
krb5_boolean *supported);
struct krb5_kdcpreauth_rock_st {
krb5_kdc_req *request;
krb5_data *inner_body;
krb5_db_entry *client;
krb5_db_entry *local_tgt;
krb5_keyblock *local_tgt_key;
krb5_key_data *client_key;
krb5_keyblock *client_keyblock;
struct kdc_request_state *rstate;
verto_ctx *vctx;
krb5_data ***auth_indicators;
krb5_boolean send_freshness_token;
krb5_boolean replaced_reply_key;
};
#define isflagset(flagfield, flag) (flagfield & (flag))
#define setflag(flagfield, flag) (flagfield |= (flag))
#define clear(flagfield, flag) (flagfield &= ~(flag))
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#endif
#define ts_min(a, b) (ts_after(a, b) ? (b) : (a))
#define ADDRTYPE2FAMILY(X) \
((X) == ADDRTYPE_INET6 ? AF_INET6 : (X) == ADDRTYPE_INET ? AF_INET : -1)
#define KRB5KDC_ERR_KEY_TOO_WEAK KRB5KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED
#define NON_TGT_OPTION (KDC_OPT_FORWARDED | KDC_OPT_PROXY | KDC_OPT_RENEW | \
KDC_OPT_VALIDATE)
#define NO_REFERRAL_OPTION (NON_TGT_OPTION | KDC_OPT_ENC_TKT_IN_SKEY)
#define AS_INVALID_OPTIONS (NO_REFERRAL_OPTION | KDC_OPT_CNAME_IN_ADDL_TKT)
#define OPTS_COMMON_FLAGS_MASK \
(KDC_OPT_FORWARDABLE | KDC_OPT_FORWARDED | \
KDC_OPT_PROXIABLE | KDC_OPT_PROXY | \
KDC_OPT_ALLOW_POSTDATE | KDC_OPT_POSTDATED | \
KDC_OPT_REQUEST_ANONYMOUS)
#define OPTS2FLAGS(x) (x & OPTS_COMMON_FLAGS_MASK)
#define TGS_COPIED_FLAGS_MASK \
(TKT_FLG_FORWARDED | TKT_FLG_PROXY | \
TKT_FLG_PRE_AUTH | TKT_FLG_HW_AUTH | \
TKT_FLG_ANONYMOUS)
#define COPY_TKT_FLAGS(x) (x & TGS_COPIED_FLAGS_MASK)
int check_anon(kdc_realm_t *realm, krb5_principal client,
krb5_principal server);
int errcode_to_protocol(krb5_error_code code);
char *data2string(krb5_data *d);
static inline krb5_kvno
current_kvno(krb5_db_entry *entry)
{
return (entry->n_key_data == 0) ? 0 : entry->key_data[0].key_data_kvno;
}
struct pac_s4u_delegation_info {
char *proxy_target;
uint32_t transited_services_length;
char **transited_services;
};
krb5_error_code
ndr_dec_delegation_info(krb5_data *data,
struct pac_s4u_delegation_info **res);
krb5_error_code
ndr_enc_delegation_info(struct pac_s4u_delegation_info *in,
krb5_data *out);
void ndr_free_delegation_info(struct pac_s4u_delegation_info *in);
#endif