diff options
Diffstat (limited to 'src/identd')
-rw-r--r-- | src/identd/identd_server.hpp | 39 | ||||
-rw-r--r-- | src/identd/identd_socket.cpp | 63 | ||||
-rw-r--r-- | src/identd/identd_socket.hpp | 36 |
3 files changed, 138 insertions, 0 deletions
diff --git a/src/identd/identd_server.hpp b/src/identd/identd_server.hpp new file mode 100644 index 0000000..b1c8ec8 --- /dev/null +++ b/src/identd/identd_server.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include <network/tcp_server_socket.hpp> +#include <identd/identd_socket.hpp> +#include <algorithm> +#include <unistd.h> + +class BiboumiComponent; + +class IdentdServer: public TcpSocketServer<IdentdSocket> +{ + public: + IdentdServer(const BiboumiComponent& biboumi_component, std::shared_ptr<Poller>& poller, const uint16_t port): + TcpSocketServer<IdentdSocket>(poller, port), + biboumi_component(biboumi_component) + {} + + const BiboumiComponent& get_biboumi_component() const + { + return this->biboumi_component; + } + void shutdown() + { + if (this->poller->is_managing_socket(this->socket)) + this->poller->remove_socket_handler(this->socket); + ::close(this->socket); + } + void clean() + { + this->sockets.erase(std::remove_if(this->sockets.begin(), this->sockets.end(), + [](const std::unique_ptr<IdentdSocket>& socket) + { + return socket->get_socket() == -1; + }), + this->sockets.end()); + } + private: + const BiboumiComponent& biboumi_component; +}; diff --git a/src/identd/identd_socket.cpp b/src/identd/identd_socket.cpp new file mode 100644 index 0000000..b85257c --- /dev/null +++ b/src/identd/identd_socket.cpp @@ -0,0 +1,63 @@ +#include <identd/identd_socket.hpp> +#include <identd/identd_server.hpp> +#include <xmpp/biboumi_component.hpp> +#include <sstream> +#include <iomanip> + +#include <utils/sha1.hpp> + +#include <logger/logger.hpp> + +IdentdSocket::IdentdSocket(std::shared_ptr<Poller>& poller, const socket_t socket, TcpSocketServer<IdentdSocket>& server): + TCPSocketHandler(poller), + server(dynamic_cast<IdentdServer&>(server)) +{ + this->socket = socket; +} + +void IdentdSocket::parse_in_buffer(const std::size_t) +{ + while (true) + { + const auto line_end = this->in_buf.find('\n'); + if (line_end == std::string::npos) + break; + std::istringstream line(this->in_buf.substr(0, line_end)); + this->consume_in_buffer(line_end + 1); + + uint16_t local_port; + uint16_t remote_port; + char sep; + line >> local_port >> sep >> remote_port; + const auto& xmpp = this->server.get_biboumi_component(); + auto response = this->generate_answer(xmpp, local_port, remote_port); + + this->send_data(std::move(response)); + } +} + +static std::string hash_jid(const std::string& jid) +{ + return sha1(jid); +} + +std::string IdentdSocket::generate_answer(const BiboumiComponent& biboumi, uint16_t local, uint16_t remote) +{ + for (const Bridge* bridge: biboumi.get_bridges()) + { + for (const auto& pair: bridge->get_irc_clients()) + { + if (pair.second->match_port_pairt(local, remote)) + { + std::ostringstream os; + os << local << " , " << remote << " : USERID : OTHER : " << hash_jid(bridge->get_bare_jid()); + log_debug("Identd, sending: ", os.str()); + return os.str(); + } + } + } + std::ostringstream os; + os << local << " , " << remote << " ERROR : NO-USER"; + log_debug("Identd, sending: ", os.str()); + return os.str(); +} diff --git a/src/identd/identd_socket.hpp b/src/identd/identd_socket.hpp new file mode 100644 index 0000000..a386d80 --- /dev/null +++ b/src/identd/identd_socket.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include <network/socket_handler.hpp> + +#include <network/tcp_socket_handler.hpp> + +#include <logger/logger.hpp> +#include <xmpp/biboumi_component.hpp> + +class XmppComponent; +class IdentdSocket; +class IdentdServer; +template <typename T> +class TcpSocketServer; + +class IdentdSocket: public TCPSocketHandler +{ + public: + IdentdSocket(std::shared_ptr<Poller>& poller, const socket_t socket, TcpSocketServer<IdentdSocket>& server); + ~IdentdSocket() = default; + std::string generate_answer(const BiboumiComponent& biboumi, uint16_t local, uint16_t remote); + + void parse_in_buffer(const std::size_t size) override final; + + bool is_connected() const override final + { + return true; + } + bool is_connecting() const override final + { + return false; + } + + private: + IdentdServer& server; +}; |