File indexing completed on 2024-04-28 15:26:29

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