90 lines
1.8 KiB
C++
90 lines
1.8 KiB
C++
|
#pragma once
|
||
|
|
||
|
#include <memory>
|
||
|
#include <optional>
|
||
|
#include <string>
|
||
|
#include <string_view>
|
||
|
|
||
|
#include "event.hpp"
|
||
|
|
||
|
struct Connection;
|
||
|
|
||
|
class SaslMechanism
|
||
|
{
|
||
|
public:
|
||
|
virtual ~SaslMechanism() {}
|
||
|
|
||
|
virtual auto mechanism_name() const -> std::string = 0;
|
||
|
virtual auto step(std::string_view msg) -> std::optional<std::string> = 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 username, std::string password)
|
||
|
: authcid_{std::move(username)}
|
||
|
, password_{std::move(password)}
|
||
|
, complete_{false}
|
||
|
{}
|
||
|
|
||
|
auto mechanism_name() const -> std::string override
|
||
|
{
|
||
|
return "PLAIN";
|
||
|
}
|
||
|
|
||
|
auto step(std::string_view msg) -> std::optional<std::string> override {
|
||
|
if (complete_) {
|
||
|
return {};
|
||
|
} else {
|
||
|
std::string reply;
|
||
|
|
||
|
reply += authzid_;
|
||
|
reply += '\0';
|
||
|
reply += authcid_;
|
||
|
reply += '\0';
|
||
|
reply += password_;
|
||
|
|
||
|
complete_ = true;
|
||
|
|
||
|
return {std::move(reply)};
|
||
|
}
|
||
|
}
|
||
|
|
||
|
auto is_complete() const -> bool override
|
||
|
{
|
||
|
return complete_;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct SaslComplete : Event
|
||
|
{
|
||
|
bool success;
|
||
|
};
|
||
|
|
||
|
struct SaslMessage : Event
|
||
|
{
|
||
|
SaslMessage(std::string message) : message{std::move(message)} {}
|
||
|
std::string message;
|
||
|
};
|
||
|
|
||
|
class SaslThread
|
||
|
{
|
||
|
Connection& connection_;
|
||
|
std::string buffer_;
|
||
|
|
||
|
const std::size_t MAX_BUFFER = 1024;
|
||
|
|
||
|
public:
|
||
|
SaslThread(Connection& connection) : connection_{connection} {}
|
||
|
|
||
|
static auto start(Connection& connection) -> std::shared_ptr<SaslThread>;
|
||
|
|
||
|
auto on_authenticate(std::string_view) -> void;
|
||
|
};
|