Skip to content

Commit

Permalink
Merge branch 'jb53434' into 'master'
Browse files Browse the repository at this point in the history
[buteo-sync-plugin-carddav] Allow redirect with different scheme. Contributes to JB#53434

See merge request mer-core/buteo-sync-plugin-carddav!30
  • Loading branch information
chriadam committed Mar 29, 2021
2 parents b4f0c40 + 94ef043 commit 07b96da
Showing 1 changed file with 30 additions and 25 deletions.
55 changes: 30 additions & 25 deletions src/carddav.cpp
Expand Up @@ -601,34 +601,39 @@ void CardDav::userInformationResponse()
QUrl redir = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
if (!redir.isEmpty()) {
QUrl orig = reply->url();
if (orig.path() != redir.path()) {
if (orig.path().endsWith(QStringLiteral(".well-known/carddav"))) {
// redirect as required, and change our server URL to point to the redirect URL.
LOG_DEBUG(Q_FUNC_INFO << "redirecting from:" << orig.toString() << "to:" << redir.toString());
QString redirPort;
if (redir.port() != -1) {
// the redirect was a url, and includes a port. use it.
redirPort = QStringLiteral(":%1").arg(redir.port());
} else if (redir.host().isEmpty() && orig.port() != -1) {
// the redirect was a path, not a url. use the original port.
redirPort = QStringLiteral(":%1").arg(orig.port());
}
m_serverUrl = QStringLiteral("%1://%2%3%4")
.arg(redir.scheme().isEmpty() ? orig.scheme() : redir.scheme())
.arg(redir.host().isEmpty() ? orig.host() : redir.host())
.arg(redirPort)
.arg(redir.path());
m_discoveryStage = CardDav::DiscoveryRedirected;
fetchUserInformation();
} else {
// possibly unsafe redirect. for security, assume it's malicious and abort sync.
LOG_WARNING(Q_FUNC_INFO << "unexpected redirect from:" << orig.toString() << "to:" << redir.toString());
errorOccurred(301);
}
} else {
LOG_DEBUG(Q_FUNC_INFO << "server requested redirect from:" << orig.toString() << "to:" << redir.toString());
const bool hostChanged = orig.host() != redir.host();
const bool pathChanged = orig.path() != redir.path();
const bool schemeChanged = orig.scheme() != redir.scheme();
const bool portChanged = orig.port() != redir.port();
const bool validPathRedirect = orig.path().endsWith(QStringLiteral(".well-known/carddav"))
|| orig.path() == redir.path(); // e.g. scheme change.
if (!hostChanged && !pathChanged && !schemeChanged && !portChanged) {
// circular redirect, avoid the endless loop by aborting sync.
LOG_WARNING(Q_FUNC_INFO << "redirect specified is circular:" << redir.toString());
errorOccurred(301);
} else if (hostChanged || !validPathRedirect) {
// possibly unsafe redirect. for security, assume it's malicious and abort sync.
LOG_WARNING(Q_FUNC_INFO << "unexpected redirect from:" << orig.toString() << "to:" << redir.toString());
errorOccurred(301);
} else {
// redirect as required, and change our server URL to point to the redirect URL.
LOG_DEBUG(Q_FUNC_INFO << "redirecting from:" << orig.toString() << "to:" << redir.toString());
QString redirPort;
if (redir.port() != -1) {
// the redirect was a url, and includes a port. use it.
redirPort = QStringLiteral(":%1").arg(redir.port());
} else if (redir.host().isEmpty() && orig.port() != -1) {
// the redirect was a path, not a url. use the original port.
redirPort = QStringLiteral(":%1").arg(orig.port());
}
m_serverUrl = QStringLiteral("%1://%2%3%4")
.arg(redir.scheme().isEmpty() ? orig.scheme() : redir.scheme())
.arg(redir.host().isEmpty() ? orig.host() : redir.host())
.arg(redirPort)
.arg(redir.path());
m_discoveryStage = CardDav::DiscoveryRedirected;
fetchUserInformation();
}
return;
}
Expand Down

0 comments on commit 07b96da

Please sign in to comment.