// Get session key from ccache or service ticket. void DecryptionManager::PacketHandler::readServiceSessionKey( krb5_ticket* ticket) { Krb5CCache *ccache = decryptionManager_->getCCache(); if (ccache) { Krb5Credentials creds = ccache->retrieveCred(ticket->server); krb5_copy_keyblock(ctx_->get(), &creds.get().keyblock, &sessionKey_); } else { krb5_error_code code = krb5_server_decrypt_ticket_keytab( ctx_->get(), decryptionManager_->getServerKeytab()->get(), ticket); if (code) { onError("Cannot decrypt service ticket using the given server keytab"); return; } krb5_copy_keyblock(ctx_->get(), ticket->enc_part2->session, &sessionKey_); } }
krb5_error_code sss_extract_pac(krb5_context ctx, krb5_ccache ccache, krb5_principal server_principal, krb5_principal client_principal, krb5_keytab keytab, krb5_authdata ***_pac_authdata) { #ifdef HAVE_PAC_RESPONDER krb5_error_code kerr; krb5_creds mcred; krb5_creds cred; krb5_authdata **pac_authdata = NULL; krb5_pac pac = NULL; int ret; krb5_ticket *ticket = NULL; krb5_keytab_entry entry; memset(&entry, 0, sizeof(entry)); memset(&mcred, 0, sizeof(mcred)); memset(&cred, 0, sizeof(mcred)); mcred.server = server_principal; mcred.client = client_principal; kerr = krb5_cc_retrieve_cred(ctx, ccache, 0, &mcred, &cred); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_cc_retrieve_cred failed.\n"); goto done; } kerr = krb5_decode_ticket(&cred.ticket, &ticket); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_decode_ticket failed.\n"); goto done; } kerr = krb5_server_decrypt_ticket_keytab(ctx, keytab, ticket); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_server_decrypt_ticket_keytab failed.\n"); goto done; } kerr = sss_krb5_find_authdata(ctx, ticket->enc_part2->authorization_data, NULL, KRB5_AUTHDATA_WIN2K_PAC, &pac_authdata); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_find_authdata failed.\n"); goto done; } if (pac_authdata == NULL || pac_authdata[0] == NULL) { DEBUG(SSSDBG_OP_FAILURE, "No PAC authdata available.\n"); kerr = ENOENT; goto done; } if (pac_authdata[1] != NULL) { DEBUG(SSSDBG_OP_FAILURE, "More than one PAC autdata found.\n"); kerr = EINVAL; goto done; } kerr = krb5_pac_parse(ctx, pac_authdata[0]->contents, pac_authdata[0]->length, &pac); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_pac_parse failed.\n"); goto done; } kerr = krb5_kt_get_entry(ctx, keytab, ticket->server, ticket->enc_part.kvno, ticket->enc_part.enctype, &entry); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_kt_get_entry failed.\n"); goto done; } kerr = krb5_pac_verify(ctx, pac, 0, NULL, &entry.key, NULL); if (kerr != 0) { DEBUG(SSSDBG_OP_FAILURE, "krb5_pac_verify failed.\n"); goto done; } ret = unsetenv("_SSS_LOOPS"); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Failed to unset _SSS_LOOPS, " "sss_pac_make_request will most certainly fail.\n"); } *_pac_authdata = pac_authdata; kerr = 0; done: if (kerr != 0) { krb5_free_authdata(ctx, pac_authdata); } if (entry.magic != 0) { krb5_free_keytab_entry_contents(ctx, &entry); } krb5_pac_free(ctx, pac); if (ticket != NULL) { krb5_free_ticket(ctx, ticket); } krb5_free_cred_contents(ctx, &cred); return kerr; #else return ENOTSUP; #endif }
static void do_v5_kvno (int count, char *names[], char * ccachestr, char *etypestr, char *keytab_name, char *sname, int canon, int unknown) { krb5_error_code ret; int i, errors; krb5_enctype etype; krb5_ccache ccache; krb5_principal me; krb5_creds in_creds, *out_creds; krb5_ticket *ticket; char *princ; krb5_keytab keytab = NULL; ret = krb5_init_context(&context); if (ret) { com_err(prog, ret, "while initializing krb5 library"); exit(1); } if (etypestr) { ret = krb5_string_to_enctype(etypestr, &etype); if (ret) { com_err(prog, ret, "while converting etype"); exit(1); } } else { etype = 0; } if (ccachestr) ret = krb5_cc_resolve(context, ccachestr, &ccache); else ret = krb5_cc_default(context, &ccache); if (ret) { com_err(prog, ret, "while opening ccache"); exit(1); } if (keytab_name) { ret = krb5_kt_resolve(context, keytab_name, &keytab); if (ret) { com_err(prog, ret, "resolving keytab %s", keytab_name); exit(1); } } ret = krb5_cc_get_principal(context, ccache, &me); if (ret) { com_err(prog, ret, "while getting client principal name"); exit(1); } errors = 0; for (i = 0; i < count; i++) { memset(&in_creds, 0, sizeof(in_creds)); in_creds.client = me; if (sname != NULL) { ret = krb5_sname_to_principal(context, names[i], sname, KRB5_NT_SRV_HST, &in_creds.server); } else { ret = krb5_parse_name(context, names[i], &in_creds.server); } if (ret) { if (!quiet) com_err(prog, ret, "while parsing principal name %s", names[i]); errors++; continue; } if (unknown == 1) { krb5_princ_type(context, in_creds.server) = KRB5_NT_UNKNOWN; } ret = krb5_unparse_name(context, in_creds.server, &princ); if (ret) { com_err(prog, ret, "while formatting parsed principal name for '%s'", names[i]); errors++; continue; } in_creds.keyblock.enctype = etype; ret = krb5_get_credentials(context, canon ? KRB5_GC_CANONICALIZE : 0, ccache, &in_creds, &out_creds); krb5_free_principal(context, in_creds.server); if (ret) { com_err(prog, ret, "while getting credentials for %s", princ); krb5_free_unparsed_name(context, princ); errors++; continue; } /* we need a native ticket */ ret = krb5_decode_ticket(&out_creds->ticket, &ticket); if (ret) { com_err(prog, ret, "while decoding ticket for %s", princ); krb5_free_creds(context, out_creds); krb5_free_unparsed_name(context, princ); errors++; continue; } if (keytab) { ret = krb5_server_decrypt_ticket_keytab(context, keytab, ticket); if (ret) { if (!quiet) printf("%s: kvno = %d, keytab entry invalid", princ, ticket->enc_part.kvno); com_err(prog, ret, "while decrypting ticket for %s", princ); krb5_free_ticket(context, ticket); krb5_free_creds(context, out_creds); krb5_free_unparsed_name(context, princ); errors++; continue; } if (!quiet) printf("%s: kvno = %d, keytab entry valid\n", princ, ticket->enc_part.kvno); } else { if (!quiet) printf("%s: kvno = %d\n", princ, ticket->enc_part.kvno); } krb5_free_creds(context, out_creds); krb5_free_unparsed_name(context, princ); } if (keytab) krb5_kt_close(context, keytab); krb5_free_principal(context, me); krb5_cc_close(context, ccache); krb5_free_context(context); if (errors) exit(1); exit(0); }