File indexing completed on 2023-09-24 04:08:40
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2007 Thiago Macieira <thiago@kde.org> 0004 SPDX-FileCopyrightText: 2007 Andreas Hartmetz <ahartmetz@gmail.com> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #ifndef KTCPSOCKET_H 0010 #define KTCPSOCKET_H 0011 0012 #include "kiocore_export.h" 0013 0014 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 65) 0015 #include "ksslerroruidata.h" 0016 0017 #include <QSslConfiguration> 0018 #include <QSslSocket> 0019 0020 #include <memory> 0021 0022 // All classes here are deprecated, no need for clazy to bother 0023 // clazy:excludeall=overloaded-signal,fully-qualified-moc-types 0024 0025 /* 0026 Notes on QCA::TLS compatibility 0027 In order to check for all validation problems as far as possible we need to use: 0028 Validity QCA::TLS::peerCertificateValidity() 0029 TLS::IdentityResult QCA::TLS::peerIdentityResult() 0030 CertificateChain QCA::TLS::peerCertificateChain().validate() - to find the failing cert! 0031 TLS::Error QCA::TLS::errorCode() - for more generic (but still SSL) errors 0032 */ 0033 0034 class KSslKeyPrivate; 0035 0036 /** SSL Key 0037 * @deprecated since 5.65, use QSslKey instead. 0038 */ 0039 class KIOCORE_EXPORT KIOCORE_DEPRECATED_VERSION(5, 65, "Use QSslKey") KSslKey 0040 { 0041 public: 0042 enum Algorithm { 0043 Rsa = 0, 0044 Dsa, 0045 Dh, 0046 }; 0047 enum KeySecrecy { 0048 PublicKey, 0049 PrivateKey, 0050 }; 0051 0052 KSslKey(); 0053 KSslKey(const KSslKey &other); 0054 KSslKey(const QSslKey &sslKey); 0055 ~KSslKey(); 0056 KSslKey &operator=(const KSslKey &other); 0057 0058 Algorithm algorithm() const; 0059 bool isExportable() const; 0060 KeySecrecy secrecy() const; 0061 QByteArray toDer() const; 0062 0063 private: 0064 std::unique_ptr<KSslKeyPrivate> const d; 0065 }; 0066 0067 class KSslCipherPrivate; 0068 0069 /** SSL Cipher 0070 * @deprecated since 5.65, use QSslCipher instead. 0071 */ 0072 class KIOCORE_EXPORT KIOCORE_DEPRECATED_VERSION(5, 65, "Use QSslCipher") KSslCipher 0073 { 0074 public: 0075 KSslCipher(); 0076 KSslCipher(const KSslCipher &other); 0077 KSslCipher(const QSslCipher &); 0078 ~KSslCipher(); 0079 KSslCipher &operator=(const KSslCipher &other); 0080 0081 bool isNull() const; 0082 QString authenticationMethod() const; 0083 QString encryptionMethod() const; 0084 QString keyExchangeMethod() const; 0085 QString digestMethod() const; 0086 /* mainly for internal use */ 0087 QString name() const; 0088 int supportedBits() const; 0089 int usedBits() const; 0090 0091 static QList<KSslCipher> supportedCiphers(); 0092 0093 private: 0094 std::unique_ptr<KSslCipherPrivate> const d; 0095 }; 0096 0097 class KSslErrorPrivate; 0098 class KTcpSocket; 0099 0100 /** To be replaced by QSslError. 0101 * @deprecated since 5.65 0102 */ 0103 class KIOCORE_EXPORT KIOCORE_DEPRECATED_VERSION(5, 65, "Use QSslError") KSslError 0104 { 0105 public: 0106 enum Error { 0107 NoError = 0, 0108 UnknownError, 0109 InvalidCertificateAuthorityCertificate, 0110 InvalidCertificate, 0111 CertificateSignatureFailed, 0112 SelfSignedCertificate, 0113 ExpiredCertificate, 0114 RevokedCertificate, 0115 InvalidCertificatePurpose, 0116 RejectedCertificate, 0117 UntrustedCertificate, 0118 NoPeerCertificate, 0119 HostNameMismatch, 0120 PathLengthExceeded, 0121 }; 0122 0123 #if KIOCORE_ENABLE_DEPRECATED_SINCE(5, 63) 0124 /** @deprecated since 5.63, use the QSslError ctor instead. */ 0125 KIOCORE_DEPRECATED_VERSION(5, 63, "Use KSslError(const QSslError &)") 0126 KSslError(KSslError::Error error = NoError, const QSslCertificate &cert = QSslCertificate()); 0127 #endif 0128 KSslError(const QSslError &error); 0129 KSslError(const KSslError &other); 0130 ~KSslError(); 0131 KSslError &operator=(const KSslError &other); 0132 0133 Error error() const; 0134 QString errorString() const; 0135 QSslCertificate certificate() const; 0136 /** 0137 * Returns the QSslError wrapped by this KSslError. 0138 * @since 5.63 0139 */ 0140 QSslError sslError() const; 0141 0142 private: 0143 std::unique_ptr<KSslErrorPrivate> const d; 0144 }; 0145 0146 // consider killing more convenience functions with huge signatures 0147 // ### do we need setSession() / session() ? 0148 0149 // BIG FAT TODO: do we keep openMode() up to date everywhere it can change? 0150 0151 // other TODO: limit possible error strings?, SSL key stuff 0152 0153 // TODO protocol (or maybe even application?) dependent automatic proxy choice 0154 0155 class KTcpSocketPrivate; 0156 class QHostAddress; 0157 0158 /** TCP socket. 0159 * @deprecated since 5.65, use QSslSocket instead. 0160 */ 0161 class KIOCORE_EXPORT KIOCORE_DEPRECATED_VERSION(5, 65, "Use QSslSocket") KTcpSocket : public QIODevice 0162 { 0163 Q_OBJECT 0164 public: 0165 enum State { 0166 UnconnectedState = 0, 0167 HostLookupState, 0168 ConnectingState, 0169 ConnectedState, 0170 BoundState, 0171 ListeningState, 0172 ClosingState, 0173 // hmmm, do we need an SslNegotiatingState? 0174 }; 0175 enum SslVersion { 0176 UnknownSslVersion = 0x01, 0177 SslV2 = 0x02, ///< Note: no-op in Qt for a long time 0178 SslV3 = 0x04, ///< Note: no-op in Qt for a long time 0179 TlsV1 = 0x08, 0180 SslV3_1 = 0x08, 0181 TlsV1SslV3 = 0x10, ///< Note: same as TlsV1_0 0182 SecureProtocols = 0x20, 0183 TlsV1_0 = TlsV1, 0184 TlsV1_1 = 0x40, 0185 TlsV1_2 = 0x80, 0186 TlsV1_3 = 0x100, 0187 AnySslVersion = SslV2 | SslV3 | TlsV1, 0188 }; 0189 Q_DECLARE_FLAGS(SslVersions, SslVersion) 0190 0191 enum Error { 0192 UnknownError = 0, 0193 ConnectionRefusedError, 0194 RemoteHostClosedError, 0195 HostNotFoundError, 0196 SocketAccessError, 0197 SocketResourceError, 0198 SocketTimeoutError, 0199 NetworkError, 0200 UnsupportedSocketOperationError, 0201 SslHandshakeFailedError, ///< @since 4.10.5 0202 }; 0203 /* 0204 The following is based on reading the OpenSSL interface code of both QSslSocket 0205 and QCA::TLS. Barring oversights it should be accurate. The two cases with the 0206 question marks apparently will never be emitted by QSslSocket so there is nothing 0207 to compare. 0208 0209 QSslError::NoError KTcpSocket::NoError 0210 QSslError::UnableToGetIssuerCertificate QCA::ErrorSignatureFailed 0211 QSslError::UnableToDecryptCertificateSignature QCA::ErrorSignatureFailed 0212 QSslError::UnableToDecodeIssuerPublicKey QCA::ErrorInvalidCA 0213 QSslError::CertificateSignatureFailed QCA::ErrorSignatureFailed 0214 QSslError::CertificateNotYetValid QCA::ErrorExpired 0215 QSslError::CertificateExpired QCA::ErrorExpired 0216 QSslError::InvalidNotBeforeField QCA::ErrorExpired 0217 QSslError::InvalidNotAfterField QCA::ErrorExpired 0218 QSslError::SelfSignedCertificate QCA::ErrorSelfSigned 0219 QSslError::SelfSignedCertificateInChain QCA::ErrorSelfSigned 0220 QSslError::UnableToGetLocalIssuerCertificate QCA::ErrorInvalidCA 0221 QSslError::UnableToVerifyFirstCertificate QCA::ErrorSignatureFailed 0222 QSslError::CertificateRevoked QCA::ErrorRevoked 0223 QSslError::InvalidCaCertificate QCA::ErrorInvalidCA 0224 QSslError::PathLengthExceeded QCA::ErrorPathLengthExceeded 0225 QSslError::InvalidPurpose QCA::ErrorInvalidPurpose 0226 QSslError::CertificateUntrusted QCA::ErrorUntrusted 0227 QSslError::CertificateRejected QCA::ErrorRejected 0228 QSslError::SubjectIssuerMismatch QCA::TLS::InvalidCertificate ? 0229 QSslError::AuthorityIssuerSerialNumberMismatch QCA::TLS::InvalidCertificate ? 0230 QSslError::NoPeerCertificate QCA::TLS::NoCertificate 0231 QSslError::HostNameMismatch QCA::TLS::HostMismatch 0232 QSslError::UnspecifiedError KTcpSocket::UnknownError 0233 QSslError::NoSslSupport Never happens :) 0234 */ 0235 enum EncryptionMode { 0236 UnencryptedMode = 0, 0237 SslClientMode, 0238 SslServerMode, // ### not implemented 0239 }; 0240 enum ProxyPolicy { 0241 /// Use the proxy that KProtocolManager suggests for the connection parameters given. 0242 AutoProxy = 0, 0243 /// Use the proxy set by setProxy(), if any; otherwise use no proxy. 0244 ManualProxy, 0245 }; 0246 0247 KTcpSocket(QObject *parent = nullptr); 0248 ~KTcpSocket() override; 0249 0250 // from QIODevice 0251 // reimplemented virtuals - the ones not reimplemented are OK for us 0252 bool atEnd() const override; 0253 qint64 bytesAvailable() const override; 0254 qint64 bytesToWrite() const override; 0255 bool canReadLine() const override; 0256 void close() override; 0257 bool isSequential() const override; 0258 bool open(QIODevice::OpenMode open) override; 0259 bool waitForBytesWritten(int msecs) override; 0260 // ### Document that this actually tries to read *more* data 0261 bool waitForReadyRead(int msecs = 30000) override; 0262 0263 protected: 0264 qint64 readData(char *data, qint64 maxSize) override; 0265 qint64 writeData(const char *data, qint64 maxSize) override; 0266 Q_SIGNALS: 0267 /// @since 4.8.1 0268 /// Forwarded from QSslSocket 0269 void encryptedBytesWritten(qint64 written); 0270 0271 public: 0272 // from QAbstractSocket 0273 void abort(); 0274 void connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy = AutoProxy); 0275 void connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy = AutoProxy); 0276 0277 /** 0278 * Take the hostname and port from @p url and connect to them. The information from a 0279 * full URL enables the most accurate choice of proxy in case of proxy rules that 0280 * depend on high-level information like protocol or username. 0281 * @see KProtocolManager::proxyForUrl() 0282 */ 0283 void connectToHost(const QUrl &url, ProxyPolicy policy = AutoProxy); 0284 void disconnectFromHost(); 0285 Error error() const; // ### QAbstractSocket's model is strange. error() should be related to the 0286 // current state and *NOT* just report the last error if there was one. 0287 QList<KSslError> sslErrors() const; // ### the errors returned can only have a subset of all 0288 // possible QSslError::SslError enum values depending on backend 0289 bool flush(); 0290 bool isValid() const; 0291 QHostAddress localAddress() const; 0292 QHostAddress peerAddress() const; 0293 QString peerName() const; 0294 quint16 peerPort() const; 0295 void setVerificationPeerName(const QString &hostName); 0296 0297 #ifndef QT_NO_NETWORKPROXY 0298 /** 0299 * @see: connectToHost() 0300 */ 0301 QNetworkProxy proxy() const; 0302 #endif 0303 qint64 readBufferSize() const; // probably hard to implement correctly 0304 0305 #ifndef QT_NO_NETWORKPROXY 0306 /** 0307 * @see: connectToHost() 0308 */ 0309 void setProxy(const QNetworkProxy &proxy); // people actually seem to need it 0310 #endif 0311 void setReadBufferSize(qint64 size); 0312 State state() const; 0313 bool waitForConnected(int msecs = 30000); 0314 bool waitForDisconnected(int msecs = 30000); 0315 0316 // from QSslSocket 0317 void addCaCertificate(const QSslCertificate &certificate); 0318 // bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, 0319 // QRegExp::PatternSyntax syntax = QRegExp::FixedString); 0320 void addCaCertificates(const QList<QSslCertificate> &certificates); 0321 QList<QSslCertificate> caCertificates() const; 0322 QList<KSslCipher> ciphers() const; 0323 void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite); 0324 // bool isEncrypted() const { return encryptionMode() != UnencryptedMode } 0325 QSslCertificate localCertificate() const; 0326 QList<QSslCertificate> peerCertificateChain() const; 0327 KSslKey privateKey() const; 0328 KSslCipher sessionCipher() const; 0329 void setCaCertificates(const QList<QSslCertificate> &certificates); 0330 void setCiphers(const QList<KSslCipher> &ciphers); 0331 // ### void setCiphers(const QString &ciphers); //what about i18n? 0332 void setLocalCertificate(const QSslCertificate &certificate); 0333 void setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format = QSsl::Pem); 0334 void setPrivateKey(const KSslKey &key); 0335 void setPrivateKey(const QString &fileName, 0336 KSslKey::Algorithm algorithm = KSslKey::Rsa, 0337 QSsl::EncodingFormat format = QSsl::Pem, 0338 const QByteArray &passPhrase = QByteArray()); 0339 void setAdvertisedSslVersion(SslVersion version); 0340 SslVersion advertisedSslVersion() const; // always equal to last setSslAdvertisedVersion 0341 SslVersion negotiatedSslVersion() const; // negotiated version; downgrades are possible. 0342 QString negotiatedSslVersionName() const; 0343 bool waitForEncrypted(int msecs = 30000); 0344 0345 EncryptionMode encryptionMode() const; 0346 0347 /** 0348 * Returns the state of the socket @p option. 0349 * 0350 * @see QAbstractSocket::socketOption 0351 * 0352 * @since 4.5.0 0353 */ 0354 QVariant socketOption(QAbstractSocket::SocketOption options) const; 0355 0356 /** 0357 * Sets the socket @p option to @p value. 0358 * 0359 * @see QAbstractSocket::setSocketOption 0360 * 0361 * @since 4.5.0 0362 */ 0363 void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value); 0364 0365 /** 0366 * Returns the socket's SSL configuration. 0367 * 0368 * @since 4.8.4 0369 */ 0370 QSslConfiguration sslConfiguration() const; 0371 0372 /** 0373 * Sets the socket's SSL configuration. 0374 * 0375 * @since 4.8.4 0376 */ 0377 void setSslConfiguration(const QSslConfiguration &configuration); 0378 0379 Q_SIGNALS: 0380 // from QAbstractSocket 0381 void connected(); 0382 void disconnected(); 0383 void error(KTcpSocket::Error); 0384 void hostFound(); 0385 #ifndef QT_NO_NETWORKPROXY 0386 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); 0387 #endif 0388 // only for raw socket state, SSL is separate 0389 void stateChanged(KTcpSocket::State); 0390 0391 // from QSslSocket 0392 void encrypted(); 0393 void encryptionModeChanged(EncryptionMode); 0394 void sslErrors(const QList<KSslError> &errors); 0395 0396 public Q_SLOTS: 0397 void ignoreSslErrors(); 0398 void startClientEncryption(); 0399 // void startServerEncryption(); //not implemented 0400 private: 0401 Q_PRIVATE_SLOT(d, void reemitReadyRead()) 0402 Q_PRIVATE_SLOT(d, void reemitSocketError(QAbstractSocket::SocketError)) 0403 Q_PRIVATE_SLOT(d, void reemitSslErrors(const QList<QSslError> &)) 0404 Q_PRIVATE_SLOT(d, void reemitStateChanged(QAbstractSocket::SocketState)) 0405 Q_PRIVATE_SLOT(d, void reemitModeChanged(QSslSocket::SslMode)) 0406 0407 // debugging H4X 0408 void showSslErrors(); 0409 0410 friend class KTcpSocketPrivate; 0411 std::unique_ptr<KTcpSocketPrivate> const d; 0412 }; 0413 0414 #endif // deprecated since 5.65 0415 0416 #endif // KTCPSOCKET_H