From 890cfe90996ac4c3916c84d178049d9b3b23465b Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Mon, 21 Sep 2015 04:27:23 +0200 Subject: Provide Ports and TLS Ports IRC-server ad-hoc options This let any user choose which ports to use when connecting to the IRC server. This also lets the user choose whether or not to force TLS usage (by setting no non-TLS port). fix #2731 --- src/irc/irc_client.cpp | 22 +++++++++--- src/test.cpp | 10 ------ src/xmpp/biboumi_adhoc_commands.cpp | 67 ++++++++++++++++++++++++++++++------- 3 files changed, 72 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index bac3e34..c6174bf 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -16,11 +16,13 @@ #include #include +#include "biboumi.h" #include "louloulibs.h" using namespace std::string_literals; using namespace std::chrono_literals; + IrcClient::IrcClient(std::shared_ptr poller, const std::string& hostname, const std::string& username, Bridge* bridge): TCPSocketHandler(poller), hostname(hostname), @@ -39,13 +41,25 @@ IrcClient::IrcClient(std::shared_ptr poller, const std::string& hostname "alive without having to join a real channel of that server. " "To disconnect from the IRC server, leave this room and all " "other IRC channels of that server."; - // TODO: get the values from the preferences of the user, and only use the - // list of default ports if the user didn't specify anything +#ifdef USE_DATABASE + auto options = Database::get_irc_server_options(this->bridge->get_bare_jid(), + this->get_hostname()); + std::vector ports = utils::split(options.ports, ';', false); + for (auto it = ports.rbegin(); it != ports.rend(); ++it) + this->ports_to_try.emplace(*it, false); +# ifdef BOTAN_FOUND + ports = utils::split(options.tlsPorts, ';', false); + for (auto it = ports.rbegin(); it != ports.rend(); ++it) + this->ports_to_try.emplace(*it, true); +# endif // BOTAN_FOUND + +#else // not USE_DATABASE this->ports_to_try.emplace("6667", false); // standard non-encrypted port -#ifdef BOTAN_FOUND +# ifdef BOTAN_FOUND this->ports_to_try.emplace("6670", true); // non-standard but I want it for some servers this->ports_to_try.emplace("6697", true); // standard encrypted port -#endif // BOTAN_FOUND +# endif // BOTAN_FOUND +#endif // USE_DATABASE } IrcClient::~IrcClient() diff --git a/src/test.cpp b/src/test.cpp index 79fcd0b..1a59041 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -423,12 +423,9 @@ int main() Config::set("db_name", "test.db"); Database::set_verbose(true); auto o = Database::get_irc_server_options("zouzou@example.com", "irc.example.com"); - o.requireTls = false; o.update(); auto a = Database::get_irc_server_options("zouzou@example.com", "irc.example.com"); - assert(a.requireTls == false); auto b = Database::get_irc_server_options("moumou@example.com", "irc.example.com"); - assert(b.requireTls == true); // b does not yet exist in the db, the object is created but not yet // inserted @@ -439,13 +436,6 @@ int main() assert(b.pass == ""); assert(b.pass.value() == ""); - - std::vector ftypes; - db::IrcServerOptions::getFieldTypes(ftypes); - for (const auto& type: ftypes) - { - std::cout << type.type() << std::endl; - } } #endif { diff --git a/src/xmpp/biboumi_adhoc_commands.cpp b/src/xmpp/biboumi_adhoc_commands.cpp index 1be38d3..2964b22 100644 --- a/src/xmpp/biboumi_adhoc_commands.cpp +++ b/src/xmpp/biboumi_adhoc_commands.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -10,6 +11,8 @@ #include #endif +#include + using namespace std::string_literals; void DisconnectUserStep1(XmppComponent* xmpp_component, AdhocSession&, XmlNode& command_node) @@ -127,16 +130,39 @@ void ConfigureIrcServerStep1(XmppComponent* xmpp_component, AdhocSession& sessio instructions.set_inner("Edit the form, to configure the settings of the IRC server "s + target.local); x.add_child(std::move(instructions)); - XmlNode require_tls("field"); - require_tls["var"] = "require_tls"; - require_tls["type"] = "boolean"; - require_tls["label"] = "Require TLS (refuse to connect insecurely)"; - XmlNode require_tls_value("value"); - require_tls_value.set_inner(options.requireTls ? "true": "false"); - require_tls.add_child(std::move(require_tls_value)); XmlNode required("required"); - require_tls.add_child(required); - x.add_child(std::move(require_tls)); + + XmlNode ports("field"); + ports["var"] = "ports"; + ports["type"] = "text-multi"; + ports["label"] = "Ports"; + ports["desc"] = "List of ports to try, without TLS. Defaults: 6667."; + auto vals = utils::split(options.ports.value(), ';', false); + for (const auto& val: vals) + { + XmlNode ports_value("value"); + ports_value.set_inner(val); + ports.add_child(std::move(ports_value)); + } + ports.add_child(required); + x.add_child(std::move(ports)); + +#ifdef BOTAN_FOUND + XmlNode tls_ports("field"); + tls_ports["var"] = "tls_ports"; + tls_ports["type"] = "text-multi"; + tls_ports["label"] = "TLS ports"; + tls_ports["desc"] = "List of ports to try, with TLS. Defaults: 6697, 6670."; + vals = utils::split(options.tlsPorts.value(), ';', false); + for (const auto& val: vals) + { + XmlNode tls_ports_value("value"); + tls_ports_value.set_inner(val); + tls_ports.add_child(std::move(tls_ports_value)); + } + tls_ports.add_child(required); + x.add_child(std::move(tls_ports)); +#endif XmlNode pass("field"); pass["var"] = "pass"; @@ -168,12 +194,27 @@ void ConfigureIrcServerStep2(XmppComponent* xmpp_component, AdhocSession& sessio for (const XmlNode* field: x->get_children("field", "jabber:x:data")) { const XmlNode* value = field->get_child("value", "jabber:x:data"); - if (field->get_tag("var") == "require_tls" && - value && !value->get_inner().empty()) - options.requireTls = to_bool(value->get_inner()); + const std::vector values = field->get_children("value", "jabber:x:data"); + if (field->get_tag("var") == "ports") + { + std::string ports; + for (const auto& val: values) + ports += val->get_inner() + ";"; + options.ports = ports; + } + +#ifdef BOTAN_FOUND + else if (field->get_tag("var") == "tls_ports") + { + std::string ports; + for (const auto& val: values) + ports += val->get_inner() + ";"; + options.tlsPorts = ports; + } +#endif // BOTAN_FOUND else if (field->get_tag("var") == "pass" && - value && !value->get_inner().empty()) + value && !value->get_inner().empty()) options.pass = value->get_inner(); } -- cgit v1.2.3