xbot/myirc/include/sasl_mechanism.hpp
2025-01-30 16:39:23 -08:00

111 lines
2.2 KiB
C++

#pragma once
#include "ref.hpp"
#include <boost/signals2.hpp>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <variant>
class SaslMechanism
{
public:
struct NoReply {};
struct Failure {};
using StepResult = std::variant<std::string, NoReply, Failure>;
virtual ~SaslMechanism() {}
virtual auto mechanism_name() const -> std::string = 0;
virtual auto step(std::string_view msg) -> StepResult = 0;
virtual auto is_complete() const -> bool = 0;
};
class SaslPlain final : public SaslMechanism
{
std::string authcid_;
std::string authzid_;
std::string password_;
bool complete_;
public:
SaslPlain(std::string authcid, std::string authzid, std::string password)
: authcid_{std::move(authcid)}
, authzid_{std::move(authzid)}
, password_{std::move(password)}
, complete_{false}
{}
auto mechanism_name() const -> std::string override
{
return "PLAIN";
}
auto step(std::string_view msg) -> StepResult override;
auto is_complete() const -> bool override
{
return complete_;
}
};
class SaslExternal final : public SaslMechanism
{
std::string authzid_;
bool complete_;
public:
SaslExternal(std::string authzid)
: authzid_{std::move(authzid)}
, complete_{false}
{}
auto mechanism_name() const -> std::string override
{
return "EXTERNAL";
}
auto step(std::string_view msg) -> StepResult override;
auto is_complete() const -> bool override
{
return complete_;
}
};
class SaslEcdsa final : public SaslMechanism
{
std::string message1_;
Ref<EVP_PKEY> key_;
int stage_;
public:
SaslEcdsa(std::string authcid, std::string authzid, Ref<EVP_PKEY> key)
: message1_{std::move(authcid)}
, key_{std::move(key)}
, stage_{0}
{
if (not authzid.empty()) {
message1_.push_back(0);
message1_.append(authzid);
}
}
auto mechanism_name() const -> std::string override
{
return "ECDSA-NIST256P-CHALLENGE";
}
auto step(std::string_view msg) -> StepResult override;
auto is_complete() const -> bool override
{
return stage_ == 2;;
}
};