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