KDECore
ktcpsocket.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2007, 2008 Andreas Hartmetz <ahartmetz@gmail.com> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "ktcpsocket.h" 00021 #include "ktcpsocket_p.h" 00022 00023 #include <kdebug.h> 00024 #include <kurl.h> 00025 #include <kglobal.h> 00026 #include <ksslcertificatemanager.h> 00027 #include <kstandarddirs.h> 00028 #include <klocale.h> 00029 00030 #include <QtCore/QStringList> 00031 #include <QtNetwork/QSslKey> 00032 #include <QtNetwork/QSslCipher> 00033 #include <QtNetwork/QHostAddress> 00034 #include <QtNetwork/QNetworkProxy> 00035 00036 static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol protocol) 00037 { 00038 switch (protocol) { 00039 case QSsl::SslV2: 00040 return KTcpSocket::SslV2; 00041 case QSsl::SslV3: 00042 return KTcpSocket::SslV3; 00043 case QSsl::TlsV1: 00044 return KTcpSocket::TlsV1; 00045 case QSsl::AnyProtocol: 00046 return KTcpSocket::AnySslVersion; 00047 #if QT_VERSION >= 0x040800 00048 case QSsl::TlsV1SslV3: 00049 return KTcpSocket::TlsV1SslV3; 00050 case QSsl::SecureProtocols: 00051 return KTcpSocket::SecureProtocols; 00052 #endif 00053 default: 00054 return KTcpSocket::UnknownSslVersion; 00055 } 00056 } 00057 00058 00059 static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion sslVersion) 00060 { 00061 //### this lowlevel bit-banging is a little dangerous and a likely source of bugs 00062 if (sslVersion == KTcpSocket::AnySslVersion) { 00063 return QSsl::AnyProtocol; 00064 } 00065 //does it contain any valid protocol? 00066 KTcpSocket::SslVersions validVersions (KTcpSocket::SslV2 | KTcpSocket::SslV3 | KTcpSocket::TlsV1); 00067 #if QT_VERSION >= 0x040800 00068 validVersions |= KTcpSocket::TlsV1SslV3; 00069 validVersions |= KTcpSocket::SecureProtocols; 00070 #endif 00071 if (!(sslVersion & validVersions)) { 00072 return QSsl::UnknownProtocol; 00073 } 00074 00075 switch (sslVersion) { 00076 case KTcpSocket::SslV2: 00077 return QSsl::SslV2; 00078 case KTcpSocket::SslV3: 00079 return QSsl::SslV3; 00080 case KTcpSocket::TlsV1: 00081 return QSsl::TlsV1; 00082 #if QT_VERSION >= 0x040800 00083 case KTcpSocket::TlsV1SslV3: 00084 return QSsl::TlsV1SslV3; 00085 case KTcpSocket::SecureProtocols: 00086 return QSsl::SecureProtocols; 00087 #endif 00088 00089 default: 00090 //QSslSocket doesn't really take arbitrary combinations. It's one or all. 00091 return QSsl::AnyProtocol; 00092 } 00093 } 00094 00095 00096 //cipher class converter KSslCipher -> QSslCipher 00097 class CipherCc 00098 { 00099 public: 00100 CipherCc() 00101 { 00102 foreach (const QSslCipher &c, QSslSocket::supportedCiphers()) { 00103 allCiphers.insert(c.name(), c); 00104 } 00105 } 00106 00107 QSslCipher converted(const KSslCipher &ksc) 00108 { 00109 return allCiphers.value(ksc.name()); 00110 } 00111 00112 private: 00113 QHash<QString, QSslCipher> allCiphers; 00114 }; 00115 00116 00117 class KSslErrorPrivate 00118 { 00119 public: 00120 static KSslError::Error errorFromQSslError(QSslError::SslError e) 00121 { 00122 switch (e) { 00123 case QSslError::NoError: 00124 return KSslError::NoError; 00125 case QSslError::UnableToGetLocalIssuerCertificate: 00126 case QSslError::InvalidCaCertificate: 00127 return KSslError::InvalidCertificateAuthorityCertificate; 00128 case QSslError::InvalidNotBeforeField: 00129 case QSslError::InvalidNotAfterField: 00130 case QSslError::CertificateNotYetValid: 00131 case QSslError::CertificateExpired: 00132 return KSslError::ExpiredCertificate; 00133 case QSslError::UnableToDecodeIssuerPublicKey: 00134 case QSslError::SubjectIssuerMismatch: 00135 case QSslError::AuthorityIssuerSerialNumberMismatch: 00136 return KSslError::InvalidCertificate; 00137 case QSslError::SelfSignedCertificate: 00138 case QSslError::SelfSignedCertificateInChain: 00139 return KSslError::SelfSignedCertificate; 00140 case QSslError::CertificateRevoked: 00141 return KSslError::RevokedCertificate; 00142 case QSslError::InvalidPurpose: 00143 return KSslError::InvalidCertificatePurpose; 00144 case QSslError::CertificateUntrusted: 00145 return KSslError::UntrustedCertificate; 00146 case QSslError::CertificateRejected: 00147 return KSslError::RejectedCertificate; 00148 case QSslError::NoPeerCertificate: 00149 return KSslError::NoPeerCertificate; 00150 case QSslError::HostNameMismatch: 00151 return KSslError::HostNameMismatch; 00152 case QSslError::UnableToVerifyFirstCertificate: 00153 case QSslError::UnableToDecryptCertificateSignature: 00154 case QSslError::UnableToGetIssuerCertificate: 00155 case QSslError::CertificateSignatureFailed: 00156 return KSslError::CertificateSignatureFailed; 00157 case QSslError::PathLengthExceeded: 00158 return KSslError::PathLengthExceeded; 00159 case QSslError::UnspecifiedError: 00160 case QSslError::NoSslSupport: 00161 default: 00162 return KSslError::UnknownError; 00163 } 00164 } 00165 00166 static QString errorString(KSslError::Error e) 00167 { 00168 switch (e) { 00169 case KSslError::NoError: 00170 return i18nc("SSL error","No error"); 00171 case KSslError::InvalidCertificateAuthorityCertificate: 00172 return i18nc("SSL error","The certificate authority's certificate is invalid"); 00173 case KSslError::ExpiredCertificate: 00174 return i18nc("SSL error","The certificate has expired"); 00175 case KSslError::InvalidCertificate: 00176 return i18nc("SSL error","The certificate is invalid"); 00177 case KSslError::SelfSignedCertificate: 00178 return i18nc("SSL error","The certificate is not signed by any trusted certificate authority"); 00179 case KSslError::RevokedCertificate: 00180 return i18nc("SSL error","The certificate has been revoked"); 00181 case KSslError::InvalidCertificatePurpose: 00182 return i18nc("SSL error","The certificate is unsuitable for this purpose"); 00183 case KSslError::UntrustedCertificate: 00184 return i18nc("SSL error","The root certificate authority's certificate is not trusted for this purpose"); 00185 case KSslError::RejectedCertificate: 00186 return i18nc("SSL error","The certificate authority's certificate is marked to reject this certificate's purpose"); 00187 case KSslError::NoPeerCertificate: 00188 return i18nc("SSL error","The peer did not present any certificate"); 00189 case KSslError::HostNameMismatch: 00190 return i18nc("SSL error","The certificate does not apply to the given host"); 00191 case KSslError::CertificateSignatureFailed: 00192 return i18nc("SSL error","The certificate cannot be verified for internal reasons"); 00193 case KSslError::PathLengthExceeded: 00194 return i18nc("SSL error","The certificate chain is too long"); 00195 case KSslError::UnknownError: 00196 default: 00197 return i18nc("SSL error","Unknown error"); 00198 } 00199 } 00200 00201 KSslError::Error error; 00202 QSslCertificate certificate; 00203 }; 00204 00205 00206 KSslError::KSslError(Error errorCode, const QSslCertificate &certificate) 00207 : d(new KSslErrorPrivate()) 00208 { 00209 d->error = errorCode; 00210 d->certificate = certificate; 00211 } 00212 00213 00214 KSslError::KSslError(const QSslError &other) 00215 : d(new KSslErrorPrivate()) 00216 { 00217 d->error = KSslErrorPrivate::errorFromQSslError(other.error()); 00218 d->certificate = other.certificate(); 00219 } 00220 00221 00222 KSslError::KSslError(const KSslError &other) 00223 : d(new KSslErrorPrivate()) 00224 { 00225 *d = *other.d; 00226 } 00227 00228 00229 KSslError::~KSslError() 00230 { 00231 delete d; 00232 } 00233 00234 00235 KSslError &KSslError::operator=(const KSslError &other) 00236 { 00237 *d = *other.d; 00238 return *this; 00239 } 00240 00241 00242 KSslError::Error KSslError::error() const 00243 { 00244 return d->error; 00245 } 00246 00247 00248 QString KSslError::errorString() const 00249 { 00250 return KSslErrorPrivate::errorString(d->error); 00251 } 00252 00253 00254 QSslCertificate KSslError::certificate() const 00255 { 00256 return d->certificate; 00257 } 00258 00259 00260 class KTcpSocketPrivate 00261 { 00262 public: 00263 KTcpSocketPrivate(KTcpSocket *qq) 00264 : q(qq), 00265 certificatesLoaded(false), 00266 emittedReadyRead(false) 00267 { 00268 // create the instance, which sets Qt's static internal cert set to empty. 00269 KSslCertificateManager::self(); 00270 } 00271 00272 KTcpSocket::State state(QAbstractSocket::SocketState s) 00273 { 00274 switch (s) { 00275 case QAbstractSocket::UnconnectedState: 00276 return KTcpSocket::UnconnectedState; 00277 case QAbstractSocket::HostLookupState: 00278 return KTcpSocket::HostLookupState; 00279 case QAbstractSocket::ConnectingState: 00280 return KTcpSocket::ConnectingState; 00281 case QAbstractSocket::ConnectedState: 00282 return KTcpSocket::ConnectedState; 00283 case QAbstractSocket::ClosingState: 00284 return KTcpSocket::ClosingState; 00285 case QAbstractSocket::BoundState: 00286 case QAbstractSocket::ListeningState: 00287 //### these two are not relevant as long as this can't be a server socket 00288 default: 00289 return KTcpSocket::UnconnectedState; //the closest to "error" 00290 } 00291 } 00292 00293 KTcpSocket::EncryptionMode encryptionMode(QSslSocket::SslMode mode) 00294 { 00295 switch (mode) { 00296 case QSslSocket::SslClientMode: 00297 return KTcpSocket::SslClientMode; 00298 case QSslSocket::SslServerMode: 00299 return KTcpSocket::SslServerMode; 00300 default: 00301 return KTcpSocket::UnencryptedMode; 00302 } 00303 } 00304 00305 KTcpSocket::Error errorFromAbsSocket(QAbstractSocket::SocketError e) 00306 { 00307 switch (e) { 00308 case QAbstractSocket::ConnectionRefusedError: 00309 return KTcpSocket::ConnectionRefusedError; 00310 case QAbstractSocket::RemoteHostClosedError: 00311 return KTcpSocket::RemoteHostClosedError; 00312 case QAbstractSocket::HostNotFoundError: 00313 return KTcpSocket::HostNotFoundError; 00314 case QAbstractSocket::SocketAccessError: 00315 return KTcpSocket::SocketAccessError; 00316 case QAbstractSocket::SocketResourceError: 00317 return KTcpSocket::SocketResourceError; 00318 case QAbstractSocket::SocketTimeoutError: 00319 return KTcpSocket::SocketTimeoutError; 00320 case QAbstractSocket::NetworkError: 00321 return KTcpSocket::NetworkError; 00322 case QAbstractSocket::UnsupportedSocketOperationError: 00323 return KTcpSocket::UnsupportedSocketOperationError; 00324 case QAbstractSocket::DatagramTooLargeError: 00325 //we don't do UDP 00326 case QAbstractSocket::AddressInUseError: 00327 case QAbstractSocket::SocketAddressNotAvailableError: 00328 //### own values if/when we ever get server socket support 00329 case QAbstractSocket::ProxyAuthenticationRequiredError: 00330 //### maybe we need an enum value for this 00331 case QAbstractSocket::UnknownSocketError: 00332 default: 00333 return KTcpSocket::UnknownError; 00334 } 00335 } 00336 00337 //private slots 00338 void reemitSocketError(QAbstractSocket::SocketError e) 00339 { 00340 emit q->error(errorFromAbsSocket(e)); 00341 } 00342 00343 void reemitSslErrors(const QList<QSslError> &errors) 00344 { 00345 q->showSslErrors(); //H4X 00346 QList<KSslError> kErrors; 00347 foreach (const QSslError &e, errors) { 00348 kErrors.append(KSslError(e)); 00349 } 00350 emit q->sslErrors(kErrors); 00351 } 00352 00353 void reemitStateChanged(QAbstractSocket::SocketState s) 00354 { 00355 emit q->stateChanged(state(s)); 00356 } 00357 00358 void reemitModeChanged(QSslSocket::SslMode m) 00359 { 00360 emit q->encryptionModeChanged(encryptionMode(m)); 00361 } 00362 00363 // This method is needed because we might emit readyRead() due to this QIODevice 00364 // having some data buffered, so we need to care about blocking, too. 00365 //### useless ATM as readyRead() now just calls d->sock.readyRead(). 00366 void reemitReadyRead() 00367 { 00368 if (!emittedReadyRead) { 00369 emittedReadyRead = true; 00370 emit q->readyRead(); 00371 emittedReadyRead = false; 00372 } 00373 } 00374 00375 void maybeLoadCertificates() 00376 { 00377 if (!certificatesLoaded) { 00378 sock.setCaCertificates(KSslCertificateManager::self()->caCertificates()); 00379 certificatesLoaded = true; 00380 } 00381 } 00382 00383 KTcpSocket *const q; 00384 bool certificatesLoaded; 00385 bool emittedReadyRead; 00386 QSslSocket sock; 00387 QList<KSslCipher> ciphers; 00388 KTcpSocket::SslVersion advertisedSslVersion; 00389 CipherCc ccc; 00390 }; 00391 00392 00393 KTcpSocket::KTcpSocket(QObject *parent) 00394 : QIODevice(parent), 00395 d(new KTcpSocketPrivate(this)) 00396 { 00397 d->advertisedSslVersion = SslV3; 00398 00399 connect(&d->sock, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose())); 00400 connect(&d->sock, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64))); 00401 connect(&d->sock, SIGNAL(encryptedBytesWritten(qint64)), this, SIGNAL(encryptedBytesWritten(qint64))); 00402 connect(&d->sock, SIGNAL(readyRead()), this, SLOT(reemitReadyRead())); 00403 connect(&d->sock, SIGNAL(connected()), this, SIGNAL(connected())); 00404 connect(&d->sock, SIGNAL(encrypted()), this, SIGNAL(encrypted())); 00405 connect(&d->sock, SIGNAL(disconnected()), this, SIGNAL(disconnected())); 00406 #ifndef QT_NO_NETWORKPROXY 00407 connect(&d->sock, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)), 00408 this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*))); 00409 #endif 00410 connect(&d->sock, SIGNAL(error(QAbstractSocket::SocketError)), 00411 this, SLOT(reemitSocketError(QAbstractSocket::SocketError))); 00412 connect(&d->sock, SIGNAL(sslErrors(QList<QSslError>)), 00413 this, SLOT(reemitSslErrors(QList<QSslError>))); 00414 connect(&d->sock, SIGNAL(hostFound()), this, SIGNAL(hostFound())); 00415 connect(&d->sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)), 00416 this, SLOT(reemitStateChanged(QAbstractSocket::SocketState))); 00417 connect(&d->sock, SIGNAL(modeChanged(QSslSocket::SslMode)), 00418 this, SLOT(reemitModeChanged(QSslSocket::SslMode))); 00419 } 00420 00421 00422 KTcpSocket::~KTcpSocket() 00423 { 00424 delete d; 00425 } 00426 00428 00429 bool KTcpSocket::atEnd() const 00430 { 00431 return d->sock.atEnd() && QIODevice::atEnd(); 00432 } 00433 00434 00435 qint64 KTcpSocket::bytesAvailable() const 00436 { 00437 return d->sock.bytesAvailable() + QIODevice::bytesAvailable(); 00438 } 00439 00440 00441 qint64 KTcpSocket::bytesToWrite() const 00442 { 00443 return d->sock.bytesToWrite(); 00444 } 00445 00446 00447 bool KTcpSocket::canReadLine() const 00448 { 00449 return d->sock.canReadLine() || QIODevice::canReadLine(); 00450 } 00451 00452 00453 void KTcpSocket::close() 00454 { 00455 d->sock.close(); 00456 QIODevice::close(); 00457 } 00458 00459 00460 bool KTcpSocket::isSequential() const 00461 { 00462 return true; 00463 } 00464 00465 00466 bool KTcpSocket::open(QIODevice::OpenMode open) 00467 { 00468 bool ret = d->sock.open(open); 00469 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00470 return ret; 00471 } 00472 00473 00474 bool KTcpSocket::waitForBytesWritten(int msecs) 00475 { 00476 return d->sock.waitForBytesWritten(msecs); 00477 } 00478 00479 00480 bool KTcpSocket::waitForReadyRead(int msecs) 00481 { 00482 return d->sock.waitForReadyRead(msecs); 00483 } 00484 00485 00486 qint64 KTcpSocket::readData(char *data, qint64 maxSize) 00487 { 00488 return d->sock.read(data, maxSize); 00489 } 00490 00491 00492 qint64 KTcpSocket::writeData(const char *data, qint64 maxSize) 00493 { 00494 return d->sock.write(data, maxSize); 00495 } 00496 00498 00499 void KTcpSocket::abort() 00500 { 00501 d->sock.abort(); 00502 } 00503 00504 00505 void KTcpSocket::connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy) 00506 { 00507 if (policy == AutoProxy) { 00508 //### 00509 } 00510 d->sock.connectToHost(hostName, port); 00511 // there are enough layers of buffers between us and the network, and there is a quirk 00512 // in QIODevice that can make it try to readData() twice per read() call if buffered and 00513 // reaData() does not deliver enough data the first time. like when the other side is 00514 // simply not sending any more data... 00515 // this can *apparently* lead to long delays sometimes which stalls applications. 00516 // do not want. 00517 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00518 } 00519 00520 00521 void KTcpSocket::connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy) 00522 { 00523 if (policy == AutoProxy) { 00524 //### 00525 } 00526 d->sock.connectToHost(hostAddress, port); 00527 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00528 } 00529 00530 00531 void KTcpSocket::connectToHost(const KUrl &url, ProxyPolicy policy) 00532 { 00533 if (policy == AutoProxy) { 00534 //### 00535 } 00536 d->sock.connectToHost(url.host(), url.port()); 00537 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00538 } 00539 00540 00541 void KTcpSocket::disconnectFromHost() 00542 { 00543 d->sock.disconnectFromHost(); 00544 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00545 } 00546 00547 00548 KTcpSocket::Error KTcpSocket::error() const 00549 { 00550 return d->errorFromAbsSocket(d->sock.error()); 00551 } 00552 00553 00554 QList<KSslError> KTcpSocket::sslErrors() const 00555 { 00556 //### pretty slow; also consider throwing out duplicate error codes. We may get 00557 // duplicates even though there were none in the original list because KSslError 00558 // has a smallest common denominator range of SSL error codes. 00559 QList<KSslError> ret; 00560 foreach (const QSslError &e, d->sock.sslErrors()) 00561 ret.append(KSslError(e)); 00562 return ret; 00563 } 00564 00565 00566 bool KTcpSocket::flush() 00567 { 00568 return d->sock.flush(); 00569 } 00570 00571 00572 bool KTcpSocket::isValid() const 00573 { 00574 return d->sock.isValid(); 00575 } 00576 00577 00578 QHostAddress KTcpSocket::localAddress() const 00579 { 00580 return d->sock.localAddress(); 00581 } 00582 00583 00584 QHostAddress KTcpSocket::peerAddress() const 00585 { 00586 return d->sock.peerAddress(); 00587 } 00588 00589 00590 QString KTcpSocket::peerName() const 00591 { 00592 return d->sock.peerName(); 00593 } 00594 00595 00596 quint16 KTcpSocket::peerPort() const 00597 { 00598 return d->sock.peerPort(); 00599 } 00600 00601 00602 #ifndef QT_NO_NETWORKPROXY 00603 QNetworkProxy KTcpSocket::proxy() const 00604 { 00605 return d->sock.proxy(); 00606 } 00607 #endif 00608 00609 qint64 KTcpSocket::readBufferSize() const 00610 { 00611 return d->sock.readBufferSize(); 00612 } 00613 00614 00615 #ifndef QT_NO_NETWORKPROXY 00616 void KTcpSocket::setProxy(const QNetworkProxy &proxy) 00617 { 00618 d->sock.setProxy(proxy); 00619 } 00620 #endif 00621 00622 void KTcpSocket::setReadBufferSize(qint64 size) 00623 { 00624 d->sock.setReadBufferSize(size); 00625 } 00626 00627 00628 KTcpSocket::State KTcpSocket::state() const 00629 { 00630 return d->state(d->sock.state()); 00631 } 00632 00633 00634 bool KTcpSocket::waitForConnected(int msecs) 00635 { 00636 bool ret = d->sock.waitForConnected(msecs); 00637 if (!ret) 00638 setErrorString(d->sock.errorString()); 00639 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00640 return ret; 00641 } 00642 00643 00644 bool KTcpSocket::waitForDisconnected(int msecs) 00645 { 00646 bool ret = d->sock.waitForDisconnected(msecs); 00647 if (!ret) 00648 setErrorString(d->sock.errorString()); 00649 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00650 return ret; 00651 } 00652 00654 00655 void KTcpSocket::addCaCertificate(const QSslCertificate &certificate) 00656 { 00657 d->maybeLoadCertificates(); 00658 d->sock.addCaCertificate(certificate); 00659 } 00660 00661 00662 /* 00663 bool KTcpSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat format, 00664 QRegExp::PatternSyntax syntax) 00665 { 00666 d->maybeLoadCertificates(); 00667 return d->sock.addCaCertificates(path, format, syntax); 00668 } 00669 */ 00670 00671 00672 void KTcpSocket::addCaCertificates(const QList<QSslCertificate> &certificates) 00673 { 00674 d->maybeLoadCertificates(); 00675 d->sock.addCaCertificates(certificates); 00676 } 00677 00678 00679 QList<QSslCertificate> KTcpSocket::caCertificates() const 00680 { 00681 d->maybeLoadCertificates(); 00682 return d->sock.caCertificates(); 00683 } 00684 00685 00686 QList<KSslCipher> KTcpSocket::ciphers() const 00687 { 00688 return d->ciphers; 00689 } 00690 00691 00692 void KTcpSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode) 00693 { 00694 d->maybeLoadCertificates(); 00695 d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion)); 00696 d->sock.connectToHostEncrypted(hostName, port, openMode); 00697 setOpenMode(d->sock.openMode() | QIODevice::Unbuffered); 00698 } 00699 00700 00701 QSslCertificate KTcpSocket::localCertificate() const 00702 { 00703 return d->sock.localCertificate(); 00704 } 00705 00706 00707 QList<QSslCertificate> KTcpSocket::peerCertificateChain() const 00708 { 00709 return d->sock.peerCertificateChain(); 00710 } 00711 00712 00713 KSslKey KTcpSocket::privateKey() const 00714 { 00715 return KSslKey(d->sock.privateKey()); 00716 } 00717 00718 00719 KSslCipher KTcpSocket::sessionCipher() const 00720 { 00721 return KSslCipher(d->sock.sessionCipher()); 00722 } 00723 00724 00725 void KTcpSocket::setCaCertificates(const QList<QSslCertificate> &certificates) 00726 { 00727 d->sock.setCaCertificates(certificates); 00728 d->certificatesLoaded = true; 00729 } 00730 00731 00732 void KTcpSocket::setCiphers(const QList<KSslCipher> &ciphers) 00733 { 00734 d->ciphers = ciphers; 00735 QList<QSslCipher> cl; 00736 foreach (const KSslCipher &c, d->ciphers) { 00737 cl.append(d->ccc.converted(c)); 00738 } 00739 d->sock.setCiphers(cl); 00740 } 00741 00742 00743 void KTcpSocket::setLocalCertificate(const QSslCertificate &certificate) 00744 { 00745 d->sock.setLocalCertificate(certificate); 00746 } 00747 00748 00749 void KTcpSocket::setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format) 00750 { 00751 d->sock.setLocalCertificate(fileName, format); 00752 } 00753 00754 00755 void KTcpSocket::setVerificationPeerName(const QString& hostName) 00756 { 00757 #if QT_VERSION >= 0x040800 00758 d->sock.setPeerVerifyName(hostName); 00759 #else 00760 Q_UNUSED(hostName); 00761 #endif 00762 } 00763 00764 00765 void KTcpSocket::setPrivateKey(const KSslKey &key) 00766 { 00767 // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm. 00768 if (key.algorithm() == KSslKey::Dh) 00769 return; 00770 00771 QSslKey _key(key.toDer(), 00772 (key.algorithm() == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa, 00773 QSsl::Der, 00774 (key.secrecy() == KSslKey::PrivateKey) ? QSsl::PrivateKey : QSsl::PublicKey); 00775 00776 d->sock.setPrivateKey(_key); 00777 } 00778 00779 00780 void KTcpSocket::setPrivateKey(const QString &fileName, KSslKey::Algorithm algorithm, 00781 QSsl::EncodingFormat format, const QByteArray &passPhrase) 00782 { 00783 // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm. 00784 if (algorithm == KSslKey::Dh) 00785 return; 00786 00787 d->sock.setPrivateKey(fileName, 00788 (algorithm == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa, 00789 format, 00790 passPhrase); 00791 } 00792 00793 00794 bool KTcpSocket::waitForEncrypted(int msecs) 00795 { 00796 return d->sock.waitForEncrypted(msecs); 00797 } 00798 00799 00800 KTcpSocket::EncryptionMode KTcpSocket::encryptionMode() const 00801 { 00802 return d->encryptionMode(d->sock.mode()); 00803 } 00804 00805 QVariant KTcpSocket::socketOption(QAbstractSocket::SocketOption options) const 00806 { 00807 return d->sock.socketOption(options); 00808 } 00809 00810 void KTcpSocket::setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value) 00811 { 00812 d->sock.setSocketOption(options, value); 00813 } 00814 00815 QSslConfiguration KTcpSocket::sslConfiguration() const 00816 { 00817 return d->sock.sslConfiguration(); 00818 } 00819 00820 void KTcpSocket::setSslConfiguration (const QSslConfiguration& configuration) 00821 { 00822 d->sock.setSslConfiguration(configuration); 00823 } 00824 00825 //slot 00826 void KTcpSocket::ignoreSslErrors() 00827 { 00828 d->sock.ignoreSslErrors(); 00829 } 00830 00831 00832 //slot 00833 void KTcpSocket::startClientEncryption() 00834 { 00835 d->maybeLoadCertificates(); 00836 d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion)); 00837 d->sock.startClientEncryption(); 00838 } 00839 00840 00841 //debugging H4X 00842 void KTcpSocket::showSslErrors() 00843 { 00844 foreach (const QSslError &e, d->sock.sslErrors()) 00845 kDebug(7029) << e.errorString(); 00846 } 00847 00848 00849 void KTcpSocket::setAdvertisedSslVersion(KTcpSocket::SslVersion version) 00850 { 00851 d->advertisedSslVersion = version; 00852 } 00853 00854 00855 KTcpSocket::SslVersion KTcpSocket::advertisedSslVersion() const 00856 { 00857 return d->advertisedSslVersion; 00858 } 00859 00860 00861 KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const 00862 { 00863 if (!d->sock.isEncrypted()) { 00864 return UnknownSslVersion; 00865 } 00866 return kSslVersionFromQ(d->sock.protocol()); 00867 } 00868 00869 00870 QString KTcpSocket::negotiatedSslVersionName() const 00871 { 00872 if (!d->sock.isEncrypted()) { 00873 return QString(); 00874 } 00875 return d->sock.sessionCipher().protocolString(); 00876 } 00877 00878 00880 00881 class KSslKeyPrivate 00882 { 00883 public: 00884 KSslKey::Algorithm convertAlgorithm(QSsl::KeyAlgorithm a) 00885 { 00886 switch(a) { 00887 case QSsl::Dsa: 00888 return KSslKey::Dsa; 00889 default: 00890 return KSslKey::Rsa; 00891 } 00892 } 00893 00894 KSslKey::Algorithm algorithm; 00895 KSslKey::KeySecrecy secrecy; 00896 bool isExportable; 00897 QByteArray der; 00898 }; 00899 00900 00901 KSslKey::KSslKey() 00902 : d(new KSslKeyPrivate) 00903 { 00904 d->algorithm = Rsa; 00905 d->secrecy = PublicKey; 00906 d->isExportable = true; 00907 } 00908 00909 00910 KSslKey::KSslKey(const KSslKey &other) 00911 : d(new KSslKeyPrivate) 00912 { 00913 *d = *other.d; 00914 } 00915 00916 00917 KSslKey::KSslKey(const QSslKey &qsk) 00918 : d(new KSslKeyPrivate) 00919 { 00920 d->algorithm = d->convertAlgorithm(qsk.algorithm()); 00921 d->secrecy = (qsk.type() == QSsl::PrivateKey) ? PrivateKey : PublicKey; 00922 d->isExportable = true; 00923 d->der = qsk.toDer(); 00924 } 00925 00926 00927 KSslKey::~KSslKey() 00928 { 00929 delete d; 00930 } 00931 00932 00933 KSslKey &KSslKey::operator=(const KSslKey &other) 00934 { 00935 *d = *other.d; 00936 return *this; 00937 } 00938 00939 00940 KSslKey::Algorithm KSslKey::algorithm() const 00941 { 00942 return d->algorithm; 00943 } 00944 00945 00946 bool KSslKey::isExportable() const 00947 { 00948 return d->isExportable; 00949 } 00950 00951 00952 KSslKey::KeySecrecy KSslKey::secrecy() const 00953 { 00954 return d->secrecy; 00955 } 00956 00957 00958 QByteArray KSslKey::toDer() const 00959 { 00960 return d->der; 00961 } 00962 00964 00965 //nice-to-have: make implicitly shared 00966 class KSslCipherPrivate 00967 { 00968 public: 00969 00970 QString authenticationMethod; 00971 QString encryptionMethod; 00972 QString keyExchangeMethod; 00973 QString name; 00974 bool isNull; 00975 int supportedBits; 00976 int usedBits; 00977 }; 00978 00979 00980 KSslCipher::KSslCipher() 00981 : d(new KSslCipherPrivate) 00982 { 00983 d->isNull = true; 00984 d->supportedBits = 0; 00985 d->usedBits = 0; 00986 } 00987 00988 00989 KSslCipher::KSslCipher(const KSslCipher &other) 00990 : d(new KSslCipherPrivate) 00991 { 00992 *d = *other.d; 00993 } 00994 00995 00996 KSslCipher::KSslCipher(const QSslCipher &qsc) 00997 : d(new KSslCipherPrivate) 00998 { 00999 d->authenticationMethod = qsc.authenticationMethod(); 01000 d->encryptionMethod = qsc.encryptionMethod(); 01001 //Qt likes to append the number of bits (usedBits?) to the algorithm, 01002 //for example "AES(256)". We only want the pure algorithm name, though. 01003 int parenIdx = d->encryptionMethod.indexOf(QLatin1Char('(')); 01004 if (parenIdx > 0) 01005 d->encryptionMethod.truncate(parenIdx); 01006 d->keyExchangeMethod = qsc.keyExchangeMethod(); 01007 d->name = qsc.name(); 01008 d->isNull = qsc.isNull(); 01009 d->supportedBits = qsc.supportedBits(); 01010 d->usedBits = qsc.usedBits(); 01011 } 01012 01013 01014 KSslCipher::~KSslCipher() 01015 { 01016 delete d; 01017 } 01018 01019 01020 KSslCipher &KSslCipher::operator=(const KSslCipher &other) 01021 { 01022 *d = *other.d; 01023 return *this; 01024 } 01025 01026 01027 bool KSslCipher::isNull() const 01028 { 01029 return d->isNull; 01030 } 01031 01032 01033 QString KSslCipher::authenticationMethod() const 01034 { 01035 return d->authenticationMethod; 01036 } 01037 01038 01039 QString KSslCipher::encryptionMethod() const 01040 { 01041 return d->encryptionMethod; 01042 } 01043 01044 01045 QString KSslCipher::keyExchangeMethod() const 01046 { 01047 return d->keyExchangeMethod; 01048 } 01049 01050 01051 QString KSslCipher::digestMethod() const 01052 { 01053 //### This is not really backend neutral. It works for OpenSSL and 01054 // for RFC compliant names, though. 01055 if (d->name.endsWith(QLatin1String("SHA"))) 01056 return QString::fromLatin1("SHA-1"); 01057 else if (d->name.endsWith(QLatin1String("MD5"))) 01058 return QString::fromLatin1("MD5"); 01059 else 01060 return QString::fromLatin1(""); // ## probably QString() is enough 01061 } 01062 01063 01064 QString KSslCipher::name() const 01065 { 01066 return d->name; 01067 } 01068 01069 01070 int KSslCipher::supportedBits() const 01071 { 01072 return d->supportedBits; 01073 } 01074 01075 01076 int KSslCipher::usedBits() const 01077 { 01078 return d->usedBits; 01079 } 01080 01081 01082 //static 01083 QList<KSslCipher> KSslCipher::supportedCiphers() 01084 { 01085 QList<KSslCipher> ret; 01086 QList<QSslCipher> candidates = QSslSocket::supportedCiphers(); 01087 foreach(const QSslCipher &c, candidates) { 01088 ret.append(KSslCipher(c)); 01089 } 01090 return ret; 01091 } 01092 01093 01094 KSslErrorUiData::KSslErrorUiData() 01095 : d(new Private()) 01096 { 01097 d->usedBits = 0; 01098 d->bits = 0; 01099 } 01100 01101 01102 KSslErrorUiData::KSslErrorUiData(const KTcpSocket *socket) 01103 : d(new Private()) 01104 { 01105 d->certificateChain = socket->peerCertificateChain(); 01106 d->sslErrors = socket->sslErrors(); 01107 d->ip = socket->peerAddress().toString(); 01108 d->host = socket->peerName(); 01109 d->sslProtocol = socket->negotiatedSslVersionName(); 01110 d->cipher = socket->sessionCipher().name(); 01111 d->usedBits = socket->sessionCipher().usedBits(); 01112 d->bits = socket->sessionCipher().supportedBits(); 01113 } 01114 01115 KSslErrorUiData::KSslErrorUiData(const QSslSocket *socket) 01116 : d(new Private()) 01117 { 01118 d->certificateChain = socket->peerCertificateChain(); 01119 01120 // See KTcpSocket::sslErrors() 01121 foreach (const QSslError &e, socket->sslErrors()) 01122 d->sslErrors.append(KSslError(e)); 01123 01124 d->ip = socket->peerAddress().toString(); 01125 d->host = socket->peerName(); 01126 if (socket->isEncrypted()) { 01127 d->sslProtocol = socket->sessionCipher().protocolString(); 01128 } 01129 d->cipher = socket->sessionCipher().name(); 01130 d->usedBits = socket->sessionCipher().usedBits(); 01131 d->bits = socket->sessionCipher().supportedBits(); 01132 } 01133 01134 01135 KSslErrorUiData::KSslErrorUiData(const KSslErrorUiData &other) 01136 : d(new Private(*other.d)) 01137 {} 01138 01139 KSslErrorUiData::~KSslErrorUiData() 01140 { 01141 delete d; 01142 } 01143 01144 KSslErrorUiData &KSslErrorUiData::operator=(const KSslErrorUiData &other) 01145 { 01146 *d = *other.d; 01147 return *this; 01148 } 01149 01150 01151 #include "ktcpsocket.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:28:13 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2019 The KDE developers.
Generated on Mon Jan 21 2019 12:28:13 by doxygen 1.7.5.1 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.