diff options
author | Samuel Gaist <samuel.gaist@idiap.ch> | 2019-11-26 23:55:01 +0100 |
---|---|---|
committer | Samuel Gaist <samuel.gaist@idiap.ch> | 2020-01-23 16:47:31 +0100 |
commit | 49f143e19ca11ef48260a3aaaa4ddbe490cf81ab (patch) | |
tree | d581f85932f43e3f38c7853f567c1344c9465da3 /src/network/ssl | |
parent | 73d1476fb1397948a4d806bd921fce372bd8d63b (diff) |
QSslCertificate: migrate to QRegularExpression
This is part of the migration of qtbase from QRexExp to
QRegularExpression.
If support for regular expression is disabled, fixed string can
still be used.
[ChangeLog][QtCore][QSslCertificate] Add overload of fromPath that does
not make use of QRegExp and deprecate the QRegExp variant.
Task-number: QTBUG-72587
Change-Id: I507d8941cc7d70166da0948375dc421fe5e7d967
Reviewed-by: MÃ¥rten Nordheim <marten.nordheim@qt.io>
Diffstat (limited to 'src/network/ssl')
-rw-r--r-- | src/network/ssl/qsslcertificate.cpp | 107 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate.h | 20 |
2 files changed, 125 insertions, 2 deletions
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 4820953468..c179cf9c4a 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -124,7 +124,9 @@ #if QT_CONFIG(schannel) #include "qsslsocket_schannel_p.h" #endif - +#if QT_CONFIG(regularexpression) +#include "qregularexpression.h" +#endif #include "qssl_p.h" #include "qsslcertificate.h" #include "qsslcertificate_p.h" @@ -462,7 +464,10 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons \since 5.0 */ +#if QT_DEPRECATED_SINCE(5,15) /*! + \obsolete + Searches all files in the \a path for certificates encoded in the specified \a format and returns them in a list. \a path must be a file or a pattern matching one or more files, as specified by \a syntax. @@ -537,6 +542,106 @@ QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, } return certs; } +#endif // QT_DEPRECATED_SINCE(5,15) + +/*! + \since 5.15 + + Searches all files in the \a path for certificates encoded in the + specified \a format and returns them in a list. \a path must be a file + or a pattern matching one or more files, as specified by \a syntax. + + Example: + + \snippet code/src_network_ssl_qsslcertificate.cpp 1 + + \sa fromData() +*/ +QList<QSslCertificate> QSslCertificate::fromPath(const QString &path, + QSsl::EncodingFormat format, + PatternSyntax syntax) +{ + // $, (,), *, +, ., ?, [, ,], ^, {, | and }. + + // make sure to use the same path separators on Windows and Unix like systems. + QString sourcePath = QDir::fromNativeSeparators(path); + + // Find the path without the filename + QString pathPrefix = sourcePath.left(sourcePath.lastIndexOf(QLatin1Char('/'))); + + // Check if the path contains any special chars + int pos = -1; + +#if QT_CONFIG(regularexpression) + if (syntax == Wildcard) + pos = pathPrefix.indexOf(QRegularExpression(QLatin1String("[*?[]"))); + else if (syntax == RegExp) + pos = sourcePath.indexOf(QRegularExpression(QLatin1String("[\\$\\(\\)\\*\\+\\.\\?\\[\\]\\^\\{\\}\\|]"))); +#else + if (syntax == Wildcard || syntax == RegExp) + qWarning("Regular expression support is disabled in this build. Only fixed string can be searched"); + return QList<QSslCertificate>(); +#endif + + if (pos != -1) { + // there was a special char in the path so cut of the part containing that char. + pathPrefix = pathPrefix.left(pos); + const int lastIndexOfSlash = pathPrefix.lastIndexOf(QLatin1Char('/')); + if (lastIndexOfSlash != -1) + pathPrefix = pathPrefix.left(lastIndexOfSlash); + else + pathPrefix.clear(); + } else { + // Check if the path is a file. + if (QFileInfo(sourcePath).isFile()) { + QFile file(sourcePath); + QIODevice::OpenMode openMode = QIODevice::ReadOnly; + if (format == QSsl::Pem) + openMode |= QIODevice::Text; + if (file.open(openMode)) + return QSslCertificate::fromData(file.readAll(), format); + return QList<QSslCertificate>(); + } + } + + // Special case - if the prefix ends up being nothing, use "." instead. + int startIndex = 0; + if (pathPrefix.isEmpty()) { + pathPrefix = QLatin1String("."); + startIndex = 2; + } + + // The path can be a file or directory. + QList<QSslCertificate> certs; + +#if QT_CONFIG(regularexpression) + if (syntax == Wildcard) + sourcePath = QRegularExpression::wildcardToRegularExpression(sourcePath); + + QRegularExpression pattern(QRegularExpression::anchoredPattern(sourcePath)); +#endif + + QDirIterator it(pathPrefix, QDir::Files, QDirIterator::FollowSymlinks | QDirIterator::Subdirectories); + while (it.hasNext()) { + QString filePath = startIndex == 0 ? it.next() : it.next().mid(startIndex); + +#if QT_CONFIG(regularexpression) + if (!pattern.match(filePath).hasMatch()) + continue; +#else + if (sourcePath != filePath) + continue; +#endif + + QFile file(filePath); + QIODevice::OpenMode openMode = QIODevice::ReadOnly; + if (format == QSsl::Pem) + openMode |= QIODevice::Text; + if (file.open(openMode)) + certs += QSslCertificate::fromData(file.readAll(), format); + } + return certs; +} /*! Searches for and parses all certificates in \a device that are diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index 69901b526c..9993769888 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -84,6 +84,13 @@ public: EmailAddress }; + enum PatternSyntax { + RegExp, + Wildcard, + FixedString + }; + + explicit QSslCertificate(QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem); explicit QSslCertificate(const QByteArray &data = QByteArray(), QSsl::EncodingFormat format = QSsl::Pem); QSslCertificate(const QSslCertificate &other); @@ -139,9 +146,20 @@ public: QByteArray toDer() const; QString toText() const; - static QList<QSslCertificate> fromPath( +#if QT_DEPRECATED_SINCE(5,15) + QT_DEPRECATED_X("Use the overload not using QRegExp") static QList<QSslCertificate> fromPath( const QString &path, QSsl::EncodingFormat format = QSsl::Pem, QRegExp::PatternSyntax syntax = QRegExp::FixedString); + + static QList<QSslCertificate> fromPath( + const QString &path, QSsl::EncodingFormat format, + PatternSyntax syntax); +#else + static QList<QSslCertificate> fromPath( + const QString &path, QSsl::EncodingFormat format = QSsl::Pem, + PatternSyntax syntax = FixedString); +#endif + static QList<QSslCertificate> fromDevice( QIODevice *device, QSsl::EncodingFormat format = QSsl::Pem); static QList<QSslCertificate> fromData( |