// EslesmeYonetici: tam el sıkışma (iki uç aynı kod + aynı anahtar), MITM nonce // oynaması kodları AYIRIR, sahte onay reddi, TTL temizliği, serialize round-trip. // Rastgele deterministik enjekte edilir (sayaçlı dolgu) — testler kararlı. #include #include "fiko/orkestra/eslesme.hpp" #include "fiko_test.hpp" using namespace fiko::orkestra; namespace { EslesmeYonetici::RastgeleFn sayacliRastgele(uint8_t tohum) { auto sayac = std::make_shared(tohum); return [sayac](uint8_t* p, size_t n) { for (size_t i = 0; i < n; ++i) p[i] = (*sayac)++; }; } } // namespace FIKO_TEST(eslesme_tam_el_sikisma) { EslesmeYonetici isteyen(sayacliRastgele(10)), dinleyen(sayacliRastgele(200)); const uint64_t A = 111, B = 222; // A ister, B dinler const std::string istek = isteyen.istekOlustur(A, "makine-a", B, 1000); uint64_t gelenId = 0; std::string ad, kodB; FIKO_KONTROL(dinleyen.istekAl(istek, B, 1001, gelenId, ad, kodB)); FIKO_KONTROL(gelenId == A && ad == "makine-a"); FIKO_KONTROL(kodB.size() == 6); std::string onay; FIKO_KONTROL(dinleyen.onayla(B, A, onay)); FIKO_KONTROL(dinleyen.esliMi(A)); uint64_t onayId = 0; std::string kodA; FIKO_KONTROL(isteyen.onayAl(onay, A, onayId, kodA)); FIKO_KONTROL(onayId == B); FIKO_KONTROL(kodA == kodB); // iki ekranda AYNI kod — kullanıcı doğrulaması FIKO_KONTROL(isteyen.esliMi(B)); // İki uç AYNI anahtarı türetti (kanonik sıra id-bağımsız). FIKO_KONTROL(isteyen.kayitBul(B)->anahtar == dinleyen.kayitBul(A)->anahtar); } FIKO_TEST(eslesme_mitm_kodlari_ayirir) { EslesmeYonetici isteyen(sayacliRastgele(10)), dinleyen(sayacliRastgele(200)); const uint64_t A = 111, B = 222; std::string istek = isteyen.istekOlustur(A, "makine-a", B, 1000); std::string kurcalanmis = istek; kurcalanmis[kurcalanmis.size() - 1] ^= 0x5A; // MITM son nonce baytını değiştirdi uint64_t id = 0; std::string ad, kodDinleyen, kodDinleyenTemiz; EslesmeYonetici temizDinleyen(sayacliRastgele(200)); // aynı tohum — tek fark nonce FIKO_KONTROL(temizDinleyen.istekAl(istek, B, 1001, id, ad, kodDinleyenTemiz)); FIKO_KONTROL(dinleyen.istekAl(kurcalanmis, B, 1001, id, ad, kodDinleyen)); FIKO_KONTROL(kodDinleyen != kodDinleyenTemiz); // kurcalama iki ekranda farklı kod üretir } FIKO_TEST(eslesme_sahte_onay_reddi) { EslesmeYonetici isteyen(sayacliRastgele(10)); uint64_t id = 0; std::string kod; // Hiç istek atmadan gelen "onay" → red (istek bizden çıkmadıysa sahtedir). EslesmeYonetici sahteci(sayacliRastgele(50)); const std::string sahteIstek = sahteci.istekOlustur(999, "sahte", 111, 1000); FIKO_KONTROL(!isteyen.onayAl(sahteIstek, 111, id, kod)); // Bozuk gövde + kendi kimliğiyle istek reddi. std::string ad; FIKO_KONTROL(!isteyen.istekAl("kisa", 111, 1000, id, ad, kod)); const std::string kendinden = sahteci.istekOlustur(111, "ben", 111, 1000); FIKO_KONTROL(!isteyen.istekAl(kendinden, 111, 1000, id, ad, kod)); } FIKO_TEST(eslesme_ttl_temizligi) { EslesmeYonetici dinleyen(sayacliRastgele(1)); EslesmeYonetici isteyen(sayacliRastgele(9)); const std::string istek = isteyen.istekOlustur(1, "a", 2, 1000); uint64_t id = 0; std::string ad, kod; FIKO_KONTROL(dinleyen.istekAl(istek, 2, 1000, id, ad, kod)); dinleyen.temizle(120'000, 60'000); // 2 dk geçti, TTL 1 dk → bekleyen düştü std::string onay; FIKO_KONTROL(!dinleyen.onayla(2, 1, onay)); // süresi geçen istek onaylanamaz } FIKO_TEST(eslesme_bekleyen_gelenler_panel) { EslesmeYonetici isteyen(sayacliRastgele(10)), dinleyen(sayacliRastgele(200)); const uint64_t A = 111, B = 222; const std::string istek = isteyen.istekOlustur(A, "makine-a", B, 1000); uint64_t id = 0; std::string ad, kod; FIKO_KONTROL(dinleyen.bekleyenGelenler().empty()); // istek gelmeden liste boş FIKO_KONTROL(dinleyen.istekAl(istek, B, 1001, id, ad, kod)); const auto liste = dinleyen.bekleyenGelenler(); FIKO_KONTROL(liste.size() == 1); FIKO_KONTROL(liste[0].nodeId == A && liste[0].ad == "makine-a"); FIKO_KONTROL(liste[0].kod == kod); // panel kartındaki kod istekAl'daki ile aynı // Onaylanınca bekleyen listeden düşer. std::string onay; FIKO_KONTROL(dinleyen.onayla(B, A, onay)); FIKO_KONTROL(dinleyen.bekleyenGelenler().empty()); // Giden (isteyen) tarafta bekleyen GELEN yoktur (yalnız dinleyende kart çıkar). FIKO_KONTROL(isteyen.bekleyenGelenler().empty()); } FIKO_TEST(eslesme_rol_kapisi) { EslesmeYonetici a(sayacliRastgele(10)), b(sayacliRastgele(200)); const std::string istek = a.istekOlustur(1, "a", 2, 1000); uint64_t id = 0; std::string ad, kod, onay; b.istekAl(istek, 2, 1001, id, ad, kod); b.onayla(2, 1, onay); // Eşli node varsayılan İzleyici (salt-okuma; komut reddi için güvenli). FIKO_KONTROL(b.rol(1) == Rol::Izleyici); FIKO_KONTROL(b.rol(999) == Rol::Izleyici); // eşsiz node da İzleyici (en kısıtlı) FIKO_KONTROL(b.rolAyarla(1, Rol::Operator)); FIKO_KONTROL(b.rol(1) == Rol::Operator); FIKO_KONTROL(!b.rolAyarla(999, Rol::Yonetici)); // eşli değil → false // Rol serialize'da korunur + eski/bozuk depo İzleyici'ye düşer (güvenli). EslesmeYonetici c(sayacliRastgele(0)); FIKO_KONTROL(c.yukle(b.serialize())); FIKO_KONTROL(c.rol(1) == Rol::Operator); } FIKO_TEST(eslesme_ttl_sonrasi_onay_reddi) { // TTL geçince isteyen tarafın bekleyeni de silinir → geç gelen onay reddedilir. EslesmeYonetici a(sayacliRastgele(10)), b(sayacliRastgele(200)); const std::string istek = a.istekOlustur(1, "a", 2, 1000); uint64_t id = 0; std::string ad, kod, onay; b.istekAl(istek, 2, 1001, id, ad, kod); b.onayla(2, 1, onay); a.temizle(200'000, 60'000); // isteyen tarafta bekleyen TTL doldu std::string kodA; FIKO_KONTROL(!a.onayAl(onay, 1, id, kodA)); // bekleyen yok → sahte sayılır, red FIKO_KONTROL(!a.esliMi(2)); // eşleşme kurulmadı } FIKO_TEST(eslesme_serialize_round_trip) { EslesmeYonetici a(sayacliRastgele(10)), b(sayacliRastgele(200)); const std::string istek = a.istekOlustur(1, "a", 2, 1000); uint64_t id = 0; std::string ad, kod, onay; FIKO_KONTROL(b.istekAl(istek, 2, 1001, id, ad, kod)); FIKO_KONTROL(b.onayla(2, 1, onay)); const std::string veri = b.serialize(); EslesmeYonetici c(sayacliRastgele(0)); FIKO_KONTROL(c.yukle(veri)); FIKO_KONTROL(c.esliMi(1) && c.kayitBul(1)->anahtar == b.kayitBul(1)->anahtar); FIKO_KONTROL(!c.yukle("bozuk")); // bozuk depo mevcut kayıtları EZMEZ FIKO_KONTROL(c.esliMi(1)); FIKO_KONTROL(c.kaldir(1) && !c.esliMi(1)); // eşleştirmeyi kaldır (sağ-tık menüsü) }