• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.8.3 API Reference
  • KDE Home
  • Contact Us
 

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 Wed May 2 2012 17:05:22 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.8.3 API Reference

Skip menu "kdelibs-4.8.3 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal