Conditionally compile the SASL code only with botan and database

This commit is contained in:
louiz’
2020-07-29 00:37:24 +02:00
parent e4550d324f
commit 189015afb4
6 changed files with 51 additions and 37 deletions
+3
View File
@@ -14,3 +14,6 @@
#cmakedefine HAS_PUT_TIME #cmakedefine HAS_PUT_TIME
#cmakedefine DEBUG_SQL_QUERIES #cmakedefine DEBUG_SQL_QUERIES
#if defined(USE_DATABASE) && defined(BOTAN_FOUND)
# define WITH_SASL
#endif
+13 -12
View File
@@ -83,11 +83,11 @@ static const std::unordered_map<std::string,
{"KICK", {&IrcClient::on_kick, {3, 0}}}, {"KICK", {&IrcClient::on_kick, {3, 0}}},
{"INVITE", {&IrcClient::on_invite, {2, 0}}}, {"INVITE", {&IrcClient::on_invite, {2, 0}}},
{"CAP", {&IrcClient::on_cap, {3, 0}}}, {"CAP", {&IrcClient::on_cap, {3, 0}}},
#ifdef WITH_SASL
{"AUTHENTICATE", {&IrcClient::on_authenticate, {1, 0}}}, {"AUTHENTICATE", {&IrcClient::on_authenticate, {1, 0}}},
{"903", {&IrcClient::on_sasl_success, {0, 0}}}, {"903", {&IrcClient::on_sasl_success, {0, 0}}},
{"900", {&IrcClient::on_sasl_login, {3, 0}}}, {"900", {&IrcClient::on_sasl_login, {3, 0}}},
#endif
{"401", {&IrcClient::on_generic_error, {2, 0}}}, {"401", {&IrcClient::on_generic_error, {2, 0}}},
{"402", {&IrcClient::on_generic_error, {2, 0}}}, {"402", {&IrcClient::on_generic_error, {2, 0}}},
{"403", {&IrcClient::on_generic_error, {2, 0}}}, {"403", {&IrcClient::on_generic_error, {2, 0}}},
@@ -286,12 +286,14 @@ void IrcClient::on_connected()
auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
this->get_hostname()); this->get_hostname());
const auto& sasl_password = options.col<Database::SaslPassword>();
const auto& server_password = options.col<Database::Pass>(); const auto& server_password = options.col<Database::Pass>();
if (!server_password.empty()) if (!server_password.empty())
this->send_pass_command(options.col<Database::Pass>()); this->send_pass_command(options.col<Database::Pass>());
#endif
#ifdef WITH_SASL
const auto& sasl_password = options.col<Database::SaslPassword>();
if (!sasl_password.empty()) if (!sasl_password.empty())
{ {
this->capabilities["sasl"] = { this->capabilities["sasl"] = {
@@ -325,10 +327,8 @@ void IrcClient::on_connected()
this->send_user_command(username, realname); this->send_user_command(username, realname);
} }
else else
this->send_user_command(this->username, this->realname);
#else
this->send_user_command(this->username, this->realname);
#endif #endif
this->send_user_command(this->username, this->realname);
} }
void IrcClient::on_connection_close(const std::string& error_msg) void IrcClient::on_connection_close(const std::string& error_msg)
@@ -1346,9 +1346,11 @@ void IrcClient::on_cap(const IrcMessage &message)
else if (sub_command == "NACK") else if (sub_command == "NACK")
capability.on_nack(); capability.on_nack();
this->capabilities.erase(it); this->capabilities.erase(it);
this->cap_end(); if (this->capabilities.empty())
this->cap_end();
} }
#ifdef WITH_SASL
void IrcClient::on_authenticate(const IrcMessage &) void IrcClient::on_authenticate(const IrcMessage &)
{ {
if (this->sasl_state == SaslState::unneeded) if (this->sasl_state == SaslState::unneeded)
@@ -1356,13 +1358,12 @@ void IrcClient::on_authenticate(const IrcMessage &)
log_warning("Received an AUTHENTICATE command but we don’t intend to authenticate…"); log_warning("Received an AUTHENTICATE command but we don’t intend to authenticate…");
return; return;
} }
#ifdef USE_DATABASE
auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(), auto options = Database::get_irc_server_options(this->bridge.get_bare_jid(),
this->get_hostname()); this->get_hostname());
const auto auth_string = '\0' + options.col<Database::Nick>() + '\0' + options.col<Database::SaslPassword>(); const auto auth_string = '\0' + options.col<Database::Nick>() + '\0' + options.col<Database::SaslPassword>();
const auto base64_auth_string = base64::encode(auth_string); const auto base64_auth_string = base64::encode(auth_string);
this->send_message({"AUTHENTICATE", {base64_auth_string}}); this->send_message({"AUTHENTICATE", {base64_auth_string}});
#endif
} }
void IrcClient::on_sasl_success(const IrcMessage &) void IrcClient::on_sasl_success(const IrcMessage &)
@@ -1379,15 +1380,15 @@ void IrcClient::on_sasl_login(const IrcMessage &message)
text = message.arguments[3]; text = message.arguments[3];
this->bridge.send_xmpp_message(this->hostname, message.prefix, text); this->bridge.send_xmpp_message(this->hostname, message.prefix, text);
} }
#endif
void IrcClient::cap_end() void IrcClient::cap_end()
{ {
if (!this->capabilities.empty()) #ifdef WITH_SASL
return;
// If we are currently authenticating through sasl, finish that before sending CAP END // If we are currently authenticating through sasl, finish that before sending CAP END
if (this->sasl_state == SaslState::needed) if (this->sasl_state == SaslState::needed)
return; return;
#endif
this->send_message({"CAP", {"END"}}); this->send_message({"CAP", {"END"}});
this->bridge.on_irc_client_connected(this->get_hostname()); this->bridge.on_irc_client_connected(this->get_hostname());
} }
+10 -1
View File
@@ -3,7 +3,12 @@
#include <irc/irc_message.hpp> #include <irc/irc_message.hpp>
#include <irc/irc_channel.hpp> #include <irc/irc_channel.hpp>
#include <irc/capability.hpp> #include <irc/capability.hpp>
#include <irc/sasl.hpp>
#include "biboumi.h"
#ifdef WITH_SASL
# include <irc/sasl.hpp>
#endif
#include <irc/iid.hpp> #include <irc/iid.hpp>
#include <bridge/history_limit.hpp> #include <bridge/history_limit.hpp>
@@ -240,9 +245,11 @@ public:
private: private:
void cap_end(); void cap_end();
public: public:
#ifdef WITH_SASL
void on_authenticate(const IrcMessage& message); void on_authenticate(const IrcMessage& message);
void on_sasl_success(const IrcMessage& message); void on_sasl_success(const IrcMessage& message);
void on_sasl_login(const IrcMessage& message); void on_sasl_login(const IrcMessage& message);
#endif
/** /**
* The channel has been completely joined (self presence, topic, all names * The channel has been completely joined (self presence, topic, all names
* received etc), send the self presence and topic to the XMPP user. * received etc), send the self presence and topic to the XMPP user.
@@ -371,11 +378,13 @@ private:
* has been established, we are authentified and we have a nick) * has been established, we are authentified and we have a nick)
*/ */
bool welcomed; bool welcomed;
#ifdef WITH_SASL
/** /**
* Whether or not we are trying to authenticate using sasl. If this is true we need to wait for a * Whether or not we are trying to authenticate using sasl. If this is true we need to wait for a
* successful auth * successful auth
*/ */
SaslState sasl_state{SaslState::unneeded}; SaslState sasl_state{SaslState::unneeded};
#endif
std::map<std::string, Capability> capabilities; std::map<std::string, Capability> capabilities;
/** /**
* See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.3 * See http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt section 3.3
+2 -5
View File
@@ -2,18 +2,15 @@
#ifdef BOTAN_FOUND #ifdef BOTAN_FOUND
#include <botan/base64.h> #include <botan/base64.h>
#endif
namespace base64 namespace base64
{ {
std::string encode(const std::string &input) std::string encode(const std::string &input)
{ {
#ifdef BOTAN_FOUND
return Botan::base64_encode(reinterpret_cast<const uint8_t*>(input.data()), input.size()); return Botan::base64_encode(reinterpret_cast<const uint8_t*>(input.data()), input.size());
#else
#error "base64::encode() not yet implemented without Botan."
#endif
} }
} }
#endif
+4
View File
@@ -2,9 +2,13 @@
#include "biboumi.h" #include "biboumi.h"
#ifdef BOTAN_FOUND
#include <string> #include <string>
namespace base64 namespace base64
{ {
std::string encode(const std::string& input); std::string encode(const std::string& input);
} }
#endif
+19 -19
View File
@@ -310,6 +310,20 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
fingerprint_value.set_inner(options.col<Database::TrustedFingerprint>()); fingerprint_value.set_inner(options.col<Database::TrustedFingerprint>());
} }
} }
{
XmlSubNode field(x, "field");
field["var"] = "sasl_password";
field["type"] = "text-private";
field["label"] = "SASL Password";
set_desc(field, "Use it to authenticate with your nick.");
if (!options.col<Database::SaslPassword>().empty())
{
XmlSubNode value(field, "value");
value.set_inner(options.col<Database::SaslPassword>());
}
}
#endif #endif
{ {
@@ -325,19 +339,6 @@ void ConfigureIrcServerStep1(XmppComponent&, AdhocSession& session, XmlNode& com
} }
} }
{
XmlSubNode field(x, "field");
field["var"] = "sasl_password";
field["type"] = "text-private";
field["label"] = "SASL Password";
set_desc(field, "Use it to authenticate with your nick.");
if (!options.col<Database::SaslPassword>().empty())
{
XmlSubNode value(field, "value");
value.set_inner(options.col<Database::SaslPassword>());
}
}
{ {
XmlSubNode pass(x, "field"); XmlSubNode pass(x, "field");
pass["var"] = "pass"; pass["var"] = "pass";
@@ -486,18 +487,17 @@ void ConfigureIrcServerStep2(XmppComponent& xmpp_component, AdhocSession& sessio
} }
else if (field->get_tag("var") == "fingerprint" && value) else if (field->get_tag("var") == "fingerprint" && value)
{ options.col<Database::TrustedFingerprint>() = value->get_inner();
options.col<Database::TrustedFingerprint>() = value->get_inner();
} else if (field->get_tag("var") == "sasl_password" && value)
options.col<Database::SaslPassword>() = value->get_inner();
#endif // BOTAN_FOUND #endif // BOTAN_FOUND
else if (field->get_tag("var") == "nick" && value) else if (field->get_tag("var") == "nick" && value)
options.col<Database::Nick>() = value->get_inner(); options.col<Database::Nick>() = value->get_inner();
else if (field->get_tag("var") == "sasl_password" && value)
options.col<Database::SaslPassword>() = value->get_inner();
else if (field->get_tag("var") == "pass" && value) else if (field->get_tag("var") == "pass" && value)
options.col<Database::Pass>() = value->get_inner(); options.col<Database::Pass>() = value->get_inner();