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

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