All pastes #1937328 Raw Edit

Miscellany

public text v1 · immutable
#1937328 ·published 2010-09-10 15:10 UTC
rendered paste body
Index: kio/kio/tcpslavebase.cpp
===================================================================
--- kio/kio/tcpslavebase.cpp	(revision 1173815)
+++ kio/kio/tcpslavebase.cpp	(working copy)
@@ -4,6 +4,7 @@
  * Copyright (C) 2001 Dawit Alemayehu <adawit@kde.org>
  * Copyright (C) 2007,2008 Andreas Hartmetz <ahartmetz@gmail.com>
  * Copyright (C) 2008 Roland Harnau <tau@gmx.eu>
+ * Copyright (C) 2010 Richard Moore <rich@kde.org>
  *
  * This file is part of the KDE project
  *
@@ -452,7 +453,46 @@
     return startTLSInternal(KTcpSocket::TlsV1) & ResultOk;
 }
 
+bool TCPSlaveBase::isMatchingHostname(const QString &cn, const QString &hostname)
+{
+    int wildcard = cn.indexOf(QLatin1Char('*'));
 
+    // Check this is a wildcard cert, if not then just compare the strings
+    if (wildcard < 0)
+        return cn == hostname;
+
+    int firstCnDot = cn.indexOf(QLatin1Char('.'));
+    int secondCnDot = cn.indexOf(QLatin1Char('.'), firstCnDot+1);
+
+    // Check at least 3 components
+    if ((-1 == secondCnDot) || (secondCnDot+1 >= cn.length()))
+        return false;
+
+    // Check * is last character of 1st component (ie. there's a following .)
+    if (wildcard+1 != firstCnDot)
+        return false;
+
+    // Check only one star
+    if (cn.lastIndexOf(QLatin1Char('*')) != wildcard)
+        return false;
+
+    // Check characters preceding * (if any) match
+    if (wildcard && (hostname.leftRef(wildcard) != cn.leftRef(wildcard)))
+        return false;
+
+    // Check characters following first . match
+    if (hostname.midRef(hostname.indexOf(QLatin1Char('.'))) != cn.midRef(firstCnDot))
+        return false;
+
+    // Check if the hostname is an IP address, if so then wildcards are not allowed
+    QHostAddress addr(hostname);
+    if (!addr.isNull())
+        return false;
+
+    // Ok, I guess this was a wildcard CN and the hostname matches.
+    return true;
+}
+
 TCPSlaveBase::SslResult TCPSlaveBase::startTLSInternal(uint v_)
 {
     KTcpSocket::SslVersion sslVersion = static_cast<KTcpSocket::SslVersion>(v_);
@@ -507,7 +547,6 @@
     QSslCertificate peerCert = d->socket.peerCertificateChain().first();
     QStringList domainPatterns(peerCert.subjectInfo(QSslCertificate::CommonName));
     domainPatterns += peerCert.alternateSubjectNames().values(QSsl::DnsEntry);
-    QRegExp domainMatcher(QString(), Qt::CaseInsensitive, QRegExp::Wildcard);
     QMutableListIterator<KSslError> it(d->sslErrors);
     while (it.hasNext()) {
         // As of 4.4.0 Qt does not assign a certificate to the QSslError it emits
@@ -518,8 +557,7 @@
             continue;
         }
         Q_FOREACH (const QString &dp, domainPatterns) {
-            domainMatcher.setPattern(dp);
-            if (domainMatcher.exactMatch(d->host)) {
+            if (isMatchingHostname(dp, d->host)) {
                 it.remove();
             }
         }
Index: kio/kio/tcpslavebase.h
===================================================================
--- kio/kio/tcpslavebase.h	(revision 1173815)
+++ kio/kio/tcpslavebase.h	(working copy)
@@ -198,6 +198,9 @@
     // For the certificate verification code
     SslResult verifyServerCertificate();
 
+    // For verifying ssl hostnames (including wildcards)
+    bool isMatchingHostname(const QString &cn, const QString &hostname);
+
     // For prompting for the client certificate to use
     void selectClientCertificate();