static void do_delegation (krb5_auth_context ac, krb5_ccache ccache, krb5_creds *cred, krb5_const_principal name, krb5_data *fwd_data, uint32_t *flags) { krb5_creds creds; KDCOptions fwd_flags; krb5_error_code kret; memset (&creds, 0, sizeof(creds)); krb5_data_zero (fwd_data); kret = krb5_cc_get_principal(_gsskrb5_context, ccache, &creds.client); if (kret) goto out; kret = krb5_build_principal(_gsskrb5_context, &creds.server, strlen(creds.client->realm), creds.client->realm, KRB5_TGS_NAME, creds.client->realm, NULL); if (kret) goto out; creds.times.endtime = 0; memset(&fwd_flags, 0, sizeof(fwd_flags)); fwd_flags.forwarded = 1; fwd_flags.forwardable = 1; if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/ name->name.name_string.len < 2) goto out; kret = krb5_get_forwarded_creds(_gsskrb5_context, ac, ccache, KDCOptions2int(fwd_flags), name->name.name_string.val[1], &creds, fwd_data); out: if (kret) *flags &= ~GSS_C_DELEG_FLAG; else *flags |= GSS_C_DELEG_FLAG; if (creds.client) krb5_free_principal(_gsskrb5_context, creds.client); if (creds.server) krb5_free_principal(_gsskrb5_context, creds.server); }
krb5_error_code KRB5_LIB_FUNCTION krb5_fwd_tgt_creds (krb5_context context, krb5_auth_context auth_context, const char *hostname, krb5_principal client, krb5_principal server, krb5_ccache ccache, int forwardable, krb5_data *out_data) { krb5_flags flags = 0; krb5_creds creds; krb5_error_code ret; krb5_const_realm client_realm; flags |= KDC_OPT_FORWARDED; if (forwardable) flags |= KDC_OPT_FORWARDABLE; if (hostname == NULL && krb5_principal_get_type(context, server) == KRB5_NT_SRV_HST) { const char *inst = krb5_principal_get_comp_string(context, server, 0); const char *host = krb5_principal_get_comp_string(context, server, 1); if (inst != NULL && strcmp(inst, "host") == 0 && host != NULL && krb5_principal_get_comp_string(context, server, 2) == NULL) hostname = host; } client_realm = krb5_principal_get_realm(context, client); memset (&creds, 0, sizeof(creds)); creds.client = client; ret = krb5_build_principal(context, &creds.server, strlen(client_realm), client_realm, KRB5_TGS_NAME, client_realm, NULL); if (ret) return ret; ret = krb5_get_forwarded_creds (context, auth_context, ccache, flags, hostname, &creds, out_data); return ret; }
int main(int argc, char **argv) { const char *hostname; krb5_context context; krb5_auth_context ac; krb5_error_code ret; krb5_creds cred; krb5_ccache id; krb5_data data; int optidx = 0; setprogname (argv[0]); if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx)) usage(1); if (help_flag) usage (0); if(version_flag){ print_version(NULL); exit(0); } argc -= optidx; argv += optidx; if (argc < 1) usage(1); hostname = argv[0]; memset(&cred, 0, sizeof(cred)); ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed: %d", ret); ret = krb5_cc_default(context, &id); if (ret) krb5_err(context, 1, ret, "krb5_cc_default failed: %d", ret); ret = krb5_auth_con_init(context, &ac); if (ret) krb5_err(context, 1, ret, "krb5_auth_con_init failed: %d", ret); krb5_auth_con_addflags(context, ac, KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED, NULL); ret = krb5_cc_get_principal(context, id, &cred.client); if (ret) krb5_err(context, 1, ret, "krb5_cc_get_principal"); ret = krb5_make_principal(context, &cred.server, krb5_principal_get_realm(context, cred.client), KRB5_TGS_NAME, krb5_principal_get_realm(context, cred.client), NULL); if (ret) krb5_err(context, 1, ret, "krb5_make_principal(server)"); ret = krb5_get_forwarded_creds (context, ac, id, KDC_OPT_FORWARDABLE, hostname, &cred, &data); if (ret) krb5_err (context, 1, ret, "krb5_get_forwarded_creds"); krb5_data_free(&data); krb5_free_context(context); return 0; }
static int proto (int sock, const char *hostname, const char *svc, char *message, size_t len) { krb5_auth_context auth_context; krb5_error_code status; krb5_principal server; krb5_data data; krb5_data data_send; krb5_ccache ccache; krb5_creds creds; krb5_kdc_flags flags; krb5_principal principal; status = krb5_auth_con_init (context, &auth_context); if (status) { krb5_warn (context, status, "krb5_auth_con_init"); return 1; } status = krb5_auth_con_setaddrs_from_fd (context, auth_context, &sock); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_auth_con_setaddr"); return 1; } status = krb5_sname_to_principal (context, hostname, svc, KRB5_NT_SRV_HST, &server); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_sname_to_principal"); return 1; } status = krb5_sendauth (context, &auth_context, &sock, KF_VERSION_1, NULL, server, AP_OPTS_MUTUAL_REQUIRED | AP_OPTS_USE_SUBKEY, NULL, NULL, NULL, NULL, NULL, NULL); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn(context, status, "krb5_sendauth"); return 1; } if (ccache_name == NULL) ccache_name = ""; data_send.data = (void *)remote_name; data_send.length = strlen(remote_name) + 1; status = krb5_write_priv_message(context, auth_context, &sock, &data_send); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_write_message"); return 1; } data_send.data = (void *)ccache_name; data_send.length = strlen(ccache_name)+1; status = krb5_write_priv_message(context, auth_context, &sock, &data_send); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_write_message"); return 1; } memset (&creds, 0, sizeof(creds)); status = krb5_cc_default (context, &ccache); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_cc_default"); return 1; } status = krb5_cc_get_principal (context, ccache, &principal); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_cc_get_principal"); return 1; } creds.client = principal; status = krb5_make_principal (context, &creds.server, principal->realm, KRB5_TGS_NAME, principal->realm, NULL); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_make_principal"); return 1; } creds.times.endtime = 0; flags.i = 0; flags.b.forwarded = 1; flags.b.forwardable = forwardable; status = krb5_get_forwarded_creds (context, auth_context, ccache, flags.i, hostname, &creds, &data); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_get_forwarded_creds"); return 1; } status = krb5_write_priv_message(context, auth_context, &sock, &data); if (status) { krb5_auth_con_free(context, auth_context); krb5_warn (context, status, "krb5_mk_priv"); return 1; } krb5_data_free (&data); status = krb5_read_priv_message(context, auth_context, &sock, &data); krb5_auth_con_free(context, auth_context); if (status) { krb5_warn (context, status, "krb5_mk_priv"); return 1; } if(data.length >= len) { krb5_warnx (context, "returned string is too long, truncating"); memcpy(message, data.data, len); message[len - 1] = '\0'; } else { memcpy(message, data.data, data.length); message[data.length] = '\0'; } krb5_data_free (&data); return(strcmp(message, "ok")); }
void kerberos5_forward(Authenticator *ap) { krb5_error_code ret; krb5_ccache ccache; krb5_creds creds; krb5_kdc_flags flags; krb5_data out_data; krb5_principal principal; ret = krb5_cc_default (context, &ccache); if (ret) { if (auth_debug_mode) printf ("KerberosV5: could not get default ccache: %s\r\n", krb5_get_err_text (context, ret)); return; } ret = krb5_cc_get_principal (context, ccache, &principal); if (ret) { if (auth_debug_mode) printf ("KerberosV5: could not get principal: %s\r\n", krb5_get_err_text (context, ret)); return; } creds.client = principal; ret = krb5_build_principal (context, &creds.server, strlen(principal->realm), principal->realm, "krbtgt", principal->realm, NULL); if (ret) { if (auth_debug_mode) printf ("KerberosV5: could not get principal: %s\r\n", krb5_get_err_text (context, ret)); return; } creds.times.endtime = 0; flags.i = 0; flags.b.forwarded = 1; if (forward_flags & OPTS_FORWARDABLE_CREDS) flags.b.forwardable = 1; ret = krb5_get_forwarded_creds (context, auth_context, ccache, flags.i, RemoteHostName, &creds, &out_data); if (ret) { if (auth_debug_mode) printf ("Kerberos V5: error gettting forwarded creds: %s\r\n", krb5_get_err_text (context, ret)); return; } if(!Data(ap, KRB_FORWARD, out_data.data, out_data.length)) { if (auth_debug_mode) printf("Not enough room for authentication data\r\n"); } else { if (auth_debug_mode) printf("Forwarded local Kerberos V5 credentials to server\r\n"); } }
static int krb5_forward_cred (krb5_auth_context auth_context, int s, const char *hostname, int forwardable) { krb5_error_code ret; krb5_ccache ccache; krb5_creds creds; krb5_kdc_flags flags; krb5_data out_data; krb5_principal principal; memset (&creds, 0, sizeof(creds)); ret = krb5_cc_default (context, &ccache); if (ret) { warnx ("could not forward creds: krb5_cc_default: %s", krb5_get_err_text (context, ret)); return 1; } ret = krb5_cc_get_principal (context, ccache, &principal); if (ret) { warnx ("could not forward creds: krb5_cc_get_principal: %s", krb5_get_err_text (context, ret)); return 1; } creds.client = principal; ret = krb5_make_principal(context, &creds.server, principal->realm, "krbtgt", principal->realm, NULL); if (ret) { warnx ("could not forward creds: krb5_make_principal: %s", krb5_get_err_text (context, ret)); return 1; } creds.times.endtime = 0; flags.i = 0; flags.b.forwarded = 1; flags.b.forwardable = forwardable; ret = krb5_get_forwarded_creds (context, auth_context, ccache, flags.i, hostname, &creds, &out_data); if (ret) { warnx ("could not forward creds: krb5_get_forwarded_creds: %s", krb5_get_err_text (context, ret)); return 1; } ret = krb5_write_message (context, (void *)&s, &out_data); krb5_data_free (&out_data); if (ret) warnx ("could not forward creds: krb5_write_message: %s", krb5_get_err_text (context, ret)); return 0; }