summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoanna Hulboj <joanna.hulboj@isode.com>2019-05-24 09:30:14 (GMT)
committerJoanna Hulboj <joanna.hulboj@isode.com>2019-05-28 15:14:50 (GMT)
commitf4b6bfbf4c1573e9914185e2ef170f47838ea11a (patch)
treeb87b2442cda92bb70be95a64b3b8295c37fe8d9f /Swiften/JID/JID.cpp
parent09d8ac653493a0bd16cb69664ca28fbfe3c61bbb (diff)
downloadswift-f4b6bfbf4c1573e9914185e2ef170f47838ea11a.zip
swift-f4b6bfbf4c1573e9914185e2ef170f47838ea11a.tar.bz2
Add check if IPv4, IPv6 are valid JID domain part
When creating a JID we were not checking if a domain part is a valid IPv4, IPv6 addresses. We were only checking if the domain is correct according to internationalized domain name rules which was failing for IPv6 addresses. Test-Information: Unit tests pass on Windows 10 and Ubuntu 18.04.1 LTS Change-Id: Ia1b67089f6edfdc6a0ebf2d26a7eaab9ce8171c0
Diffstat (limited to 'Swiften/JID/JID.cpp')
-rw-r--r--Swiften/JID/JID.cpp41
1 files changed, 38 insertions, 3 deletions
diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp
index fff88e9..5c6ea9d 100644
--- a/Swiften/JID/JID.cpp
+++ b/Swiften/JID/JID.cpp
@@ -13,6 +13,7 @@
#include <Swiften/Base/String.h>
#include <Swiften/IDN/IDNConverter.h>
#include <Swiften/JID/JID.h>
+#include <Swiften/Network/HostAddress.h>
#ifndef SWIFTEN_JID_NO_DEFAULT_IDN_CONVERTER
#include <memory>
@@ -97,14 +98,47 @@ void JID::initializeFromString(const std::string& jid) {
}
}
+void JID::setComponents(const std::string& node, const std::string& domain, const std::string& resource) {
+ domain_ = domain;
+ try {
+ node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
+ resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
+ }
+ catch (...) {
+ valid_ = false;
+ return;
+ }
+}
void JID::nameprepAndSetComponents(const std::string& node, const std::string& domain, const std::string& resource) {
- if (domain.empty() || !idnConverter->getIDNAEncoded(domain)) {
+ if (domain.empty() || (hasResource_ && resource.empty())) {
valid_ = false;
return;
}
- if (hasResource_ && resource.empty()) {
+ // Handling IPv6 addresses according to RFC 3986 rules
+ // saying that they are enclosed in square brackets
+ // which we have to remove when passing to HostAddress
+ if (domain.size() > 2 && domain.front() == '[' && domain.back() == ']') {
+ auto inner = std::string(domain.begin() + 1, domain.end() - 1);
+ auto hostAddress = HostAddress::fromString(inner);
+ if (hostAddress && hostAddress->isValid()) {
+ setComponents(node, domain, resource);
+ return;
+ }
+ }
+
+ const auto isAnyOfNonNumericAndNotDot = std::any_of(std::begin(domain), std::end(domain), [](char c) {return !::isdigit(c) && c != '.'; });
+
+ if (!isAnyOfNonNumericAndNotDot) {
+ auto hostAddress = HostAddress::fromString(domain);
+ if (hostAddress && hostAddress->isValid()) {
+ setComponents(node, domain, resource);
+ return;
+ }
+ }
+
+ if (!isAnyOfNonNumericAndNotDot || !idnConverter->getIDNAEncoded(domain)) {
valid_ = false;
return;
}
@@ -118,7 +152,8 @@ void JID::nameprepAndSetComponents(const std::string& node, const std::string& d
domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep);
}
resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
- } catch (...) {
+ }
+ catch (...) {
valid_ = false;
return;
}