Commit 39b63ff5 authored by jan.koester's avatar jan.koester
Browse files

test

parent f845c0a6
Loading
Loading
Loading
Loading
Loading
+6 −3
Changes for plugin/ad/ad.cpp: 6 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -1247,7 +1247,7 @@ void ActiveDirectory::RequestEvent(netplus::con &curcon, const int, ULONG_PTR) {
            if (!responses.empty()) {
                fenrirds::crypto::Bytes resp(responses.begin(), responses.end());
                auto wrapped = gss::wrap(session->gssKey, session->gssEtype, true, session->sendSeq++, resp,
                                         session->ssf == 2);
                                         session->ssf == 2, session->gssAccSubkey);
                uint32_t wl = uint32_t(wrapped.size());
                curcon.SendData.push_back(char(wl >> 24));
                curcon.SendData.push_back(char(wl >> 16));
@@ -1529,6 +1529,7 @@ std::vector<uint8_t> ActiveDirectory::handleBindRequest(const uint8_t *content,
            session.gssState = LdapSession::GssSentApRep;
            session.sendSeq = res.acceptorSeq;
            session.recvSeq = res.initiatorSeq;
            session.gssAccSubkey = res.acceptorSubkey;

            std::vector<uint8_t> krb5reply;
            if (!res.apRep.empty()) {
@@ -1544,7 +1545,8 @@ std::vector<uint8_t> ActiveDirectory::handleBindRequest(const uint8_t *content,
            if (spnego) {
                std::vector<uint8_t> krb5oid = gss::firstMechOid(session.gssMechTypes);
                std::vector<uint8_t> mic = gss::getMic(session.gssKey, session.gssEtype,
                                                       true, session.sendSeq++, session.gssMechTypes);
                                                       true, session.sendSeq++, session.gssMechTypes,
                                                       session.gssAccSubkey);
                creds = gss::buildSpnegoResp(gss::ACCEPT_COMPLETED, &krb5oid, krb5reply, mic);
                /* GSS-SPNEGO has no RFC 4752 layer negotiation: the bind is
                 * done, and the client signs or seals the following PDUs as
@@ -1568,7 +1570,8 @@ std::vector<uint8_t> ActiveDirectory::handleBindRequest(const uint8_t *content,
             * with a max receive buffer. Wrapped (sign) with the context key. */
            uint32_t maxBuf = 0x000FFFFF;
            std::vector<uint8_t> sec = {0x07, uint8_t(maxBuf >> 16), uint8_t(maxBuf >> 8), uint8_t(maxBuf)};
            auto tok = gss::wrap(session.gssKey, session.gssEtype, true, session.sendSeq++, sec);
            auto tok = gss::wrap(session.gssKey, session.gssEtype, true, session.sendSeq++, sec,
                                 false, session.gssAccSubkey);
            session.gssState = LdapSession::GssSentSecLayer;
            return bindResp(SASL_BIND_IN_PROGRESS, &tok);
        }
+1 −0
Changes for plugin/ad/ad.h: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ namespace fenrirds {
        int                  ssf = 0;
        uint64_t             sendSeq = 0;   /* acceptor -> client */
        uint64_t             recvSeq = 0;   /* client -> acceptor */
        bool                 gssAccSubkey = false;   /* context key = our AP-REP subkey */
    };

    /***************************************************************************
+21 −3
Changes for plugin/krb5/krb5.cpp: 21 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -3882,6 +3882,20 @@ bool Krb5KDC::gssAccept(const std::vector<uint8_t> &apReqData, GssAcceptResult &
    out.acceptorSeq = variant == 0 ? (Krb5Crypto::randomNonce() & 0x3fffffff) : 0;
    if (ap.ap_options & 0x20000000) {
        Krb5Service svc("", "", ap.ticket.sname.realm, svcKey);
        /* Like Windows and Heimdal acceptors, assert our own subkey for AES
         * contexts: it becomes the GSS context key (MIC, wrap, the SMB
         * session key); our tokens then carry the AcceptorSubkey flag. */
        Krb5SessionKey accKey;
        int accEtype = auth.has_subkey ? auth.subkey.enctype : et.session_key.enctype;
        bool useAccKey = variant == 0 &&
                         (accEtype == KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1 || accEtype == KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1);
        if (useAccKey) {
            accKey.enctype = static_cast<Krb5EncType>(accEtype);
            accKey.keydata = Krb5Crypto::randomBytes(accEtype == KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1 ? 32 : 16);
            out.sessionKey = accKey.keydata;
            out.sessionEtype = accEtype;
            out.acceptorSubkey = true;
        }
        if (variant == 3) {
            auto legacy = Asn1Der::encodePaEncTimestamp(auth.ctime, auth.cusec);
            Krb5ApRep ap_rep;
@@ -3892,13 +3906,14 @@ bool Krb5KDC::gssAccept(const std::vector<uint8_t> &apReqData, GssAcceptResult &
            ap_rep.enc_part = Krb5Crypto::encrypt(et.session_key.keydata, legacy, KRB5_KU_AP_REP_ENC_PART);
            out.apRep = ap_rep.serialize();
        } else {
            out.apRep = svc.buildApRep(auth, et.session_key, out.acceptorSeq);
            out.apRep = svc.buildApRep(auth, et.session_key, out.acceptorSeq,
                                       useAccKey ? &accKey : nullptr);
        }
    }
    out.gssFlags = auth.has_gss_cksum ? auth.gss_flags : 0;
    out.initiatorSeq = auth.seq_number;
    std::cerr << "[KDC] gssAccept " << out.clientPrincipal << " variant=" << "ABCD"[out.apRepVariant]
              << " subkey=" << auth.has_subkey
              << " subkey=" << auth.has_subkey << " accSubkey=" << out.acceptorSubkey
              << " flags=0x" << std::hex << out.gssFlags << " initSeq=0x" << out.initiatorSeq
              << " accSeq=0x" << out.acceptorSeq << std::dec << " mutual=" << !out.apRep.empty() << std::endl;
    return true;
@@ -4435,7 +4450,8 @@ bool Krb5Service::verifyApReq(const std::vector<uint8_t> &apReqData,

std::vector<uint8_t> Krb5Service::buildApRep(const Krb5Authenticator &auth,
                                               const Krb5SessionKey &sessionKey,
                                               uint32_t seqNumber) {
                                               uint32_t seqNumber,
                                               const Krb5SessionKey *subkey) {
    /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE {
     *   ctime [0] KerberosTime, cusec [1] Microseconds,
     *   subkey [2] EncryptionKey OPTIONAL, seq-number [3] UInt32 OPTIONAL }
@@ -4446,6 +4462,8 @@ std::vector<uint8_t> Krb5Service::buildApRep(const Krb5Authenticator &auth,
    std::vector<uint8_t> seq;
    Asn1Der::encodeContextTag(seq, 0, Asn1Der::encodeGeneralizedTime(auth.ctime));
    Asn1Der::encodeContextTag(seq, 1, Asn1Der::encodeUInteger(auth.cusec));
    if (subkey && !subkey->keydata.empty())
        Asn1Der::encodeContextTag(seq, 2, Asn1Der::encodeEncryptionKey(*subkey));
    Asn1Der::encodeContextTag(seq, 3, Asn1Der::encodeUInteger(seqNumber & 0x7fffffff));
    std::vector<uint8_t> repData;
    Asn1Der::encodeTLV(repData, 0x7B /* [APPLICATION 27] */, Asn1Der::encodeSequence(seq));
+2 −1
Changes for plugin/krb5/krb5.h: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -927,7 +927,8 @@ namespace fenrirds {
        /* Build an AP-REP response */
        std::vector<uint8_t> buildApRep(const Krb5Authenticator &auth,
                                         const Krb5SessionKey &sessionKey,
                                        uint32_t seqNumber = 0);
                                        uint32_t seqNumber = 0,
                                        const Krb5SessionKey *subkey = nullptr);

    private:
        Krb5Principal        _ServicePrincipal;
+2 −1
Changes for plugin/smb/smb.cpp: 2 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -753,7 +753,8 @@ SmbServer::Reply SmbServer::sessionSetup(Conn &c, const smb::Smb2Header &req,
    std::vector<uint8_t> outTok;
    if (spnego) {
        std::vector<uint8_t> oid = gss::firstMechOid(mechTypes);
        auto m = gss::getMic(res.sessionKey, res.sessionEtype, true, res.acceptorSeq, mechTypes);
        auto m = gss::getMic(res.sessionKey, res.sessionEtype, true, res.acceptorSeq, mechTypes,
                             res.acceptorSubkey);
        outTok = gss::buildSpnegoResp(gss::ACCEPT_COMPLETED, &oid, krb5reply, m);
    } else {
        outTok = krb5reply;
Loading