#include #include #include #include #include #include static krb5_error_code KRB5_CALLCONV windc_init(krb5_context context, void **ctx) { krb5_warnx(context, "windc init"); *ctx = NULL; return 0; } static void KRB5_CALLCONV windc_fini(void *ctx) { } static krb5_error_code KRB5_CALLCONV pac_generate(void *ctx, krb5_context context, struct hdb_entry_ex *client, struct hdb_entry_ex *server, const krb5_keyblock *pk_replykey, uint64_t pac_attributes, krb5_pac *pac) { krb5_error_code ret; krb5_data data; if ((pac_attributes & (KRB5_PAC_WAS_REQUESTED | KRB5_PAC_WAS_GIVEN_IMPLICITLY)) == 0) { *pac = NULL; return 0; } krb5_warnx(context, "pac generate"); data.data = "\x00\x01"; data.length = 2; ret = krb5_pac_init(context, pac); if (ret) return ret; ret = krb5_pac_add_buffer(context, *pac, 1, &data); if (ret) return ret; return 0; } static krb5_error_code KRB5_CALLCONV pac_verify(void *ctx, krb5_context context, const krb5_principal new_ticket_client, const krb5_principal delegation_proxy, struct hdb_entry_ex * client, struct hdb_entry_ex * server, struct hdb_entry_ex * krbtgt, krb5_pac *pac) { krb5_error_code ret; krb5_data data; krb5_cksumtype cstype; uint16_t rodc_id; krb5_enctype etype; Key *key; krb5_warnx(context, "pac_verify"); ret = krb5_pac_get_buffer(context, *pac, 1, &data); if (ret) return ret; krb5_data_free(&data); ret = krb5_pac_get_kdc_checksum_info(context, *pac, &cstype, &rodc_id); if (ret) return ret; if (rodc_id == 0 || rodc_id != krbtgt->entry.kvno >> 16) { krb5_warnx(context, "Wrong RODCIdentifier"); return EINVAL; } ret = krb5_cksumtype_to_enctype(context, cstype, &etype); if (ret) return ret; ret = hdb_enctype2key(context, &krbtgt->entry, NULL, etype, &key); if (ret) return ret; return krb5_pac_verify(context, *pac, 0, NULL, NULL, &key->key); } static void logit(const char *what, astgs_request_t r) { krb5_warnx(r->context, "%s: client %s server %s", what, r->cname ? r->cname : "", r->sname ? r->sname : ""); } static krb5_error_code KRB5_CALLCONV client_access(void *ctx, astgs_request_t r) { logit("client_access", r); return 0; } static krb5_error_code KRB5_CALLCONV finalize_reply(void *ctx, astgs_request_t r) { logit("finalize_reply", r); return 0; } static krb5plugin_windc_ftable windc = { KRB5_WINDC_PLUGING_MINOR, windc_init, windc_fini, pac_generate, pac_verify, client_access, finalize_reply }; static const krb5plugin_windc_ftable *const windc_plugins[] = { &windc }; krb5_error_code KRB5_CALLCONV windc_plugin_load(krb5_context context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, const krb5plugin_windc_ftable *const **plugins); static uintptr_t KRB5_CALLCONV windc_get_instance(const char *libname) { if (strcmp(libname, "hdb") == 0) return hdb_get_instance(libname); else if (strcmp(libname, "krb5") == 0) return krb5_get_instance(libname); return 0; } krb5_error_code KRB5_CALLCONV windc_plugin_load(krb5_context context, krb5_get_instance_func_t *get_instance, size_t *num_plugins, const krb5plugin_windc_ftable *const **plugins) { *get_instance = windc_get_instance; *num_plugins = sizeof(windc_plugins) / sizeof(windc_plugins[0]); *plugins = windc_plugins; return 0; }