// 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_);
  }
}
Example #2
0
File: sss_krb5.c Project: 3van/sssd
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
}
Example #3
0
File: kvno.c Project: OPSF/uClinux
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);
}