KDECore
ktcpsocket.h
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2007 Thiago Macieira <thiago@kde.org> 00003 Copyright (C) 2007 Andreas Hartmetz <ahartmetz@gmail.com> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to 00017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00018 Boston, MA 02110-1301, USA. 00019 */ 00020 00021 #ifndef KTCPSOCKET_H 00022 #define KTCPSOCKET_H 00023 00024 #include <QtNetwork/QSslSocket> 00025 //#include <QtCore/QRegExp> 00026 00027 #include "kdecore_export.h" 00028 00029 /* 00030 Notes on QCA::TLS compatibility 00031 In order to check for all validation problems as far as possible we need to use: 00032 Validity QCA::TLS::peerCertificateValidity() 00033 TLS::IdentityResult QCA::TLS::peerIdentityResult() 00034 CertificateChain QCA::TLS::peerCertificateChain().validate() - to find the failing cert! 00035 TLS::Error QCA::TLS::errorCode() - for more generic (but stil SSL) errors 00036 */ 00037 00038 00039 class KSslKeyPrivate; 00040 00041 class KDECORE_EXPORT KSslKey { 00042 public: 00043 enum Algorithm { 00044 Rsa = 0, 00045 Dsa, 00046 Dh 00047 }; 00048 enum KeySecrecy { 00049 PublicKey, 00050 PrivateKey 00051 }; 00052 00053 KSslKey(); 00054 KSslKey(const KSslKey &other); 00055 KSslKey(const QSslKey &sslKey); 00056 ~KSslKey(); 00057 KSslKey &operator=(const KSslKey &other); 00058 00059 Algorithm algorithm() const; 00060 bool isExportable() const; 00061 KeySecrecy secrecy() const; 00062 QByteArray toDer() const; 00063 private: 00064 KSslKeyPrivate *const d; 00065 }; 00066 00067 00068 class KSslCipherPrivate; 00069 00070 class KDECORE_EXPORT KSslCipher { 00071 public: 00072 KSslCipher(); 00073 KSslCipher(const KSslCipher &other); 00074 KSslCipher(const QSslCipher &); 00075 ~KSslCipher(); 00076 KSslCipher &operator=(const KSslCipher &other); 00077 00078 bool isNull() const; 00079 QString authenticationMethod() const; 00080 QString encryptionMethod() const; 00081 QString keyExchangeMethod() const; 00082 QString digestMethod() const; 00083 /* mainly for internal use */ 00084 QString name() const; 00085 int supportedBits() const; 00086 int usedBits() const; 00087 00088 static QList<KSslCipher> supportedCiphers(); 00089 00090 private: 00091 KSslCipherPrivate *const d; 00092 }; 00093 00094 00095 class KSslErrorPrivate; 00096 class KTcpSocket; 00097 00098 class KDECORE_EXPORT KSslError 00099 { 00100 public: 00101 enum Error { 00102 NoError = 0, 00103 UnknownError, 00104 InvalidCertificateAuthorityCertificate, 00105 InvalidCertificate, 00106 CertificateSignatureFailed, 00107 SelfSignedCertificate, 00108 ExpiredCertificate, 00109 RevokedCertificate, 00110 InvalidCertificatePurpose, 00111 RejectedCertificate, 00112 UntrustedCertificate, 00113 NoPeerCertificate, 00114 HostNameMismatch, 00115 PathLengthExceeded 00116 }; 00117 KSslError(KSslError::Error error = NoError, const QSslCertificate &cert = QSslCertificate()); 00118 KSslError(const QSslError &error); //### explicit yes or no? 00119 KSslError(const KSslError &other); 00120 ~KSslError(); 00121 KSslError &operator=(const KSslError &other); 00122 00123 Error error() const; 00124 QString errorString() const; 00125 QSslCertificate certificate() const; 00126 private: 00127 KSslErrorPrivate *const d; 00128 }; 00129 00130 00131 //consider killing more convenience functions with huge signatures 00132 //### do we need setSession() / session() ? 00133 00134 //BIG FAT TODO: do we keep openMode() up to date everywhere it can change? 00135 00136 //other TODO: limit possible error strings?, SSL key stuff 00137 00138 //TODO protocol (or maybe even application?) dependent automatic proxy choice 00139 00140 class KTcpSocketPrivate; 00141 class QHostAddress; 00142 class KUrl; 00143 00144 class KDECORE_EXPORT KTcpSocket: public QIODevice 00145 { 00146 Q_OBJECT 00147 public: 00148 enum State { 00149 UnconnectedState = 0, 00150 HostLookupState, 00151 ConnectingState, 00152 ConnectedState, 00153 BoundState, 00154 ListeningState, 00155 ClosingState 00156 //hmmm, do we need an SslNegotiatingState? 00157 }; 00158 enum SslVersion { 00159 UnknownSslVersion = 0x01, 00160 SslV2 = 0x02, 00161 SslV3 = 0x04, 00162 TlsV1 = 0x08, 00163 SslV3_1 = 0x08, 00164 AnySslVersion = SslV2 | SslV3 | TlsV1 00165 }; 00166 Q_DECLARE_FLAGS(SslVersions, SslVersion) 00167 enum Error { 00168 UnknownError = 0, 00169 ConnectionRefusedError, 00170 RemoteHostClosedError, 00171 HostNotFoundError, 00172 SocketAccessError, 00173 SocketResourceError, 00174 SocketTimeoutError, 00175 NetworkError, 00176 UnsupportedSocketOperationError 00177 }; 00178 /* 00179 The following is based on reading the OpenSSL interface code of both QSslSocket 00180 and QCA::TLS. Barring oversights it should be accurate. The two cases with the 00181 question marks apparently will never be emitted by QSslSocket so there is nothing 00182 to compare. 00183 00184 QSslError::NoError KTcpSocket::NoError 00185 QSslError::UnableToGetIssuerCertificate QCA::ErrorSignatureFailed 00186 QSslError::UnableToDecryptCertificateSignature QCA::ErrorSignatureFailed 00187 QSslError::UnableToDecodeIssuerPublicKey QCA::ErrorInvalidCA 00188 QSslError::CertificateSignatureFailed QCA::ErrorSignatureFailed 00189 QSslError::CertificateNotYetValid QCA::ErrorExpired 00190 QSslError::CertificateExpired QCA::ErrorExpired 00191 QSslError::InvalidNotBeforeField QCA::ErrorExpired 00192 QSslError::InvalidNotAfterField QCA::ErrorExpired 00193 QSslError::SelfSignedCertificate QCA::ErrorSelfSigned 00194 QSslError::SelfSignedCertificateInChain QCA::ErrorSelfSigned 00195 QSslError::UnableToGetLocalIssuerCertificate QCA::ErrorInvalidCA 00196 QSslError::UnableToVerifyFirstCertificate QCA::ErrorSignatureFailed 00197 QSslError::CertificateRevoked QCA::ErrorRevoked 00198 QSslError::InvalidCaCertificate QCA::ErrorInvalidCA 00199 QSslError::PathLengthExceeded QCA::ErrorPathLengthExceeded 00200 QSslError::InvalidPurpose QCA::ErrorInvalidPurpose 00201 QSslError::CertificateUntrusted QCA::ErrorUntrusted 00202 QSslError::CertificateRejected QCA::ErrorRejected 00203 QSslError::SubjectIssuerMismatch QCA::TLS::InvalidCertificate ? 00204 QSslError::AuthorityIssuerSerialNumberMismatch QCA::TLS::InvalidCertificate ? 00205 QSslError::NoPeerCertificate QCA::TLS::NoCertificate 00206 QSslError::HostNameMismatch QCA::TLS::HostMismatch 00207 QSslError::UnspecifiedError KTcpSocket::UnknownError 00208 QSslError::NoSslSupport Never happens :) 00209 */ 00210 enum EncryptionMode { 00211 UnencryptedMode = 0, 00212 SslClientMode, 00213 SslServerMode //### not implemented 00214 }; 00215 enum ProxyPolicy { 00217 AutoProxy = 0, 00219 ManualProxy 00220 }; 00221 00222 KTcpSocket(QObject *parent = 0); 00223 ~KTcpSocket(); 00224 00225 //from QIODevice 00226 //reimplemented virtuals - the ones not reimplemented are OK for us 00227 virtual bool atEnd() const; 00228 virtual qint64 bytesAvailable() const; 00229 virtual qint64 bytesToWrite() const; 00230 virtual bool canReadLine() const; 00231 virtual void close(); 00232 virtual bool isSequential() const; 00233 virtual bool open(QIODevice::OpenMode open); 00234 virtual bool waitForBytesWritten(int msecs); 00235 //### Document that this actually tries to read *more* data 00236 virtual bool waitForReadyRead(int msecs = 30000); 00237 protected: 00238 virtual qint64 readData (char *data, qint64 maxSize); 00239 virtual qint64 writeData (const char *data, qint64 maxSize); 00240 public: 00241 //from QAbstractSocket 00242 void abort(); 00243 void connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy = AutoProxy); 00244 void connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy = AutoProxy); 00245 00252 void connectToHost(const KUrl &url, ProxyPolicy policy = AutoProxy); 00253 void disconnectFromHost(); 00254 Error error() const; //### QAbstractSocket's model is strange. error() should be related to the 00255 //current state and *NOT* just report the last error if there was one. 00256 QList<KSslError> sslErrors() const; //### the errors returned can only have a subset of all 00257 //possible QSslError::SslError enum values depending on backend 00258 bool flush(); 00259 bool isValid() const; 00260 QHostAddress localAddress() const; 00261 QHostAddress peerAddress() const; 00262 QString peerName() const; 00263 quint16 peerPort() const; 00264 00265 #ifndef QT_NO_NETWORKPROXY 00266 00269 QNetworkProxy proxy() const; 00270 #endif 00271 qint64 readBufferSize() const; //probably hard to implement correctly 00272 00273 #ifndef QT_NO_NETWORKPROXY 00274 00277 void setProxy(const QNetworkProxy &proxy); //people actually seem to need it 00278 #endif 00279 void setReadBufferSize(qint64 size); 00280 State state() const; 00281 bool waitForConnected(int msecs = 30000); 00282 bool waitForDisconnected(int msecs = 30000); 00283 00284 //from QSslSocket 00285 void addCaCertificate(const QSslCertificate &certificate); 00286 // bool addCaCertificates(const QString &path, QSsl::EncodingFormat format = QSsl::Pem, 00287 // QRegExp::PatternSyntax syntax = QRegExp::FixedString); 00288 void addCaCertificates(const QList<QSslCertificate> &certificates); 00289 QList<QSslCertificate> caCertificates() const; 00290 QList<KSslCipher> ciphers() const; 00291 void connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode = ReadWrite); 00292 // bool isEncrypted() const { return encryptionMode() != UnencryptedMode } 00293 QSslCertificate localCertificate() const; 00294 QList<QSslCertificate> peerCertificateChain() const; 00295 KSslKey privateKey() const; 00296 KSslCipher sessionCipher() const; 00297 void setCaCertificates(const QList<QSslCertificate> &certificates); 00298 void setCiphers(const QList<KSslCipher> &ciphers); 00299 //### void setCiphers(const QString &ciphers); //what about i18n? 00300 void setLocalCertificate(const QSslCertificate &certificate); 00301 void setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format = QSsl::Pem); 00302 void setPrivateKey(const KSslKey &key); //implement 00303 void setPrivateKey(const QString &fileName, KSslKey::Algorithm algorithm = KSslKey::Rsa, 00304 QSsl::EncodingFormat format = QSsl::Pem, 00305 const QByteArray &passPhrase = QByteArray()); //TODO 00306 void setAdvertisedSslVersion(SslVersion version); 00307 SslVersion advertisedSslVersion() const; //always equal to last setSslAdvertisedVersion 00308 SslVersion negotiatedSslVersion() const; //negotiated version; downgrades are possible. 00309 QString negotiatedSslVersionName() const; 00310 bool waitForEncrypted(int msecs = 30000); 00311 00312 EncryptionMode encryptionMode() const; 00313 00321 QVariant socketOption(QAbstractSocket::SocketOption options) const; 00322 00330 void setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value); 00331 00332 Q_SIGNALS: 00333 //from QAbstractSocket 00334 void connected(); 00335 void disconnected(); 00336 void error(KTcpSocket::Error); 00337 void hostFound(); 00338 #ifndef QT_NO_NETWORKPROXY 00339 void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *authenticator); 00340 #endif 00341 // only for raw socket state, SSL is separate 00342 void stateChanged(KTcpSocket::State); 00343 00344 //from QSslSocket 00345 void encrypted(); 00346 void encryptionModeChanged(EncryptionMode); 00347 void sslErrors(const QList<KSslError> &errors); 00348 00349 public Q_SLOTS: 00350 void ignoreSslErrors(); 00351 void startClientEncryption(); 00352 // void startServerEncryption(); //not implemented 00353 private: 00354 Q_PRIVATE_SLOT(d, void reemitReadyRead()) 00355 Q_PRIVATE_SLOT(d, void reemitSocketError(QAbstractSocket::SocketError)) 00356 Q_PRIVATE_SLOT(d, void reemitSslErrors(const QList<QSslError> &)) 00357 Q_PRIVATE_SLOT(d, void reemitStateChanged(QAbstractSocket::SocketState)) 00358 Q_PRIVATE_SLOT(d, void reemitModeChanged(QSslSocket::SslMode)) 00359 00360 //debugging H4X 00361 void showSslErrors(); 00362 00363 friend class KTcpSocketPrivate; 00364 KTcpSocketPrivate *const d; 00365 }; 00366 00367 00375 class KDECORE_EXPORT KSslErrorUiData 00376 { 00377 public: 00381 KSslErrorUiData(); 00385 KSslErrorUiData(const KTcpSocket *socket); 00386 KSslErrorUiData(const KSslErrorUiData &other); 00387 KSslErrorUiData &operator=(const KSslErrorUiData &); 00388 class Private; 00389 private: 00390 friend class Private; 00391 Private *const d; 00392 }; 00393 00394 00395 #endif // KTCPSOCKET_H
KDE 4.6 API Reference