Commit b8437558 authored by jan.koester's avatar jan.koester
Browse files

test

parent 94d9007e
Loading
Loading
Loading
Loading
Loading
+40 −0
Changes for plugin/krb5/krb5.cpp: 40 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -2607,6 +2607,10 @@ Krb5KDC::Krb5KDC(AuthBackend &adminBackend,
    /* Create a TCP server socket for the KDC on the given port */
    netplus::tcp *ssock = new netplus::tcp(bindAddr.c_str(), port, maxconn, 0);
    _ServerSockets.push_back(ssock);

    /* UDP socket on the same port (Kerberos primary transport) */
    _Udp = new netplus::udp(bindAddr.c_str(), port, maxconn, -1);
    std::cerr << "KDC listening on " << bindAddr << ":" << port << " (tcp+udp)" << std::endl;
}

void Krb5KDC::init() {
@@ -2615,9 +2619,42 @@ void Krb5KDC::init() {
        s->setNonBlock();
        s->listen();
    }
    if (_Udp)
        _Udp->bind();
}

/* UDP responder: each datagram is a bare ASN.1 DER Kerberos message (no TCP
 * 4-byte length prefix). Process it and send the bare response back. */
void Krb5KDC::udpLoop() {
    while (_Running) {
        std::vector<std::vector<uint8_t>> dgrams;
        std::vector<sockaddr_storage> addrs;
        size_t n = 0;
        try {
            n = _Udp->recvBatchAddr(dgrams, addrs, 16);
        } catch (...) { continue; }
        for (size_t i = 0; i < n; ++i) {
            std::vector<uint8_t> response;
            try {
                response = handleStandardRequest(dgrams[i].data(), dgrams[i].size());
            } catch (const std::exception &e) {
                std::string errRealm = _Realms.empty() ? "UNKNOWN" : _Realms.begin()->first;
                response = buildStandardError(KRB_ERR_GENERIC, e.what(), errRealm, "krbtgt");
            }
            if (response.empty())
                continue;
            socklen_t sl = addrs[i].ss_family == AF_INET6 ? sizeof(sockaddr_in6) : sizeof(sockaddr_in);
            std::vector<std::pair<const uint8_t*, size_t>> out = {{response.data(), response.size()}};
            try { _Udp->sendBatch(out, &addrs[i], sl); } catch (...) {}
        }
    }
}

Krb5KDC::~Krb5KDC() {
    _Running = false;
    if (_UdpThread.joinable())
        _UdpThread.join();
    delete _Udp;
    delete static_cast<KdcEvent*>(_Event);
    for (auto *s : _ServerSockets)
        delete s;
@@ -2746,6 +2783,9 @@ bool Krb5KDC::getCrossRealmKey(const std::string &localRealm,
}

void Krb5KDC::runKdc(ULONG_PTR args) {
    _Running = true;
    if (_Udp)
        _UdpThread = std::thread([this]() { udpLoop(); });
    auto *ev = new KdcEvent(_ServerSockets, this);
    _Event = ev;
    ev->runEventloop(args);
+8 −0
Changes for plugin/krb5/krb5.h: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <ctime>
#include <mutex>
#include <memory>
#include <thread>

#include <uuidp.h>
#include <netplus/socket.h>
@@ -812,6 +813,13 @@ namespace fenrirds {

        std::vector<netplus::socket*>     _ServerSockets;
        void                             *_Event;

        /* Kerberos primary transport is UDP 88 (no 4-byte length prefix);
         * Windows sends AS-REQ over UDP first. Served in its own thread. */
        netplus::udp                     *_Udp = nullptr;
        std::thread                       _UdpThread;
        bool                              _Running = false;
        void                              udpLoop();
    };

    /***************************************************************************