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

KDECore

  • kdecore
  • network
ktcpsocket.cpp
Go to the documentation of this file.
1 /* This file is part of the KDE libraries
2  Copyright (C) 2007, 2008 Andreas Hartmetz <ahartmetz@gmail.com>
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Library General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "ktcpsocket.h"
21 #include "ktcpsocket_p.h"
22 
23 #include <kdebug.h>
24 #include <kurl.h>
25 #include <kglobal.h>
26 #include <ksslcertificatemanager.h>
27 #include <kstandarddirs.h>
28 #include <klocale.h>
29 
30 #include <QtCore/QStringList>
31 #include <QtNetwork/QSslKey>
32 #include <QtNetwork/QSslCipher>
33 #include <QtNetwork/QHostAddress>
34 #include <QtNetwork/QNetworkProxy>
35 
36 static KTcpSocket::SslVersion kSslVersionFromQ(QSsl::SslProtocol protocol)
37 {
38  switch (protocol) {
39  case QSsl::SslV2:
40  return KTcpSocket::SslV2;
41  case QSsl::SslV3:
42  return KTcpSocket::SslV3;
43  case QSsl::TlsV1:
44  return KTcpSocket::TlsV1;
45  case QSsl::AnyProtocol:
46  return KTcpSocket::AnySslVersion;
47 #if QT_VERSION >= 0x040800
48  case QSsl::TlsV1SslV3:
49  return KTcpSocket::TlsV1SslV3;
50  case QSsl::SecureProtocols:
51  return KTcpSocket::SecureProtocols;
52 #endif
53  default:
54  return KTcpSocket::UnknownSslVersion;
55  }
56 }
57 
58 
59 static QSsl::SslProtocol qSslProtocolFromK(KTcpSocket::SslVersion sslVersion)
60 {
61  //### this lowlevel bit-banging is a little dangerous and a likely source of bugs
62  if (sslVersion == KTcpSocket::AnySslVersion) {
63  return QSsl::AnyProtocol;
64  }
65  //does it contain any valid protocol?
66  KTcpSocket::SslVersions validVersions (KTcpSocket::SslV2 | KTcpSocket::SslV3 | KTcpSocket::TlsV1);
67 #if QT_VERSION >= 0x040800
68  validVersions |= KTcpSocket::TlsV1SslV3;
69  validVersions |= KTcpSocket::SecureProtocols;
70 #endif
71  if (!(sslVersion & validVersions)) {
72  return QSsl::UnknownProtocol;
73  }
74 
75  switch (sslVersion) {
76  case KTcpSocket::SslV2:
77  return QSsl::SslV2;
78  case KTcpSocket::SslV3:
79  return QSsl::SslV3;
80  case KTcpSocket::TlsV1:
81  return QSsl::TlsV1;
82 #if QT_VERSION >= 0x040800
83  case KTcpSocket::TlsV1SslV3:
84  return QSsl::TlsV1SslV3;
85  case KTcpSocket::SecureProtocols:
86  return QSsl::SecureProtocols;
87 #endif
88 
89  default:
90  //QSslSocket doesn't really take arbitrary combinations. It's one or all.
91  return QSsl::AnyProtocol;
92  }
93 }
94 
95 
96 //cipher class converter KSslCipher -> QSslCipher
97 class CipherCc
98 {
99 public:
100  CipherCc()
101  {
102  foreach (const QSslCipher &c, QSslSocket::supportedCiphers()) {
103  allCiphers.insert(c.name(), c);
104  }
105  }
106 
107  QSslCipher converted(const KSslCipher &ksc)
108  {
109  return allCiphers.value(ksc.name());
110  }
111 
112 private:
113  QHash<QString, QSslCipher> allCiphers;
114 };
115 
116 
117 class KSslErrorPrivate
118 {
119 public:
120  static KSslError::Error errorFromQSslError(QSslError::SslError e)
121  {
122  switch (e) {
123  case QSslError::NoError:
124  return KSslError::NoError;
125  case QSslError::UnableToGetLocalIssuerCertificate:
126  case QSslError::InvalidCaCertificate:
127  return KSslError::InvalidCertificateAuthorityCertificate;
128  case QSslError::InvalidNotBeforeField:
129  case QSslError::InvalidNotAfterField:
130  case QSslError::CertificateNotYetValid:
131  case QSslError::CertificateExpired:
132  return KSslError::ExpiredCertificate;
133  case QSslError::UnableToDecodeIssuerPublicKey:
134  case QSslError::SubjectIssuerMismatch:
135  case QSslError::AuthorityIssuerSerialNumberMismatch:
136  return KSslError::InvalidCertificate;
137  case QSslError::SelfSignedCertificate:
138  case QSslError::SelfSignedCertificateInChain:
139  return KSslError::SelfSignedCertificate;
140  case QSslError::CertificateRevoked:
141  return KSslError::RevokedCertificate;
142  case QSslError::InvalidPurpose:
143  return KSslError::InvalidCertificatePurpose;
144  case QSslError::CertificateUntrusted:
145  return KSslError::UntrustedCertificate;
146  case QSslError::CertificateRejected:
147  return KSslError::RejectedCertificate;
148  case QSslError::NoPeerCertificate:
149  return KSslError::NoPeerCertificate;
150  case QSslError::HostNameMismatch:
151  return KSslError::HostNameMismatch;
152  case QSslError::UnableToVerifyFirstCertificate:
153  case QSslError::UnableToDecryptCertificateSignature:
154  case QSslError::UnableToGetIssuerCertificate:
155  case QSslError::CertificateSignatureFailed:
156  return KSslError::CertificateSignatureFailed;
157  case QSslError::PathLengthExceeded:
158  return KSslError::PathLengthExceeded;
159  case QSslError::UnspecifiedError:
160  case QSslError::NoSslSupport:
161  default:
162  return KSslError::UnknownError;
163  }
164  }
165 
166  static QString errorString(KSslError::Error e)
167  {
168  switch (e) {
169  case KSslError::NoError:
170  return i18nc("SSL error","No error");
171  case KSslError::InvalidCertificateAuthorityCertificate:
172  return i18nc("SSL error","The certificate authority's certificate is invalid");
173  case KSslError::ExpiredCertificate:
174  return i18nc("SSL error","The certificate has expired");
175  case KSslError::InvalidCertificate:
176  return i18nc("SSL error","The certificate is invalid");
177  case KSslError::SelfSignedCertificate:
178  return i18nc("SSL error","The certificate is not signed by any trusted certificate authority");
179  case KSslError::RevokedCertificate:
180  return i18nc("SSL error","The certificate has been revoked");
181  case KSslError::InvalidCertificatePurpose:
182  return i18nc("SSL error","The certificate is unsuitable for this purpose");
183  case KSslError::UntrustedCertificate:
184  return i18nc("SSL error","The root certificate authority's certificate is not trusted for this purpose");
185  case KSslError::RejectedCertificate:
186  return i18nc("SSL error","The certificate authority's certificate is marked to reject this certificate's purpose");
187  case KSslError::NoPeerCertificate:
188  return i18nc("SSL error","The peer did not present any certificate");
189  case KSslError::HostNameMismatch:
190  return i18nc("SSL error","The certificate does not apply to the given host");
191  case KSslError::CertificateSignatureFailed:
192  return i18nc("SSL error","The certificate cannot be verified for internal reasons");
193  case KSslError::PathLengthExceeded:
194  return i18nc("SSL error","The certificate chain is too long");
195  case KSslError::UnknownError:
196  default:
197  return i18nc("SSL error","Unknown error");
198  }
199  }
200 
201  KSslError::Error error;
202  QSslCertificate certificate;
203 };
204 
205 
206 KSslError::KSslError(Error errorCode, const QSslCertificate &certificate)
207  : d(new KSslErrorPrivate())
208 {
209  d->error = errorCode;
210  d->certificate = certificate;
211 }
212 
213 
214 KSslError::KSslError(const QSslError &other)
215  : d(new KSslErrorPrivate())
216 {
217  d->error = KSslErrorPrivate::errorFromQSslError(other.error());
218  d->certificate = other.certificate();
219 }
220 
221 
222 KSslError::KSslError(const KSslError &other)
223  : d(new KSslErrorPrivate())
224 {
225  *d = *other.d;
226 }
227 
228 
229 KSslError::~KSslError()
230 {
231  delete d;
232 }
233 
234 
235 KSslError &KSslError::operator=(const KSslError &other)
236 {
237  *d = *other.d;
238  return *this;
239 }
240 
241 
242 KSslError::Error KSslError::error() const
243 {
244  return d->error;
245 }
246 
247 
248 QString KSslError::errorString() const
249 {
250  return KSslErrorPrivate::errorString(d->error);
251 }
252 
253 
254 QSslCertificate KSslError::certificate() const
255 {
256  return d->certificate;
257 }
258 
259 
260 class KTcpSocketPrivate
261 {
262 public:
263  KTcpSocketPrivate(KTcpSocket *qq)
264  : q(qq),
265  certificatesLoaded(false),
266  emittedReadyRead(false)
267  {
268  // create the instance, which sets Qt's static internal cert set to empty.
269  KSslCertificateManager::self();
270  }
271 
272  KTcpSocket::State state(QAbstractSocket::SocketState s)
273  {
274  switch (s) {
275  case QAbstractSocket::UnconnectedState:
276  return KTcpSocket::UnconnectedState;
277  case QAbstractSocket::HostLookupState:
278  return KTcpSocket::HostLookupState;
279  case QAbstractSocket::ConnectingState:
280  return KTcpSocket::ConnectingState;
281  case QAbstractSocket::ConnectedState:
282  return KTcpSocket::ConnectedState;
283  case QAbstractSocket::ClosingState:
284  return KTcpSocket::ClosingState;
285  case QAbstractSocket::BoundState:
286  case QAbstractSocket::ListeningState:
287  //### these two are not relevant as long as this can't be a server socket
288  default:
289  return KTcpSocket::UnconnectedState; //the closest to "error"
290  }
291  }
292 
293  KTcpSocket::EncryptionMode encryptionMode(QSslSocket::SslMode mode)
294  {
295  switch (mode) {
296  case QSslSocket::SslClientMode:
297  return KTcpSocket::SslClientMode;
298  case QSslSocket::SslServerMode:
299  return KTcpSocket::SslServerMode;
300  default:
301  return KTcpSocket::UnencryptedMode;
302  }
303  }
304 
305  KTcpSocket::Error errorFromAbsSocket(QAbstractSocket::SocketError e)
306  {
307  switch (e) {
308  case QAbstractSocket::ConnectionRefusedError:
309  return KTcpSocket::ConnectionRefusedError;
310  case QAbstractSocket::RemoteHostClosedError:
311  return KTcpSocket::RemoteHostClosedError;
312  case QAbstractSocket::HostNotFoundError:
313  return KTcpSocket::HostNotFoundError;
314  case QAbstractSocket::SocketAccessError:
315  return KTcpSocket::SocketAccessError;
316  case QAbstractSocket::SocketResourceError:
317  return KTcpSocket::SocketResourceError;
318  case QAbstractSocket::SocketTimeoutError:
319  return KTcpSocket::SocketTimeoutError;
320  case QAbstractSocket::NetworkError:
321  return KTcpSocket::NetworkError;
322  case QAbstractSocket::UnsupportedSocketOperationError:
323  return KTcpSocket::UnsupportedSocketOperationError;
324  case QAbstractSocket::DatagramTooLargeError:
325  //we don't do UDP
326  case QAbstractSocket::AddressInUseError:
327  case QAbstractSocket::SocketAddressNotAvailableError:
328  //### own values if/when we ever get server socket support
329  case QAbstractSocket::ProxyAuthenticationRequiredError:
330  //### maybe we need an enum value for this
331  case QAbstractSocket::UnknownSocketError:
332  default:
333  return KTcpSocket::UnknownError;
334  }
335  }
336 
337  //private slots
338  void reemitSocketError(QAbstractSocket::SocketError e)
339  {
340  emit q->error(errorFromAbsSocket(e));
341  }
342 
343  void reemitSslErrors(const QList<QSslError> &errors)
344  {
345  q->showSslErrors(); //H4X
346  QList<KSslError> kErrors;
347  foreach (const QSslError &e, errors) {
348  kErrors.append(KSslError(e));
349  }
350  emit q->sslErrors(kErrors);
351  }
352 
353  void reemitStateChanged(QAbstractSocket::SocketState s)
354  {
355  emit q->stateChanged(state(s));
356  }
357 
358  void reemitModeChanged(QSslSocket::SslMode m)
359  {
360  emit q->encryptionModeChanged(encryptionMode(m));
361  }
362 
363  // This method is needed because we might emit readyRead() due to this QIODevice
364  // having some data buffered, so we need to care about blocking, too.
365  //### useless ATM as readyRead() now just calls d->sock.readyRead().
366  void reemitReadyRead()
367  {
368  if (!emittedReadyRead) {
369  emittedReadyRead = true;
370  emit q->readyRead();
371  emittedReadyRead = false;
372  }
373  }
374 
375  void maybeLoadCertificates()
376  {
377  if (!certificatesLoaded) {
378  sock.setCaCertificates(KSslCertificateManager::self()->caCertificates());
379  certificatesLoaded = true;
380  }
381  }
382 
383  KTcpSocket *const q;
384  bool certificatesLoaded;
385  bool emittedReadyRead;
386  QSslSocket sock;
387  QList<KSslCipher> ciphers;
388  KTcpSocket::SslVersion advertisedSslVersion;
389  CipherCc ccc;
390 };
391 
392 
393 KTcpSocket::KTcpSocket(QObject *parent)
394  : QIODevice(parent),
395  d(new KTcpSocketPrivate(this))
396 {
397  d->advertisedSslVersion = SslV3;
398 
399  connect(&d->sock, SIGNAL(aboutToClose()), this, SIGNAL(aboutToClose()));
400  connect(&d->sock, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64)));
401  connect(&d->sock, SIGNAL(encryptedBytesWritten(qint64)), this, SIGNAL(encryptedBytesWritten(qint64)));
402  connect(&d->sock, SIGNAL(readyRead()), this, SLOT(reemitReadyRead()));
403  connect(&d->sock, SIGNAL(connected()), this, SIGNAL(connected()));
404  connect(&d->sock, SIGNAL(encrypted()), this, SIGNAL(encrypted()));
405  connect(&d->sock, SIGNAL(disconnected()), this, SIGNAL(disconnected()));
406 #ifndef QT_NO_NETWORKPROXY
407  connect(&d->sock, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
408  this, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)));
409 #endif
410  connect(&d->sock, SIGNAL(error(QAbstractSocket::SocketError)),
411  this, SLOT(reemitSocketError(QAbstractSocket::SocketError)));
412  connect(&d->sock, SIGNAL(sslErrors(QList<QSslError>)),
413  this, SLOT(reemitSslErrors(QList<QSslError>)));
414  connect(&d->sock, SIGNAL(hostFound()), this, SIGNAL(hostFound()));
415  connect(&d->sock, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
416  this, SLOT(reemitStateChanged(QAbstractSocket::SocketState)));
417  connect(&d->sock, SIGNAL(modeChanged(QSslSocket::SslMode)),
418  this, SLOT(reemitModeChanged(QSslSocket::SslMode)));
419 }
420 
421 
422 KTcpSocket::~KTcpSocket()
423 {
424  delete d;
425 }
426 
428 
429 bool KTcpSocket::atEnd() const
430 {
431  return d->sock.atEnd() && QIODevice::atEnd();
432 }
433 
434 
435 qint64 KTcpSocket::bytesAvailable() const
436 {
437  return d->sock.bytesAvailable() + QIODevice::bytesAvailable();
438 }
439 
440 
441 qint64 KTcpSocket::bytesToWrite() const
442 {
443  return d->sock.bytesToWrite();
444 }
445 
446 
447 bool KTcpSocket::canReadLine() const
448 {
449  return d->sock.canReadLine() || QIODevice::canReadLine();
450 }
451 
452 
453 void KTcpSocket::close()
454 {
455  d->sock.close();
456  QIODevice::close();
457 }
458 
459 
460 bool KTcpSocket::isSequential() const
461 {
462  return true;
463 }
464 
465 
466 bool KTcpSocket::open(QIODevice::OpenMode open)
467 {
468  bool ret = d->sock.open(open);
469  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
470  return ret;
471 }
472 
473 
474 bool KTcpSocket::waitForBytesWritten(int msecs)
475 {
476  return d->sock.waitForBytesWritten(msecs);
477 }
478 
479 
480 bool KTcpSocket::waitForReadyRead(int msecs)
481 {
482  return d->sock.waitForReadyRead(msecs);
483 }
484 
485 
486 qint64 KTcpSocket::readData(char *data, qint64 maxSize)
487 {
488  return d->sock.read(data, maxSize);
489 }
490 
491 
492 qint64 KTcpSocket::writeData(const char *data, qint64 maxSize)
493 {
494  return d->sock.write(data, maxSize);
495 }
496 
498 
499 void KTcpSocket::abort()
500 {
501  d->sock.abort();
502 }
503 
504 
505 void KTcpSocket::connectToHost(const QString &hostName, quint16 port, ProxyPolicy policy)
506 {
507  if (policy == AutoProxy) {
508  //###
509  }
510  d->sock.connectToHost(hostName, port);
511  // there are enough layers of buffers between us and the network, and there is a quirk
512  // in QIODevice that can make it try to readData() twice per read() call if buffered and
513  // reaData() does not deliver enough data the first time. like when the other side is
514  // simply not sending any more data...
515  // this can *apparently* lead to long delays sometimes which stalls applications.
516  // do not want.
517  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
518 }
519 
520 
521 void KTcpSocket::connectToHost(const QHostAddress &hostAddress, quint16 port, ProxyPolicy policy)
522 {
523  if (policy == AutoProxy) {
524  //###
525  }
526  d->sock.connectToHost(hostAddress, port);
527  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
528 }
529 
530 
531 void KTcpSocket::connectToHost(const KUrl &url, ProxyPolicy policy)
532 {
533  if (policy == AutoProxy) {
534  //###
535  }
536  d->sock.connectToHost(url.host(), url.port());
537  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
538 }
539 
540 
541 void KTcpSocket::disconnectFromHost()
542 {
543  d->sock.disconnectFromHost();
544  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
545 }
546 
547 
548 KTcpSocket::Error KTcpSocket::error() const
549 {
550  return d->errorFromAbsSocket(d->sock.error());
551 }
552 
553 
554 QList<KSslError> KTcpSocket::sslErrors() const
555 {
556  //### pretty slow; also consider throwing out duplicate error codes. We may get
557  // duplicates even though there were none in the original list because KSslError
558  // has a smallest common denominator range of SSL error codes.
559  QList<KSslError> ret;
560  foreach (const QSslError &e, d->sock.sslErrors())
561  ret.append(KSslError(e));
562  return ret;
563 }
564 
565 
566 bool KTcpSocket::flush()
567 {
568  return d->sock.flush();
569 }
570 
571 
572 bool KTcpSocket::isValid() const
573 {
574  return d->sock.isValid();
575 }
576 
577 
578 QHostAddress KTcpSocket::localAddress() const
579 {
580  return d->sock.localAddress();
581 }
582 
583 
584 QHostAddress KTcpSocket::peerAddress() const
585 {
586  return d->sock.peerAddress();
587 }
588 
589 
590 QString KTcpSocket::peerName() const
591 {
592  return d->sock.peerName();
593 }
594 
595 
596 quint16 KTcpSocket::peerPort() const
597 {
598  return d->sock.peerPort();
599 }
600 
601 
602 #ifndef QT_NO_NETWORKPROXY
603 QNetworkProxy KTcpSocket::proxy() const
604 {
605  return d->sock.proxy();
606 }
607 #endif
608 
609 qint64 KTcpSocket::readBufferSize() const
610 {
611  return d->sock.readBufferSize();
612 }
613 
614 
615 #ifndef QT_NO_NETWORKPROXY
616 void KTcpSocket::setProxy(const QNetworkProxy &proxy)
617 {
618  d->sock.setProxy(proxy);
619 }
620 #endif
621 
622 void KTcpSocket::setReadBufferSize(qint64 size)
623 {
624  d->sock.setReadBufferSize(size);
625 }
626 
627 
628 KTcpSocket::State KTcpSocket::state() const
629 {
630  return d->state(d->sock.state());
631 }
632 
633 
634 bool KTcpSocket::waitForConnected(int msecs)
635 {
636  bool ret = d->sock.waitForConnected(msecs);
637  if (!ret)
638  setErrorString(d->sock.errorString());
639  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
640  return ret;
641 }
642 
643 
644 bool KTcpSocket::waitForDisconnected(int msecs)
645 {
646  bool ret = d->sock.waitForDisconnected(msecs);
647  if (!ret)
648  setErrorString(d->sock.errorString());
649  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
650  return ret;
651 }
652 
654 
655 void KTcpSocket::addCaCertificate(const QSslCertificate &certificate)
656 {
657  d->maybeLoadCertificates();
658  d->sock.addCaCertificate(certificate);
659 }
660 
661 
662 /*
663 bool KTcpSocket::addCaCertificates(const QString &path, QSsl::EncodingFormat format,
664  QRegExp::PatternSyntax syntax)
665 {
666  d->maybeLoadCertificates();
667  return d->sock.addCaCertificates(path, format, syntax);
668 }
669 */
670 
671 
672 void KTcpSocket::addCaCertificates(const QList<QSslCertificate> &certificates)
673 {
674  d->maybeLoadCertificates();
675  d->sock.addCaCertificates(certificates);
676 }
677 
678 
679 QList<QSslCertificate> KTcpSocket::caCertificates() const
680 {
681  d->maybeLoadCertificates();
682  return d->sock.caCertificates();
683 }
684 
685 
686 QList<KSslCipher> KTcpSocket::ciphers() const
687 {
688  return d->ciphers;
689 }
690 
691 
692 void KTcpSocket::connectToHostEncrypted(const QString &hostName, quint16 port, OpenMode openMode)
693 {
694  d->maybeLoadCertificates();
695  d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion));
696  d->sock.connectToHostEncrypted(hostName, port, openMode);
697  setOpenMode(d->sock.openMode() | QIODevice::Unbuffered);
698 }
699 
700 
701 QSslCertificate KTcpSocket::localCertificate() const
702 {
703  return d->sock.localCertificate();
704 }
705 
706 
707 QList<QSslCertificate> KTcpSocket::peerCertificateChain() const
708 {
709  return d->sock.peerCertificateChain();
710 }
711 
712 
713 KSslKey KTcpSocket::privateKey() const
714 {
715  return KSslKey(d->sock.privateKey());
716 }
717 
718 
719 KSslCipher KTcpSocket::sessionCipher() const
720 {
721  return KSslCipher(d->sock.sessionCipher());
722 }
723 
724 
725 void KTcpSocket::setCaCertificates(const QList<QSslCertificate> &certificates)
726 {
727  d->sock.setCaCertificates(certificates);
728  d->certificatesLoaded = true;
729 }
730 
731 
732 void KTcpSocket::setCiphers(const QList<KSslCipher> &ciphers)
733 {
734  d->ciphers = ciphers;
735  QList<QSslCipher> cl;
736  foreach (const KSslCipher &c, d->ciphers) {
737  cl.append(d->ccc.converted(c));
738  }
739  d->sock.setCiphers(cl);
740 }
741 
742 
743 void KTcpSocket::setLocalCertificate(const QSslCertificate &certificate)
744 {
745  d->sock.setLocalCertificate(certificate);
746 }
747 
748 
749 void KTcpSocket::setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format)
750 {
751  d->sock.setLocalCertificate(fileName, format);
752 }
753 
754 
755 void KTcpSocket::setVerificationPeerName(const QString& hostName)
756 {
757 #if QT_VERSION >= 0x040800
758  d->sock.setPeerVerifyName(hostName);
759 #else
760  Q_UNUSED(hostName);
761 #endif
762 }
763 
764 
765 void KTcpSocket::setPrivateKey(const KSslKey &key)
766 {
767  // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm.
768  if (key.algorithm() == KSslKey::Dh)
769  return;
770 
771  QSslKey _key(key.toDer(),
772  (key.algorithm() == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa,
773  QSsl::Der,
774  (key.secrecy() == KSslKey::PrivateKey) ? QSsl::PrivateKey : QSsl::PublicKey);
775 
776  d->sock.setPrivateKey(_key);
777 }
778 
779 
780 void KTcpSocket::setPrivateKey(const QString &fileName, KSslKey::Algorithm algorithm,
781  QSsl::EncodingFormat format, const QByteArray &passPhrase)
782 {
783  // We cannot map KSslKey::Algorithm:Dh to anything in QSsl::KeyAlgorithm.
784  if (algorithm == KSslKey::Dh)
785  return;
786 
787  d->sock.setPrivateKey(fileName,
788  (algorithm == KSslKey::Rsa) ? QSsl::Rsa : QSsl::Dsa,
789  format,
790  passPhrase);
791 }
792 
793 
794 bool KTcpSocket::waitForEncrypted(int msecs)
795 {
796  return d->sock.waitForEncrypted(msecs);
797 }
798 
799 
800 KTcpSocket::EncryptionMode KTcpSocket::encryptionMode() const
801 {
802  return d->encryptionMode(d->sock.mode());
803 }
804 
805 QVariant KTcpSocket::socketOption(QAbstractSocket::SocketOption options) const
806 {
807  return d->sock.socketOption(options);
808 }
809 
810 void KTcpSocket::setSocketOption(QAbstractSocket::SocketOption options, const QVariant &value)
811 {
812  d->sock.setSocketOption(options, value);
813 }
814 
815 QSslConfiguration KTcpSocket::sslConfiguration() const
816 {
817  return d->sock.sslConfiguration();
818 }
819 
820 void KTcpSocket::setSslConfiguration (const QSslConfiguration& configuration)
821 {
822  d->sock.setSslConfiguration(configuration);
823 }
824 
825 //slot
826 void KTcpSocket::ignoreSslErrors()
827 {
828  d->sock.ignoreSslErrors();
829 }
830 
831 
832 //slot
833 void KTcpSocket::startClientEncryption()
834 {
835  d->maybeLoadCertificates();
836  d->sock.setProtocol(qSslProtocolFromK(d->advertisedSslVersion));
837  d->sock.startClientEncryption();
838 }
839 
840 
841 //debugging H4X
842 void KTcpSocket::showSslErrors()
843 {
844  foreach (const QSslError &e, d->sock.sslErrors())
845  kDebug(7029) << e.errorString();
846 }
847 
848 
849 void KTcpSocket::setAdvertisedSslVersion(KTcpSocket::SslVersion version)
850 {
851  d->advertisedSslVersion = version;
852 }
853 
854 
855 KTcpSocket::SslVersion KTcpSocket::advertisedSslVersion() const
856 {
857  return d->advertisedSslVersion;
858 }
859 
860 
861 KTcpSocket::SslVersion KTcpSocket::negotiatedSslVersion() const
862 {
863  if (!d->sock.isEncrypted()) {
864  return UnknownSslVersion;
865  }
866  return kSslVersionFromQ(d->sock.protocol());
867 }
868 
869 
870 QString KTcpSocket::negotiatedSslVersionName() const
871 {
872  if (!d->sock.isEncrypted()) {
873  return QString();
874  }
875  return d->sock.sessionCipher().protocolString();
876 }
877 
878 
880 
881 class KSslKeyPrivate
882 {
883 public:
884  KSslKey::Algorithm convertAlgorithm(QSsl::KeyAlgorithm a)
885  {
886  switch(a) {
887  case QSsl::Dsa:
888  return KSslKey::Dsa;
889  default:
890  return KSslKey::Rsa;
891  }
892  }
893 
894  KSslKey::Algorithm algorithm;
895  KSslKey::KeySecrecy secrecy;
896  bool isExportable;
897  QByteArray der;
898 };
899 
900 
901 KSslKey::KSslKey()
902  : d(new KSslKeyPrivate)
903 {
904  d->algorithm = Rsa;
905  d->secrecy = PublicKey;
906  d->isExportable = true;
907 }
908 
909 
910 KSslKey::KSslKey(const KSslKey &other)
911  : d(new KSslKeyPrivate)
912 {
913  *d = *other.d;
914 }
915 
916 
917 KSslKey::KSslKey(const QSslKey &qsk)
918  : d(new KSslKeyPrivate)
919 {
920  d->algorithm = d->convertAlgorithm(qsk.algorithm());
921  d->secrecy = (qsk.type() == QSsl::PrivateKey) ? PrivateKey : PublicKey;
922  d->isExportable = true;
923  d->der = qsk.toDer();
924 }
925 
926 
927 KSslKey::~KSslKey()
928 {
929  delete d;
930 }
931 
932 
933 KSslKey &KSslKey::operator=(const KSslKey &other)
934 {
935  *d = *other.d;
936  return *this;
937 }
938 
939 
940 KSslKey::Algorithm KSslKey::algorithm() const
941 {
942  return d->algorithm;
943 }
944 
945 
946 bool KSslKey::isExportable() const
947 {
948  return d->isExportable;
949 }
950 
951 
952 KSslKey::KeySecrecy KSslKey::secrecy() const
953 {
954  return d->secrecy;
955 }
956 
957 
958 QByteArray KSslKey::toDer() const
959 {
960  return d->der;
961 }
962 
964 
965 //nice-to-have: make implicitly shared
966 class KSslCipherPrivate
967 {
968 public:
969 
970  QString authenticationMethod;
971  QString encryptionMethod;
972  QString keyExchangeMethod;
973  QString name;
974  bool isNull;
975  int supportedBits;
976  int usedBits;
977 };
978 
979 
980 KSslCipher::KSslCipher()
981  : d(new KSslCipherPrivate)
982 {
983  d->isNull = true;
984  d->supportedBits = 0;
985  d->usedBits = 0;
986 }
987 
988 
989 KSslCipher::KSslCipher(const KSslCipher &other)
990  : d(new KSslCipherPrivate)
991 {
992  *d = *other.d;
993 }
994 
995 
996 KSslCipher::KSslCipher(const QSslCipher &qsc)
997  : d(new KSslCipherPrivate)
998 {
999  d->authenticationMethod = qsc.authenticationMethod();
1000  d->encryptionMethod = qsc.encryptionMethod();
1001  //Qt likes to append the number of bits (usedBits?) to the algorithm,
1002  //for example "AES(256)". We only want the pure algorithm name, though.
1003  int parenIdx = d->encryptionMethod.indexOf(QLatin1Char('('));
1004  if (parenIdx > 0)
1005  d->encryptionMethod.truncate(parenIdx);
1006  d->keyExchangeMethod = qsc.keyExchangeMethod();
1007  d->name = qsc.name();
1008  d->isNull = qsc.isNull();
1009  d->supportedBits = qsc.supportedBits();
1010  d->usedBits = qsc.usedBits();
1011 }
1012 
1013 
1014 KSslCipher::~KSslCipher()
1015 {
1016  delete d;
1017 }
1018 
1019 
1020 KSslCipher &KSslCipher::operator=(const KSslCipher &other)
1021 {
1022  *d = *other.d;
1023  return *this;
1024 }
1025 
1026 
1027 bool KSslCipher::isNull() const
1028 {
1029  return d->isNull;
1030 }
1031 
1032 
1033 QString KSslCipher::authenticationMethod() const
1034 {
1035  return d->authenticationMethod;
1036 }
1037 
1038 
1039 QString KSslCipher::encryptionMethod() const
1040 {
1041  return d->encryptionMethod;
1042 }
1043 
1044 
1045 QString KSslCipher::keyExchangeMethod() const
1046 {
1047  return d->keyExchangeMethod;
1048 }
1049 
1050 
1051 QString KSslCipher::digestMethod() const
1052 {
1053  //### This is not really backend neutral. It works for OpenSSL and
1054  // for RFC compliant names, though.
1055  if (d->name.endsWith(QLatin1String("SHA")))
1056  return QString::fromLatin1("SHA-1");
1057  else if (d->name.endsWith(QLatin1String("MD5")))
1058  return QString::fromLatin1("MD5");
1059  else
1060  return QString::fromLatin1(""); // ## probably QString() is enough
1061 }
1062 
1063 
1064 QString KSslCipher::name() const
1065 {
1066  return d->name;
1067 }
1068 
1069 
1070 int KSslCipher::supportedBits() const
1071 {
1072  return d->supportedBits;
1073 }
1074 
1075 
1076 int KSslCipher::usedBits() const
1077 {
1078  return d->usedBits;
1079 }
1080 
1081 
1082 //static
1083 QList<KSslCipher> KSslCipher::supportedCiphers()
1084 {
1085  QList<KSslCipher> ret;
1086  QList<QSslCipher> candidates = QSslSocket::supportedCiphers();
1087  foreach(const QSslCipher &c, candidates) {
1088  ret.append(KSslCipher(c));
1089  }
1090  return ret;
1091 }
1092 
1093 
1094 KSslErrorUiData::KSslErrorUiData()
1095  : d(new Private())
1096 {
1097  d->usedBits = 0;
1098  d->bits = 0;
1099 }
1100 
1101 
1102 KSslErrorUiData::KSslErrorUiData(const KTcpSocket *socket)
1103  : d(new Private())
1104 {
1105  d->certificateChain = socket->peerCertificateChain();
1106  d->sslErrors = socket->sslErrors();
1107  d->ip = socket->peerAddress().toString();
1108  d->host = socket->peerName();
1109  d->sslProtocol = socket->negotiatedSslVersionName();
1110  d->cipher = socket->sessionCipher().name();
1111  d->usedBits = socket->sessionCipher().usedBits();
1112  d->bits = socket->sessionCipher().supportedBits();
1113 }
1114 
1115 KSslErrorUiData::KSslErrorUiData(const QSslSocket *socket)
1116  : d(new Private())
1117 {
1118  d->certificateChain = socket->peerCertificateChain();
1119 
1120  // See KTcpSocket::sslErrors()
1121  foreach (const QSslError &e, socket->sslErrors())
1122  d->sslErrors.append(KSslError(e));
1123 
1124  d->ip = socket->peerAddress().toString();
1125  d->host = socket->peerName();
1126  if (socket->isEncrypted()) {
1127  d->sslProtocol = socket->sessionCipher().protocolString();
1128  }
1129  d->cipher = socket->sessionCipher().name();
1130  d->usedBits = socket->sessionCipher().usedBits();
1131  d->bits = socket->sessionCipher().supportedBits();
1132 }
1133 
1134 
1135 KSslErrorUiData::KSslErrorUiData(const KSslErrorUiData &other)
1136  : d(new Private(*other.d))
1137 {}
1138 
1139 KSslErrorUiData::~KSslErrorUiData()
1140 {
1141  delete d;
1142 }
1143 
1144 KSslErrorUiData &KSslErrorUiData::operator=(const KSslErrorUiData &other)
1145 {
1146  *d = *other.d;
1147  return *this;
1148 }
1149 
1150 
1151 #include "ktcpsocket.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2013 The KDE developers.
Generated on Sat Jun 1 2013 12:05:04 by doxygen 1.8.1.1 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.10.4 API Reference

Skip menu "kdelibs-4.10.4 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