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 //slot 00811 void KTcpSocket::ignoreSslErrors() 00812 { 00813 d->sock.ignoreSslErrors(); 00814 } 00815 00816 00817 //slot 00818 void KTcpSocket::startClientEncryption() 00819 { 00820 d->maybeLoadCertificates(); 00821 d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion)); 00822 d->sock.startClientEncryption(); 00823 } 00824 00825 00826 //debugging H4X 00827 void KTcpSocket::showSslErrors() 00828 { 00829 foreach (const QSslError &e, d->sock.sslErrors()) 00830 kDebug(7029) << e.errorString(); 00831 } 00832 00833 00834 void KTcpSocket::setAdvertisedSslVersion(KTcpSocket::SslVersion version) 00835 { 00836 d->advertisedSslVersion = version; 00837 } 00838 00839 00840 KTcpSocket::SslVersion KTcpSocket::advertisedSslVersion() const 00841 { 00842 return d->advertisedSslVersion; 00843 } 00844 00845 00846 KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const 00847 { 00848 if (!d->sock.isEncrypted()) { 00849 return UnknownSslVersion; 00850 } 00851 return kSslVersionFromQ(d->sock.protocol()); 00852 } 00853 00854 00855 QString KTcpSocket::negotiatedSslVersionName() const 00856 { 00857 if (!d->sock.isEncrypted()) { 00858 return QString(); 00859 } 00860 return d->sock.sessionCipher().protocolString(); 00861 } 00862 00863 00865 00866 class KSslKeyPrivate 00867 { 00868 public: 00869 KSslKey::Algorithm convertAlgorithm(QSsl::KeyAlgorithm a) 00870 { 00871 switch(a) { 00872 case QSsl::Dsa: 00873 return KSslKey::Dsa; 00874 default: 00875 return KSslKey::Rsa; 00876 } 00877 } 00878 00879 KSslKey::Algorithm algorithm; 00880 KSslKey::KeySecrecy secrecy; 00881 bool isExportable; 00882 QByteArray der; 00883 }; 00884 00885 00886 KSslKey::KSslKey() 00887 : d(new KSslKeyPrivate) 00888 { 00889 d->algorithm = Rsa; 00890 d->secrecy = PublicKey; 00891 d->isExportable = true; 00892 } 00893 00894 00895 KSslKey::KSslKey(const KSslKey &other) 00896 : d(new KSslKeyPrivate) 00897 { 00898 *d = *other.d; 00899 } 00900 00901 00902 KSslKey::KSslKey(const QSslKey &qsk) 00903 : d(new KSslKeyPrivate) 00904 { 00905 d->algorithm = d->convertAlgorithm(qsk.algorithm()); 00906 d->secrecy = (qsk.type() == QSsl::PrivateKey) ? PrivateKey : PublicKey; 00907 d->isExportable = true; 00908 d->der = qsk.toDer(); 00909 } 00910 00911 00912 KSslKey::~KSslKey() 00913 { 00914 delete d; 00915 } 00916 00917 00918 KSslKey &KSslKey::operator=(const KSslKey &other) 00919 { 00920 *d = *other.d; 00921 return *this; 00922 } 00923 00924 00925 KSslKey::Algorithm KSslKey::algorithm() const 00926 { 00927 return d->algorithm; 00928 } 00929 00930 00931 bool KSslKey::isExportable() const 00932 { 00933 return d->isExportable; 00934 } 00935 00936 00937 KSslKey::KeySecrecy KSslKey::secrecy() const 00938 { 00939 return d->secrecy; 00940 } 00941 00942 00943 QByteArray KSslKey::toDer() const 00944 { 00945 return d->der; 00946 } 00947 00949 00950 //nice-to-have: make implicitly shared 00951 class KSslCipherPrivate 00952 { 00953 public: 00954 00955 QString authenticationMethod; 00956 QString encryptionMethod; 00957 QString keyExchangeMethod; 00958 QString name; 00959 bool isNull; 00960 int supportedBits; 00961 int usedBits; 00962 }; 00963 00964 00965 KSslCipher::KSslCipher() 00966 : d(new KSslCipherPrivate) 00967 { 00968 d->isNull = true; 00969 d->supportedBits = 0; 00970 d->usedBits = 0; 00971 } 00972 00973 00974 KSslCipher::KSslCipher(const KSslCipher &other) 00975 : d(new KSslCipherPrivate) 00976 { 00977 *d = *other.d; 00978 } 00979 00980 00981 KSslCipher::KSslCipher(const QSslCipher &qsc) 00982 : d(new KSslCipherPrivate) 00983 { 00984 d->authenticationMethod = qsc.authenticationMethod(); 00985 d->encryptionMethod = qsc.encryptionMethod(); 00986 //Qt likes to append the number of bits (usedBits?) to the algorithm, 00987 //for example "AES(256)". We only want the pure algorithm name, though. 00988 int parenIdx = d->encryptionMethod.indexOf(QLatin1Char('(')); 00989 if (parenIdx > 0) 00990 d->encryptionMethod.truncate(parenIdx); 00991 d->keyExchangeMethod = qsc.keyExchangeMethod(); 00992 d->name = qsc.name(); 00993 d->isNull = qsc.isNull(); 00994 d->supportedBits = qsc.supportedBits(); 00995 d->usedBits = qsc.usedBits(); 00996 } 00997 00998 00999 KSslCipher::~KSslCipher() 01000 { 01001 delete d; 01002 } 01003 01004 01005 KSslCipher &KSslCipher::operator=(const KSslCipher &other) 01006 { 01007 *d = *other.d; 01008 return *this; 01009 } 01010 01011 01012 bool KSslCipher::isNull() const 01013 { 01014 return d->isNull; 01015 } 01016 01017 01018 QString KSslCipher::authenticationMethod() const 01019 { 01020 return d->authenticationMethod; 01021 } 01022 01023 01024 QString KSslCipher::encryptionMethod() const 01025 { 01026 return d->encryptionMethod; 01027 } 01028 01029 01030 QString KSslCipher::keyExchangeMethod() const 01031 { 01032 return d->keyExchangeMethod; 01033 } 01034 01035 01036 QString KSslCipher::digestMethod() const 01037 { 01038 //### This is not really backend neutral. It works for OpenSSL and 01039 // for RFC compliant names, though. 01040 if (d->name.endsWith(QLatin1String("SHA"))) 01041 return QString::fromLatin1("SHA-1"); 01042 else if (d->name.endsWith(QLatin1String("MD5"))) 01043 return QString::fromLatin1("MD5"); 01044 else 01045 return QString::fromLatin1(""); // ## probably QString() is enough 01046 } 01047 01048 01049 QString KSslCipher::name() const 01050 { 01051 return d->name; 01052 } 01053 01054 01055 int KSslCipher::supportedBits() const 01056 { 01057 return d->supportedBits; 01058 } 01059 01060 01061 int KSslCipher::usedBits() const 01062 { 01063 return d->usedBits; 01064 } 01065 01066 01067 //static 01068 QList<KSslCipher> KSslCipher::supportedCiphers() 01069 { 01070 QList<KSslCipher> ret; 01071 QList<QSslCipher> candidates = QSslSocket::supportedCiphers(); 01072 foreach(const QSslCipher &c, candidates) { 01073 ret.append(KSslCipher(c)); 01074 } 01075 return ret; 01076 } 01077 01078 01079 KSslErrorUiData::KSslErrorUiData() 01080 : d(new Private()) 01081 { 01082 d->usedBits = 0; 01083 d->bits = 0; 01084 } 01085 01086 01087 KSslErrorUiData::KSslErrorUiData(const KTcpSocket *socket) 01088 : d(new Private()) 01089 { 01090 d->certificateChain = socket->peerCertificateChain(); 01091 d->sslErrors = socket->sslErrors(); 01092 d->ip = socket->peerAddress().toString(); 01093 d->host = socket->peerName(); 01094 d->sslProtocol = socket->negotiatedSslVersionName(); 01095 d->cipher = socket->sessionCipher().name(); 01096 d->usedBits = socket->sessionCipher().usedBits(); 01097 d->bits = socket->sessionCipher().supportedBits(); 01098 } 01099 01100 KSslErrorUiData::KSslErrorUiData(const QSslSocket *socket) 01101 : d(new Private()) 01102 { 01103 d->certificateChain = socket->peerCertificateChain(); 01104 01105 // See KTcpSocket::sslErrors() 01106 foreach (const QSslError &e, socket->sslErrors()) 01107 d->sslErrors.append(KSslError(e)); 01108 01109 d->ip = socket->peerAddress().toString(); 01110 d->host = socket->peerName(); 01111 if (socket->isEncrypted()) { 01112 d->sslProtocol = socket->sessionCipher().protocolString(); 01113 } 01114 d->cipher = socket->sessionCipher().name(); 01115 d->usedBits = socket->sessionCipher().usedBits(); 01116 d->bits = socket->sessionCipher().supportedBits(); 01117 } 01118 01119 01120 KSslErrorUiData::KSslErrorUiData(const KSslErrorUiData &other) 01121 : d(new Private(*other.d)) 01122 {} 01123 01124 KSslErrorUiData::~KSslErrorUiData() 01125 { 01126 delete d; 01127 } 01128 01129 KSslErrorUiData &KSslErrorUiData::operator=(const KSslErrorUiData &other) 01130 { 01131 *d = *other.d; 01132 return *this; 01133 } 01134 01135 01136 #include "ktcpsocket.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:49:33 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:49:33 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.