• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdeio
 

tdeio/tdeio

  • tdeio
  • tdeio
tcpslavebase.cpp
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2000 Alex Zepeda <zipzippy@sonic.net
5  * Copyright (C) 2001-2003 George Staikos <staikos@kde.org>
6  * Copyright (C) 2001 Dawit Alemayehu <adawit@kde.org>
7  *
8  * This file is part of the KDE project
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Library General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * Library General Public License for more details.
19  *
20  * You should have received a copy of the GNU Library General Public License
21  * along with this library; see the file COPYING.LIB. If not, write to
22  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23  * Boston, MA 02110-1301, USA.
24  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
29 
30 #include <sys/types.h>
31 #include <sys/uio.h>
32 #include <sys/time.h>
33 #include <sys/socket.h>
34 
35 #include <netinet/in.h>
36 
37 #include <time.h>
38 #include <netdb.h>
39 #include <unistd.h>
40 #include <errno.h>
41 
42 #include <ksocks.h>
43 #include <kdebug.h>
44 #include <ksslall.h>
45 #include <ksslcertdlg.h>
46 #include <tdemessagebox.h>
47 #ifndef Q_WS_WIN //temporary
48 #include <kresolver.h>
49 #endif
50 
51 #include <tdelocale.h>
52 #include <dcopclient.h>
53 #include <tqcstring.h>
54 #include <tqdatastream.h>
55 
56 #include <tdeapplication.h>
57 
58 #include <tdeprotocolmanager.h>
59 #include <kde_file.h>
60 
61 #include "tdeio/tcpslavebase.h"
62 
63 using namespace TDEIO;
64 
65 class TCPSlaveBase::TcpSlaveBasePrivate
66 {
67 public:
68 
69  TcpSlaveBasePrivate() : rblockSz(256), militantSSL(false), userAborted(false) {}
70  ~TcpSlaveBasePrivate() {}
71 
72  KSSL *kssl;
73  bool usingTLS;
74  KSSLCertificateCache *cc;
75  TQString host;
76  TQString realHost;
77  TQString ip;
78  DCOPClient *dcc;
79  KSSLPKCS12 *pkcs;
80 
81  int status;
82  int timeout;
83  int rblockSz; // Size for reading blocks in readLine()
84  bool block;
85  bool useSSLTunneling;
86  bool needSSLHandShake;
87  bool militantSSL; // If true, we just drop a connection silently
88  // if SSL certificate check fails in any way.
89  bool userAborted;
90  MetaData savedMetaData;
91 };
92 
93 
94 TCPSlaveBase::TCPSlaveBase(unsigned short int defaultPort,
95  const TQCString &protocol,
96  const TQCString &poolSocket,
97  const TQCString &appSocket)
98  :SlaveBase (protocol, poolSocket, appSocket),
99  m_iSock(-1),
100  m_iDefaultPort(defaultPort),
101  m_sServiceName(protocol),
102  fp(0)
103 {
104  // We have to have two constructors, so don't add anything
105  // else in here. Put it in doConstructorStuff() instead.
106  doConstructorStuff();
107  m_bIsSSL = false;
108 }
109 
110 TCPSlaveBase::TCPSlaveBase(unsigned short int defaultPort,
111  const TQCString &protocol,
112  const TQCString &poolSocket,
113  const TQCString &appSocket,
114  bool useSSL)
115  :SlaveBase (protocol, poolSocket, appSocket),
116  m_iSock(-1),
117  m_bIsSSL(useSSL),
118  m_iDefaultPort(defaultPort),
119  m_sServiceName(protocol),
120  fp(0)
121 {
122  doConstructorStuff();
123  if (useSSL)
124  m_bIsSSL = initializeSSL();
125 }
126 
127 // The constructor procedures go here now.
128 void TCPSlaveBase::doConstructorStuff()
129 {
130  d = new TcpSlaveBasePrivate;
131  d->kssl = 0L;
132  d->ip = "";
133  d->cc = 0L;
134  d->usingTLS = false;
135  d->dcc = 0L;
136  d->pkcs = 0L;
137  d->status = -1;
138  d->timeout = KProtocolManager::connectTimeout();
139  d->block = false;
140  d->useSSLTunneling = false;
141 }
142 
143 TCPSlaveBase::~TCPSlaveBase()
144 {
145  cleanSSL();
146  if (d->usingTLS) delete d->kssl;
147  if (d->dcc) delete d->dcc;
148  if (d->pkcs) delete d->pkcs;
149  delete d;
150 }
151 
152 ssize_t TCPSlaveBase::write(const void *data, ssize_t len)
153 {
154 #ifdef Q_OS_UNIX
155  if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling )
156  {
157  if ( d->needSSLHandShake )
158  (void) doSSLHandShake( true );
159  return d->kssl->write(data, len);
160  }
161  return KSocks::self()->write(m_iSock, data, len);
162 #else
163  return 0;
164 #endif
165 }
166 
167 ssize_t TCPSlaveBase::read(void *data, ssize_t len)
168 {
169 #ifdef Q_OS_UNIX
170  if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling )
171  {
172  if ( d->needSSLHandShake )
173  (void) doSSLHandShake( true );
174  return d->kssl->read(data, len);
175  }
176  return KSocks::self()->read(m_iSock, data, len);
177 #else
178  return 0;
179 #endif
180 }
181 
182 
183 void TCPSlaveBase::setBlockSize(int sz)
184 {
185  if (sz <= 0)
186  sz = 1;
187 
188  d->rblockSz = sz;
189 }
190 
191 
192 ssize_t TCPSlaveBase::readLine(char *data, ssize_t len)
193 {
194 // Optimization:
195 // It's small, but it probably results in a gain on very high
196 // speed connections. I moved 3 if statements out of the while loop
197 // so that the while loop is as small as possible. (GS)
198 
199  // let's not segfault!
200  if (!data)
201  return -1;
202 
203  char tmpbuf[1024]; // 1kb temporary buffer for peeking
204  *data = 0;
205  ssize_t clen = 0;
206  char *buf = data;
207  int rc = 0;
208 
209 if ((m_bIsSSL || d->usingTLS) && !d->useSSLTunneling) { // SSL CASE
210  if ( d->needSSLHandShake )
211  (void) doSSLHandShake( true );
212 
213  while (clen < len-1) {
214  rc = d->kssl->pending();
215  if (rc > 0) { // Read a chunk
216  int bytes = rc;
217  if (bytes > d->rblockSz)
218  bytes = d->rblockSz;
219 
220  rc = d->kssl->peek(tmpbuf, bytes);
221  if (rc <= 0) {
222  // FIXME: this doesn't cover rc == 0 case
223  return -1;
224  }
225 
226  bytes = rc; // in case it contains no \n
227  for (int i = 0; i < rc; i++) {
228  if (tmpbuf[i] == '\n') {
229  bytes = i+1;
230  break;
231  }
232  }
233 
234  if (bytes+clen >= len) // don't read too much!
235  bytes = len - clen - 1;
236 
237  rc = d->kssl->read(buf, bytes);
238  if (rc > 0) {
239  clen += rc;
240  buf += (rc-1);
241  if (*buf++ == '\n')
242  break;
243  } else {
244  // FIXME: different case if rc == 0;
245  return -1;
246  }
247  } else { // Read a byte
248  rc = d->kssl->read(buf, 1);
249  if (rc <= 0) {
250  return -1;
251  // hm rc = 0 then
252  // SSL_read says to call SSL_get_error to see if
253  // this was an error. FIXME
254  } else {
255  clen++;
256  if (*buf++ == '\n')
257  break;
258  }
259  }
260  }
261 } else { // NON SSL CASE
262  while (clen < len-1) {
263 #ifdef Q_OS_UNIX
264  rc = KSocks::self()->read(m_iSock, buf, 1);
265 #else
266  rc = 0;
267 #endif
268  if (rc <= 0) {
269  // FIXME: this doesn't cover rc == 0 case
270  return -1;
271  } else {
272  clen++;
273  if (*buf++ == '\n')
274  break;
275  }
276  }
277 }
278 
279  // Both cases fall through to here
280  *buf = 0;
281 return clen;
282 }
283 
284 unsigned short int TCPSlaveBase::port(unsigned short int _p)
285 {
286  unsigned short int p = _p;
287 
288  if (_p <= 0)
289  {
290  p = m_iDefaultPort;
291  }
292 
293  return p;
294 }
295 
296 // This function is simply a wrapper to establish the connection
297 // to the server. It's a bit more complicated than ::connect
298 // because we first have to check to see if the user specified
299 // a port, and if so use it, otherwise we check to see if there
300 // is a port specified in /etc/services, and if so use that
301 // otherwise as a last resort use the supplied default port.
302 bool TCPSlaveBase::connectToHost( const TQString &host,
303  unsigned int _port,
304  bool sendError )
305 {
306 #ifdef Q_OS_UNIX
307  unsigned short int p;
308  KExtendedSocket ks;
309 
310  d->userAborted = false;
311 
312  // - leaving SSL - warn before we even connect
313  if (metaData("main_frame_request") == "TRUE" &&
314  metaData("ssl_activate_warnings") == "TRUE" &&
315  metaData("ssl_was_in_use") == "TRUE" &&
316  !m_bIsSSL) {
317  KSSLSettings kss;
318  if (kss.warnOnLeave()) {
319  int result = messageBox( i18n("You are about to leave secure "
320  "mode. Transmissions will no "
321  "longer be encrypted.\nThis "
322  "means that a third party could "
323  "observe your data in transit."),
324  WarningContinueCancel,
325  i18n("Security Information"),
326  i18n("C&ontinue Loading"), TQString::null,
327  "WarnOnLeaveSSLMode" );
328 
329  // Move this setting into KSSL instead
330  TDEConfig *config = new TDEConfig("tdeioslaverc");
331  config->setGroup("Notification Messages");
332 
333  if (!config->readBoolEntry("WarnOnLeaveSSLMode", true)) {
334  config->deleteEntry("WarnOnLeaveSSLMode");
335  config->sync();
336  kss.setWarnOnLeave(false);
337  kss.save();
338  }
339  delete config;
340 
341  if ( result == KMessageBox::Cancel ) {
342  d->userAborted = true;
343  return false;
344  }
345  }
346  }
347 
348  d->status = -1;
349  d->host = host;
350  d->needSSLHandShake = m_bIsSSL;
351  p = port(_port);
352  ks.setAddress(host, p);
353  if ( d->timeout > -1 )
354  ks.setTimeout( d->timeout );
355 
356  if (ks.connect() < 0)
357  {
358  d->status = ks.status();
359  if ( sendError )
360  {
361  if (d->status == IO_LookupError)
362  error( ERR_UNKNOWN_HOST, host);
363  else if ( d->status != -1 )
364  error( ERR_COULD_NOT_CONNECT, host);
365  }
366  return false;
367  }
368 
369  m_iSock = ks.fd();
370 
371  // store the IP for later
372  const TDESocketAddress *sa = ks.peerAddress();
373  if (sa)
374  d->ip = sa->nodeName();
375  else
376  d->ip = "";
377 
378  ks.release(); // KExtendedSocket no longer applicable
379 
380  if ( d->block != ks.blockingMode() )
381  ks.setBlockingMode( d->block );
382 
383  m_iPort=p;
384 
385  if (m_bIsSSL && !d->useSSLTunneling) {
386  if ( !doSSLHandShake( sendError ) )
387  return false;
388  }
389  else
390  setMetaData("ssl_in_use", "FALSE");
391 
392  // Since we want to use stdio on the socket,
393  // we must fdopen it to get a file pointer,
394  // if it fails, close everything up
395  if ((fp = KDE_fdopen(m_iSock, "w+")) == 0) {
396  closeDescriptor();
397  return false;
398  }
399 
400  return true;
401 #else
402  return false;
403 #endif //Q_OS_UNIX
404 }
405 
406 void TCPSlaveBase::closeDescriptor()
407 {
408  stopTLS();
409  if (fp) {
410  fclose(fp);
411  fp=0;
412  m_iSock=-1;
413  if (m_bIsSSL)
414  d->kssl->close();
415  }
416  if (m_iSock != -1) {
417  close(m_iSock);
418  m_iSock=-1;
419  }
420  d->ip = "";
421  d->host = "";
422 }
423 
424 bool TCPSlaveBase::initializeSSL()
425 {
426  if (m_bIsSSL) {
427  if (KSSL::doesSSLWork()) {
428  d->kssl = new KSSL;
429  return true;
430  }
431  }
432 return false;
433 }
434 
435 void TCPSlaveBase::cleanSSL()
436 {
437  delete d->cc;
438 
439  if (m_bIsSSL) {
440  delete d->kssl;
441  d->kssl = 0;
442  }
443  d->militantSSL = false;
444 }
445 
446 bool TCPSlaveBase::atEnd()
447 {
448  return feof(fp);
449 }
450 
451 int TCPSlaveBase::startTLS()
452 {
453  if (d->usingTLS || d->useSSLTunneling || m_bIsSSL || !KSSL::doesSSLWork())
454  return false;
455 
456  d->kssl = new KSSL(false);
457  if (!d->kssl->TLSInit()) {
458  delete d->kssl;
459  return -1;
460  }
461 
462  if ( !d->realHost.isEmpty() )
463  {
464  kdDebug(7029) << "Setting real hostname: " << d->realHost << endl;
465  d->kssl->setPeerHost(d->realHost);
466  } else {
467  kdDebug(7029) << "Setting real hostname: " << d->host << endl;
468  d->kssl->setPeerHost(d->host);
469  }
470 
471  if (hasMetaData("ssl_session_id")) {
472  KSSLSession *s = KSSLSession::fromString(metaData("ssl_session_id"));
473  if (s) {
474  d->kssl->takeSession(s);
475  delete s;
476  }
477  }
478  certificatePrompt();
479 
480  int rc = d->kssl->connect(m_iSock);
481  if (rc < 0) {
482  delete d->kssl;
483  return -2;
484  }
485 
486  setMetaData("ssl_session_id", d->kssl->session()->toString());
487 
488  d->usingTLS = true;
489  setMetaData("ssl_in_use", "TRUE");
490 
491  if (!d->kssl->reusingSession()) {
492  rc = verifyCertificate();
493  if (rc != 1) {
494  setMetaData("ssl_in_use", "FALSE");
495  d->usingTLS = false;
496  delete d->kssl;
497  return -3;
498  }
499  }
500 
501  d->savedMetaData = mOutgoingMetaData;
502  return (d->usingTLS ? 1 : 0);
503 }
504 
505 
506 void TCPSlaveBase::stopTLS()
507 {
508  if (d->usingTLS) {
509  delete d->kssl;
510  d->usingTLS = false;
511  setMetaData("ssl_in_use", "FALSE");
512  }
513 }
514 
515 
516 void TCPSlaveBase::setSSLMetaData() {
517  if (!(d->usingTLS || d->useSSLTunneling || m_bIsSSL))
518  return;
519 
520  mOutgoingMetaData = d->savedMetaData;
521 }
522 
523 
524 bool TCPSlaveBase::canUseTLS()
525 {
526  if (m_bIsSSL || d->needSSLHandShake || !KSSL::doesSSLWork())
527  return false;
528 
529  KSSLSettings kss;
530  return kss.tlsv1();
531 }
532 
533 
534 void TCPSlaveBase::certificatePrompt()
535 {
536 TQString certname; // the cert to use this session
537 bool send = false, prompt = false, save = false, forcePrompt = false;
538 KSSLCertificateHome::KSSLAuthAction aa;
539 
540  setMetaData("ssl_using_client_cert", "FALSE"); // we change this if needed
541 
542  if (metaData("ssl_no_client_cert") == "TRUE") return;
543  forcePrompt = (metaData("ssl_force_cert_prompt") == "TRUE");
544 
545  // Delete the old cert since we're certainly done with it now
546  if (d->pkcs) {
547  delete d->pkcs;
548  d->pkcs = NULL;
549  }
550 
551  if (!d->kssl) return;
552 
553  // Look for a general certificate
554  if (!forcePrompt) {
555  certname = KSSLCertificateHome::getDefaultCertificateName(&aa);
556  switch(aa) {
557  case KSSLCertificateHome::AuthSend:
558  send = true; prompt = false;
559  break;
560  case KSSLCertificateHome::AuthDont:
561  send = false; prompt = false;
562  certname = TQString::null;
563  break;
564  case KSSLCertificateHome::AuthPrompt:
565  send = false; prompt = true;
566  break;
567  default:
568  break;
569  }
570  }
571 
572  TQString ourHost;
573  if (!d->realHost.isEmpty()) {
574  ourHost = d->realHost;
575  } else {
576  ourHost = d->host;
577  }
578 
579  // Look for a certificate on a per-host basis as an override
580  TQString tmpcn = KSSLCertificateHome::getDefaultCertificateName(ourHost, &aa);
581  if (aa != KSSLCertificateHome::AuthNone) { // we must override
582  switch (aa) {
583  case KSSLCertificateHome::AuthSend:
584  send = true;
585  prompt = false;
586  certname = tmpcn;
587  break;
588  case KSSLCertificateHome::AuthDont:
589  send = false;
590  prompt = false;
591  certname = TQString::null;
592  break;
593  case KSSLCertificateHome::AuthPrompt:
594  send = false;
595  prompt = true;
596  certname = tmpcn;
597  break;
598  default:
599  break;
600  }
601  }
602 
603  // Finally, we allow the application to override anything.
604  if (hasMetaData("ssl_demand_certificate")) {
605  certname = metaData("ssl_demand_certificate");
606  if (!certname.isEmpty()) {
607  forcePrompt = false;
608  prompt = false;
609  send = true;
610  }
611  }
612 
613  if (certname.isEmpty() && !prompt && !forcePrompt) return;
614 
615  // Ok, we're supposed to prompt the user....
616  if (prompt || forcePrompt) {
617  TQStringList certs = KSSLCertificateHome::getCertificateList();
618 
619  for (TQStringList::Iterator it = certs.begin(); it != certs.end(); ++it) {
620  KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(*it);
621  if (pkcs && (!pkcs->getCertificate() ||
622  !pkcs->getCertificate()->x509V3Extensions().certTypeSSLClient())) {
623  certs.remove(*it);
624  }
625  delete pkcs;
626  }
627 
628  if (certs.isEmpty()) return; // we had nothing else, and prompt failed
629 
630  if (!d->dcc) {
631  d->dcc = new DCOPClient;
632  d->dcc->attach();
633  if (!d->dcc->isApplicationRegistered("tdeio_uiserver")) {
634  TDEApplication::startServiceByDesktopPath("tdeio_uiserver.desktop",
635  TQStringList() );
636  }
637  }
638 
639  TQByteArray data, retval;
640  TQCString rettype;
641  TQDataStream arg(data, IO_WriteOnly);
642  arg << ourHost;
643  arg << certs;
644  arg << metaData("window-id").toInt();
645  bool rc = d->dcc->call("tdeio_uiserver", "UIServer",
646  "showSSLCertDialog(TQString, TQStringList,int)",
647  data, rettype, retval);
648 
649  if (rc && rettype == "KSSLCertDlgRet") {
650  TQDataStream retStream(retval, IO_ReadOnly);
651  KSSLCertDlgRet drc;
652  retStream >> drc;
653  if (drc.ok) {
654  send = drc.send;
655  save = drc.save;
656  certname = drc.choice;
657  }
658  }
659  }
660 
661  // The user may have said to not send the certificate,
662  // but to save the choice
663  if (!send) {
664  if (save) {
665  KSSLCertificateHome::setDefaultCertificate(certname, ourHost,
666  false, false);
667  }
668  return;
669  }
670 
671  // We're almost committed. If we can read the cert, we'll send it now.
672  KSSLPKCS12 *pkcs = KSSLCertificateHome::getCertificateByName(certname);
673  if (!pkcs && KSSLCertificateHome::hasCertificateByName(certname)) { // We need the password
674  TDEIO::AuthInfo ai;
675  bool first = true;
676  do {
677  ai.prompt = i18n("Enter the certificate password:");
678  ai.caption = i18n("SSL Certificate Password");
679  ai.url.setProtocol("kssl");
680  ai.url.setHost(certname);
681  ai.username = certname;
682  ai.keepPassword = true;
683 
684  bool showprompt;
685  if (first)
686  showprompt = !checkCachedAuthentication(ai);
687  else
688  showprompt = true;
689  if (showprompt) {
690  if (!openPassDlg(ai, first ? TQString::null :
691  i18n("Unable to open the certificate. Try a new password?")))
692  break;
693  }
694 
695  first = false;
696  pkcs = KSSLCertificateHome::getCertificateByName(certname, ai.password);
697  } while (!pkcs);
698 
699  }
700 
701  // If we could open the certificate, let's send it
702  if (pkcs) {
703  if (!d->kssl->setClientCertificate(pkcs)) {
704  messageBox(Information, i18n("The procedure to set the "
705  "client certificate for the session "
706  "failed."), i18n("SSL"));
707  delete pkcs; // we don't need this anymore
708  pkcs = 0L;
709  } else {
710  kdDebug(7029) << "Client SSL certificate is being used." << endl;
711  setMetaData("ssl_using_client_cert", "TRUE");
712  if (save) {
713  KSSLCertificateHome::setDefaultCertificate(certname, ourHost,
714  true, false);
715  }
716  }
717  d->pkcs = pkcs;
718  }
719 }
720 
721 
722 
723 bool TCPSlaveBase::usingTLS() const
724 {
725  return d->usingTLS;
726 }
727 
728 // ### remove this for KDE4 (misses const):
729 bool TCPSlaveBase::usingTLS()
730 {
731  return d->usingTLS;
732 }
733 
734 
735 // Returns 0 for failed verification, -1 for rejected cert and 1 for ok
736 int TCPSlaveBase::verifyCertificate()
737 {
738  int rc = 0;
739  bool permacache = false;
740  bool isChild = false;
741  bool _IPmatchesCN = false;
742  int result;
743  bool doAddHost = false;
744  TQString ourHost;
745 
746  if (!d->realHost.isEmpty())
747  ourHost = d->realHost;
748  else ourHost = d->host;
749 
750  TQString theurl = TQString(m_sServiceName)+"://"+ourHost+":"+TQString::number(m_iPort);
751 
752  if (!hasMetaData("ssl_militant") || metaData("ssl_militant") == "FALSE")
753  d->militantSSL = false;
754  else if (metaData("ssl_militant") == "TRUE")
755  d->militantSSL = true;
756 
757  if (!d->cc) d->cc = new KSSLCertificateCache;
758 
759  KSSLCertificate& pc = d->kssl->peerInfo().getPeerCertificate();
760 
761  KSSLCertificate::KSSLValidationList ksvl = pc.validateVerbose(KSSLCertificate::SSLServer);
762 
763  _IPmatchesCN = d->kssl->peerInfo().certMatchesAddress();
764  if (!_IPmatchesCN) {
765 #ifndef Q_WS_WIN //temporary
766  KNetwork::KResolverResults res = KNetwork::KResolver::resolve(d->kssl->peerInfo().peerHost(), "80", KNetwork::KResolver::CanonName);
767  if (!res.isEmpty()) {
768  TQString old = d->kssl->peerInfo().peerHost();
769  d->kssl->peerInfo().setPeerHost(res[0].canonicalName());
770  _IPmatchesCN = d->kssl->peerInfo().certMatchesAddress();
771  if (!_IPmatchesCN) {
772  d->kssl->peerInfo().setPeerHost(old);
773  }
774  }
775 #endif
776  if (!_IPmatchesCN && !d->militantSSL) { // force this if the user wants it
777  if (d->cc->getHostList(pc).contains(ourHost)) {
778  _IPmatchesCN = true;
779  }
780  }
781  }
782 
783  if (!_IPmatchesCN) {
784  ksvl << KSSLCertificate::InvalidHost;
785  }
786 
787  KSSLCertificate::KSSLValidation ksv = KSSLCertificate::Ok;
788  if (!ksvl.isEmpty())
789  ksv = ksvl.first();
790 
791  /* Setting the various bits of meta-info that will be needed. */
792  setMetaData("ssl_cipher", d->kssl->connectionInfo().getCipher());
793  setMetaData("ssl_cipher_desc",
794  d->kssl->connectionInfo().getCipherDescription());
795  setMetaData("ssl_cipher_version",
796  d->kssl->connectionInfo().getCipherVersion());
797  setMetaData("ssl_cipher_used_bits",
798  TQString::number(d->kssl->connectionInfo().getCipherUsedBits()));
799  setMetaData("ssl_cipher_bits",
800  TQString::number(d->kssl->connectionInfo().getCipherBits()));
801  setMetaData("ssl_peer_ip", d->ip);
802  if (!d->realHost.isEmpty()) {
803  setMetaData("ssl_proxied", "true");
804  }
805 
806  TQString errorStr;
807  for(KSSLCertificate::KSSLValidationList::ConstIterator it = ksvl.begin();
808  it != ksvl.end(); ++it)
809  {
810  errorStr += TQString::number(*it)+":";
811  }
812  setMetaData("ssl_cert_errors", errorStr);
813  setMetaData("ssl_peer_certificate", pc.toString());
814 
815  if (pc.chain().isValid() && pc.chain().depth() > 1) {
816  TQString theChain;
817  TQPtrList<KSSLCertificate> chain = pc.chain().getChain();
818  chain.setAutoDelete(true);
819  for (KSSLCertificate *c = chain.first(); c; c = chain.next()) {
820  theChain += c->toString();
821  theChain += "\n";
822  }
823  setMetaData("ssl_peer_chain", theChain);
824  } else setMetaData("ssl_peer_chain", "");
825 
826  setMetaData("ssl_cert_state", TQString::number(ksv));
827 
828  if (ksv == KSSLCertificate::Ok) {
829  rc = 1;
830  setMetaData("ssl_action", "accept");
831  }
832 
833  kdDebug(7029) << "SSL HTTP frame the parent? " << metaData("main_frame_request") << endl;
834  if (!hasMetaData("main_frame_request") || metaData("main_frame_request") == "TRUE") {
835  // Since we're the parent, we need to teach the child.
836  setMetaData("ssl_parent_ip", d->ip);
837  setMetaData("ssl_parent_cert", pc.toString());
838  // - Read from cache and see if there is a policy for this
839  KSSLCertificateCache::KSSLCertificatePolicy cp =
840  d->cc->getPolicyByCertificate(pc);
841 
842  // - validation code
843  if (ksv != KSSLCertificate::Ok) {
844  if (d->militantSSL) {
845  return -1;
846  }
847 
848  if (cp == KSSLCertificateCache::Unknown ||
849  cp == KSSLCertificateCache::Ambiguous) {
850  cp = KSSLCertificateCache::Prompt;
851  } else {
852  // A policy was already set so let's honor that.
853  permacache = d->cc->isPermanent(pc);
854  }
855 
856 /*
857  if (!_IPmatchesCN && cp == KSSLCertificateCache::Accept) {
858  cp = KSSLCertificateCache::Prompt;
859 // ksv = KSSLCertificate::Ok;
860  }
861 */
862 
863  // Precondition: cp is one of Reject, Accept or Prompt
864  switch (cp) {
865  case KSSLCertificateCache::Accept:
866  rc = 1;
867  setMetaData("ssl_action", "accept");
868  break;
869  case KSSLCertificateCache::Reject:
870  rc = -1;
871  setMetaData("ssl_action", "reject");
872  break;
873  case KSSLCertificateCache::Prompt:
874  {
875  do {
876  if (ksv == KSSLCertificate::InvalidHost) {
877  TQString msg = i18n("The IP address of the host %1 "
878  "does not match the one the "
879  "certificate was issued to.");
880  result = messageBox( WarningYesNoCancel,
881  msg.arg(ourHost),
882  i18n("Server Authentication"),
883  i18n("&Details"),
884  i18n("Co&ntinue") );
885  } else {
886  TQString msg = i18n("The server certificate failed the "
887  "authenticity test (%1).");
888  result = messageBox( WarningYesNoCancel,
889  msg.arg(ourHost),
890  i18n("Server Authentication"),
891  i18n("&Details"),
892  i18n("Co&ntinue") );
893  }
894 
895  if (result == KMessageBox::Yes) {
896  if (!d->dcc) {
897  d->dcc = new DCOPClient;
898  d->dcc->attach();
899  if (!d->dcc->isApplicationRegistered("tdeio_uiserver")) {
900  TDEApplication::startServiceByDesktopPath("tdeio_uiserver.desktop",
901  TQStringList() );
902  }
903 
904  }
905  TQByteArray data, ignore;
906  TQCString ignoretype;
907  TQDataStream arg(data, IO_WriteOnly);
908  arg << theurl << mOutgoingMetaData;
909  arg << metaData("window-id").toInt();
910  d->dcc->call("tdeio_uiserver", "UIServer",
911  "showSSLInfoDialog(TQString,TDEIO::MetaData,int)",
912  data, ignoretype, ignore);
913  }
914  } while (result == KMessageBox::Yes);
915 
916  if (result == KMessageBox::No) {
917  setMetaData("ssl_action", "accept");
918  rc = 1;
919  cp = KSSLCertificateCache::Accept;
920  doAddHost = true;
921  result = messageBox( WarningYesNo,
922  i18n("Would you like to accept this "
923  "certificate forever without "
924  "being prompted?"),
925  i18n("Server Authentication"),
926  i18n("&Forever"),
927  i18n("&Current Sessions Only"));
928  if (result == KMessageBox::Yes)
929  permacache = true;
930  else
931  permacache = false;
932  } else {
933  setMetaData("ssl_action", "reject");
934  rc = -1;
935  cp = KSSLCertificateCache::Prompt;
936  }
937  break;
938  }
939  default:
940  kdDebug(7029) << "TCPSlaveBase/SSL error in cert code."
941  << "Please report this to kfm-devel@kde.org."
942  << endl;
943  break;
944  }
945  }
946 
947 
948  // - cache the results
949  d->cc->addCertificate(pc, cp, permacache);
950  if (doAddHost) d->cc->addHost(pc, ourHost);
951  } else { // Child frame
952  // - Read from cache and see if there is a policy for this
953  KSSLCertificateCache::KSSLCertificatePolicy cp =
954  d->cc->getPolicyByCertificate(pc);
955  isChild = true;
956 
957  // Check the cert and IP to make sure they're the same
958  // as the parent frame
959  bool certAndIPTheSame = (d->ip == metaData("ssl_parent_ip") &&
960  pc.toString() == metaData("ssl_parent_cert"));
961 
962  if (ksv == KSSLCertificate::Ok) {
963  if (certAndIPTheSame) { // success
964  rc = 1;
965  setMetaData("ssl_action", "accept");
966  } else {
967  /*
968  if (d->militantSSL) {
969  return -1;
970  }
971  result = messageBox(WarningYesNo,
972  i18n("The certificate is valid but does not appear to have been assigned to this server. Do you wish to continue loading?"),
973  i18n("Server Authentication"));
974  if (result == KMessageBox::Yes) { // success
975  rc = 1;
976  setMetaData("ssl_action", "accept");
977  } else { // fail
978  rc = -1;
979  setMetaData("ssl_action", "reject");
980  }
981  */
982  setMetaData("ssl_action", "accept");
983  rc = 1; // Let's accept this now. It's bad, but at least the user
984  // will see potential attacks in KDE3 with the pseudo-lock
985  // icon on the toolbar, and can investigate with the RMB
986  }
987  } else {
988  if (d->militantSSL) {
989  return -1;
990  }
991 
992  if (cp == KSSLCertificateCache::Accept) {
993  if (certAndIPTheSame) { // success
994  rc = 1;
995  setMetaData("ssl_action", "accept");
996  } else { // fail
997  result = messageBox(WarningYesNo,
998  i18n("You have indicated that you wish to accept this certificate, but it is not issued to the server who is presenting it. Do you wish to continue loading?"),
999  i18n("Server Authentication"));
1000  if (result == KMessageBox::Yes) {
1001  rc = 1;
1002  setMetaData("ssl_action", "accept");
1003  d->cc->addHost(pc, ourHost);
1004  } else {
1005  rc = -1;
1006  setMetaData("ssl_action", "reject");
1007  }
1008  }
1009  } else if (cp == KSSLCertificateCache::Reject) { // fail
1010  messageBox(Information, i18n("SSL certificate is being rejected as requested. You can disable this in the Trinity Control Center."),
1011  i18n("Server Authentication"));
1012  rc = -1;
1013  setMetaData("ssl_action", "reject");
1014  } else {
1015  do {
1016  TQString msg = i18n("The server certificate failed the "
1017  "authenticity test (%1).");
1018  result = messageBox(WarningYesNoCancel,
1019  msg.arg(ourHost),
1020  i18n("Server Authentication"),
1021  i18n("&Details"),
1022  i18n("Co&nnect"));
1023  if (result == KMessageBox::Yes) {
1024  if (!d->dcc) {
1025  d->dcc = new DCOPClient;
1026  d->dcc->attach();
1027  if (!d->dcc->isApplicationRegistered("tdeio_uiserver")) {
1028  TDEApplication::startServiceByDesktopPath("tdeio_uiserver.desktop",
1029  TQStringList() );
1030  }
1031  }
1032  TQByteArray data, ignore;
1033  TQCString ignoretype;
1034  TQDataStream arg(data, IO_WriteOnly);
1035  arg << theurl << mOutgoingMetaData;
1036  arg << metaData("window-id").toInt();
1037  d->dcc->call("tdeio_uiserver", "UIServer",
1038  "showSSLInfoDialog(TQString,TDEIO::MetaData,int)",
1039  data, ignoretype, ignore);
1040  }
1041  } while (result == KMessageBox::Yes);
1042 
1043  if (result == KMessageBox::No) {
1044  setMetaData("ssl_action", "accept");
1045  rc = 1;
1046  cp = KSSLCertificateCache::Accept;
1047  result = messageBox(WarningYesNo,
1048  i18n("Would you like to accept this "
1049  "certificate forever without "
1050  "being prompted?"),
1051  i18n("Server Authentication"),
1052  i18n("&Forever"),
1053  i18n("&Current Sessions Only"));
1054  permacache = (result == KMessageBox::Yes);
1055  d->cc->addCertificate(pc, cp, permacache);
1056  d->cc->addHost(pc, ourHost);
1057  } else {
1058  setMetaData("ssl_action", "reject");
1059  rc = -1;
1060  cp = KSSLCertificateCache::Prompt;
1061  d->cc->addCertificate(pc, cp, permacache);
1062  }
1063  }
1064  }
1065  }
1066 
1067 
1068  if (rc == -1) {
1069  return rc;
1070  }
1071 
1072  if (metaData("ssl_activate_warnings") == "TRUE") {
1073  // - entering SSL
1074  if (!isChild && metaData("ssl_was_in_use") == "FALSE" &&
1075  d->kssl->settings()->warnOnEnter()) {
1076  int result;
1077  do {
1078  result = messageBox( i18n("You are about to "
1079  "enter secure mode. "
1080  "All transmissions "
1081  "will be encrypted "
1082  "unless otherwise "
1083  "noted.\nThis means "
1084  "that no third party "
1085  "will be able to "
1086  "easily observe your "
1087  "data in transit."),
1088  WarningYesNo,
1089  i18n("Security Information"),
1090  i18n("Display SSL "
1091  "&Information"),
1092  i18n("C&onnect"),
1093  "WarnOnEnterSSLMode" );
1094  // Move this setting into KSSL instead
1095  TDEConfig *config = new TDEConfig("tdeioslaverc");
1096  config->setGroup("Notification Messages");
1097 
1098  bool dialogBoxStatus = false;
1099  if( config->hasKey("WarnOnEnterSSLMode") ) {
1100  dialogBoxStatus = true;
1101  }
1102  bool keyStatus = config->readBoolEntry("WarnOnEnterSSLMode", true);
1103  dialogBoxStatus = dialogBoxStatus && keyStatus;
1104  if (!keyStatus) {
1105  config->deleteEntry("WarnOnEnterSSLMode");
1106  config->sync();
1107  d->kssl->settings()->setWarnOnEnter(false);
1108  d->kssl->settings()->save();
1109  }
1110  delete config;
1111 
1112  if ( result == KMessageBox::Yes )
1113  {
1114  if (!d->dcc) {
1115  d->dcc = new DCOPClient;
1116  d->dcc->attach();
1117  if (!d->dcc->isApplicationRegistered("tdeio_uiserver")) {
1118  TDEApplication::startServiceByDesktopPath("tdeio_uiserver.desktop",
1119  TQStringList() );
1120  }
1121  }
1122  TQByteArray data, ignore;
1123  TQCString ignoretype;
1124  TQDataStream arg(data, IO_WriteOnly);
1125  arg << theurl << mOutgoingMetaData;
1126  arg << metaData("window-id").toInt();
1127  d->dcc->call("tdeio_uiserver", "UIServer",
1128  "showSSLInfoDialog(TQString,TDEIO::MetaData,int)",
1129  data, ignoretype, ignore);
1130  }
1131  //Laurent: If we disable message box we can't click on KMessageBox::No
1132  if(dialogBoxStatus) {
1133  break;
1134  }
1135  } while (result != KMessageBox::No);
1136  }
1137 
1138  } // if ssl_activate_warnings
1139 
1140 
1141  kdDebug(7029) << "SSL connection information follows:" << endl
1142  << "+-----------------------------------------------" << endl
1143  << "| Cipher: " << d->kssl->connectionInfo().getCipher() << endl
1144  << "| Description: " << d->kssl->connectionInfo().getCipherDescription() << endl
1145  << "| Version: " << d->kssl->connectionInfo().getCipherVersion() << endl
1146  << "| Strength: " << d->kssl->connectionInfo().getCipherUsedBits()
1147  << " of " << d->kssl->connectionInfo().getCipherBits()
1148  << " bits used." << endl
1149  << "| PEER:" << endl
1150  << "| Subject: " << d->kssl->peerInfo().getPeerCertificate().getSubject() << endl
1151  << "| Issuer: " << d->kssl->peerInfo().getPeerCertificate().getIssuer() << endl
1152  << "| Validation: " << (int)ksv << endl
1153  << "| Certificate matches IP: " << _IPmatchesCN << endl
1154  << "+-----------------------------------------------"
1155  << endl;
1156 
1157  // sendMetaData(); Do not call this function!!
1158  return rc;
1159 }
1160 
1161 
1162 bool TCPSlaveBase::isConnectionValid()
1163 {
1164  if ( m_iSock == -1 )
1165  return false;
1166 
1167  fd_set rdfs;
1168  FD_ZERO(&rdfs);
1169  FD_SET(m_iSock , &rdfs);
1170 
1171  struct timeval tv;
1172  tv.tv_usec = 0;
1173  tv.tv_sec = 0;
1174  int retval;
1175 #ifdef Q_OS_UNIX
1176  do {
1177  retval = KSocks::self()->select(m_iSock+1, &rdfs, NULL, NULL, &tv);
1178  if (wasKilled())
1179  return false; // Beam us out of here
1180  } while ((retval == -1) && (errno == EAGAIN));
1181 #else
1182  retval = -1;
1183 #endif
1184  // retval == -1 ==> Error
1185  // retval == 0 ==> Connection Idle
1186  // retval >= 1 ==> Connection Active
1187  //kdDebug(7029) << "TCPSlaveBase::isConnectionValid: select returned: "
1188  // << retval << endl;
1189 
1190  if (retval == -1)
1191  return false;
1192 
1193  if (retval == 0)
1194  return true;
1195 
1196  // Connection is active, check if it has closed.
1197  char buffer[100];
1198 #ifdef Q_OS_UNIX
1199  do {
1200  retval = KSocks::self()->recv(m_iSock, buffer, 80, MSG_PEEK);
1201 
1202  } while ((retval == -1) && (errno == EAGAIN));
1203 #else
1204  retval = -1;
1205 #endif
1206  //kdDebug(7029) << "TCPSlaveBase::isConnectionValid: recv returned: "
1207  // << retval << endl;
1208  if (retval <= 0)
1209  return false; // Error or connection closed.
1210 
1211  return true; // Connection still valid.
1212 }
1213 
1214 
1215 bool TCPSlaveBase::waitForResponse( int t )
1216 {
1217  fd_set rd;
1218  struct timeval timeout;
1219 
1220  if ( (m_bIsSSL || d->usingTLS) && !d->useSSLTunneling && d->kssl )
1221  if (d->kssl->pending() > 0)
1222  return true;
1223 
1224  FD_ZERO(&rd);
1225  FD_SET(m_iSock, &rd);
1226 
1227  timeout.tv_usec = 0;
1228  timeout.tv_sec = t;
1229  time_t startTime;
1230 
1231  int rc;
1232  int n = t;
1233 
1234 reSelect:
1235  startTime = time(NULL);
1236 #ifdef Q_OS_UNIX
1237  rc = KSocks::self()->select(m_iSock+1, &rd, NULL, NULL, &timeout);
1238 #else
1239  rc = -1;
1240 #endif
1241  if (wasKilled())
1242  return false; // We're dead.
1243 
1244  if (rc == -1)
1245  return false;
1246 
1247  if (FD_ISSET(m_iSock, &rd))
1248  return true;
1249 
1250  // Well it returned but it wasn't set. Let's see if it
1251  // returned too early (perhaps from an errant signal) and
1252  // start over with the remaining time
1253  int timeDone = time(NULL) - startTime;
1254  if (timeDone < n)
1255  {
1256  n -= timeDone;
1257  timeout.tv_sec = n;
1258  goto reSelect;
1259  }
1260 
1261  return false; // Timed out!
1262 }
1263 
1264 int TCPSlaveBase::connectResult()
1265 {
1266  return d->status;
1267 }
1268 
1269 void TCPSlaveBase::setBlockConnection( bool b )
1270 {
1271  d->block = b;
1272 }
1273 
1274 void TCPSlaveBase::setConnectTimeout( int t )
1275 {
1276  d->timeout = t;
1277 }
1278 
1279 bool TCPSlaveBase::isSSLTunnelEnabled()
1280 {
1281  return d->useSSLTunneling;
1282 }
1283 
1284 void TCPSlaveBase::setEnableSSLTunnel( bool enable )
1285 {
1286  d->useSSLTunneling = enable;
1287 }
1288 
1289 void TCPSlaveBase::setRealHost( const TQString& realHost )
1290 {
1291  d->realHost = realHost;
1292 }
1293 
1294 bool TCPSlaveBase::doSSLHandShake( bool sendError )
1295 {
1296  kdDebug(7029) << "TCPSlaveBase::doSSLHandShake: " << endl;
1297  TQString msgHost = d->host;
1298 
1299  d->kssl->reInitialize();
1300 
1301  if (hasMetaData("ssl_session_id")) {
1302  KSSLSession *s = KSSLSession::fromString(metaData("ssl_session_id"));
1303  if (s) {
1304  d->kssl->takeSession(s);
1305  delete s;
1306  }
1307  }
1308  certificatePrompt();
1309 
1310  if ( !d->realHost.isEmpty() )
1311  {
1312  msgHost = d->realHost;
1313  }
1314 
1315  kdDebug(7029) << "Setting real hostname: " << msgHost << endl;
1316  d->kssl->setPeerHost(msgHost);
1317 
1318  d->status = d->kssl->connect(m_iSock);
1319  if (d->status < 0)
1320  {
1321  closeDescriptor();
1322  if ( sendError )
1323  error( ERR_COULD_NOT_CONNECT, msgHost);
1324  return false;
1325  }
1326 
1327  setMetaData("ssl_session_id", d->kssl->session()->toString());
1328  setMetaData("ssl_in_use", "TRUE");
1329 
1330  if (!d->kssl->reusingSession()) {
1331  int rc = verifyCertificate();
1332  if ( rc != 1 ) {
1333  d->status = -1;
1334  closeDescriptor();
1335  if ( sendError )
1336  error( ERR_COULD_NOT_CONNECT, msgHost);
1337  return false;
1338  }
1339  }
1340 
1341  d->needSSLHandShake = false;
1342 
1343  d->savedMetaData = mOutgoingMetaData;
1344  return true;
1345 }
1346 
1347 
1348 bool TCPSlaveBase::userAborted() const
1349 {
1350  return d->userAborted;
1351 }
1352 
1353 void TCPSlaveBase::virtual_hook( int id, void* data )
1354 { SlaveBase::virtual_hook( id, data ); }
1355 
TDEIO::TCPSlaveBase::cleanSSL
void cleanSSL()
Cleans up all SSL settings.
Definition: tcpslavebase.cpp:435
TDEIO::TCPSlaveBase::write
ssize_t write(const void *data, ssize_t len)
This function acts like standard write function call except it is also capable of making SSL or SOCKS...
Definition: tcpslavebase.cpp:152
TDEIO::SlaveBase::metaData
TQString metaData(const TQString &key) const
Queries for config/meta-data send by the application to the slave.
Definition: slavebase.cpp:360
TDEIO::TCPSlaveBase::startTLS
int startTLS()
Start using TLS on the connection.
Definition: tcpslavebase.cpp:451
TDEIO::SlaveBase
There are two classes that specifies the protocol between application (job) and tdeioslave.
Definition: slavebase.h:45
TDEIO::TCPSlaveBase::isConnectionValid
bool isConnectionValid()
Determines whether or not we are still connected to the remote machine.
Definition: tcpslavebase.cpp:1162
TDEIO::TCPSlaveBase::connectResult
int connectResult()
Returns the status of the connection.
Definition: tcpslavebase.cpp:1264
TDEIO::TCPSlaveBase::setEnableSSLTunnel
void setEnableSSLTunnel(bool enable)
Set up SSL tunneling mode.
Definition: tcpslavebase.cpp:1284
TDEIO::AuthInfo::username
TQString username
This is required for caching.
Definition: authinfo.h:99
TDEIO::SlaveBase::setMetaData
void setMetaData(const TQString &key, const TQString &value)
Sets meta-data to be send to the application before the first data() or finished() signal...
Definition: slavebase.cpp:355
TDEIO::SlaveBase::config
TDEConfigBase * config()
Returns a configuration object to query config/meta-data information from.
Definition: slavebase.cpp:386
TDEIO::SlaveBase::data
void data(const TQByteArray &data)
Sends data in the slave to the job (i.e.
Definition: slavebase.cpp:409
TDEIO
A namespace for TDEIO globals.
Definition: authinfo.h:29
TDEIO::TCPSlaveBase::setRealHost
void setRealHost(const TQString &realHost)
Sets up the the real hostname for an SSL connection that goes through a proxy server.
Definition: tcpslavebase.cpp:1289
TDEIO::AuthInfo::keepPassword
bool keepPassword
Flag to indicate the persistence of the given password.
Definition: authinfo.h:220
TDEIO::TCPSlaveBase::waitForResponse
bool waitForResponse(int t)
Wait for some type of activity on the socket for the period specified by t.
Definition: tcpslavebase.cpp:1215
TDEIO::TCPSlaveBase::setBlockSize
void setBlockSize(int sz)
Sets the maximum size of blocks read in during calls to readLine().
Definition: tcpslavebase.cpp:183
TDEIO::TCPSlaveBase::setConnectTimeout
void setConnectTimeout(int t)
Sets how long to wait for orignally connecting to the requested before timinig out.
Definition: tcpslavebase.cpp:1274
TDEIO::AuthInfo::url
KURL url
The URL for which authentication is to be stored.
Definition: authinfo.h:94
TDEIO::TCPSlaveBase::isSSLTunnelEnabled
bool isSSLTunnelEnabled()
Returns true if SSL tunneling is enabled.
Definition: tcpslavebase.cpp:1279
TDEIO::TCPSlaveBase::initializeSSL
bool initializeSSL()
Initializs all SSL variables.
Definition: tcpslavebase.cpp:424
TDEIO::TCPSlaveBase::port
unsigned short int port(unsigned short int _port)
Determines the appropriate port to use.
Definition: tcpslavebase.cpp:284
TDEIO::TCPSlaveBase::read
ssize_t read(void *data, ssize_t len)
This function acts like standard read function call except it is also capable of deciphering SSL data...
Definition: tcpslavebase.cpp:167
TDEIO::TCPSlaveBase::connectToHost
bool connectToHost(const TQString &host, unsigned int port, bool sendError=true)
Performs the initial TCP connection stuff and/or SSL handshaking as necessary.
Definition: tcpslavebase.cpp:302
KProtocolManager::connectTimeout
static int connectTimeout()
Returns the preferred timeout value for remote connections in seconds.
Definition: tdeprotocolmanager.cpp:120
TDEIO::TCPSlaveBase::usingTLS
bool usingTLS() const
Are we using TLS?
Definition: tcpslavebase.cpp:723
TDEIO::TCPSlaveBase::stopTLS
void stopTLS()
Stop using TLS on the connection.
Definition: tcpslavebase.cpp:506
TDEIO::TCPSlaveBase::readLine
ssize_t readLine(char *data, ssize_t len)
Same as above except it reads data one line at a time.
Definition: tcpslavebase.cpp:192
TDEIO::TCPSlaveBase::atEnd
bool atEnd()
Returns true when end of data is reached.
Definition: tcpslavebase.cpp:446
TDEIO::AuthInfo
This class is intended to make it easier to prompt for, cache and retrieve authorization information...
Definition: authinfo.h:51
TDEIO::SlaveBase::messageBox
int messageBox(MessageBoxType type, const TQString &text, const TQString &caption=TQString::null, const TQString &buttonYes=TQString::null, const TQString &buttonNo=TQString::null)
Call this to show a message box from the slave.
Definition: slavebase.cpp:914
TDEIO::AuthInfo::prompt
TQString prompt
Information to be displayed when prompting the user for authentication information.
Definition: authinfo.h:115
TDEIO::SlaveBase::wasKilled
bool wasKilled() const
If your ioslave was killed by a signal, wasKilled() returns true.
Definition: slavebase.cpp:1307
TDEIO::AuthInfo::caption
TQString caption
The text to displayed in the title bar of the password prompting dialog.
Definition: authinfo.h:126
TDEIO::TCPSlaveBase::closeDescriptor
void closeDescriptor()
Closes the current file descriptor.
Definition: tcpslavebase.cpp:406
TDEIO::SlaveBase::error
void error(int _errid, const TQString &_text)
Call to signal an error.
Definition: slavebase.cpp:429
TDEIO::SlaveBase::hasMetaData
bool hasMetaData(const TQString &key) const
Queries for the existence of a certain config/meta-data entry send by the application to the slave...
Definition: slavebase.cpp:369
TDEIO::TCPSlaveBase::setBlockConnection
void setBlockConnection(bool b)
Sets the mode of the connection to blocking or non-blocking.
Definition: tcpslavebase.cpp:1269
TDEIO::SlaveBase::checkCachedAuthentication
bool checkCachedAuthentication(AuthInfo &info)
Checks for cached authentication based on parameters given by info.
Definition: slavebase.cpp:1207
TDEIO::SlaveBase::openPassDlg
bool openPassDlg(TDEIO::AuthInfo &info, const TQString &errorMsg)
Prompt the user for Authorization info (login & password).
Definition: slavebase.cpp:854
TDEIO::MetaData
MetaData is a simple map of key/value strings.
Definition: global.h:515
TDEIO::TCPSlaveBase::canUseTLS
bool canUseTLS()
Can we use TLS?
Definition: tcpslavebase.cpp:524
TDEIO::AuthInfo::password
TQString password
This is required for caching.
Definition: authinfo.h:104
TDEIO::TCPSlaveBase::setSSLMetaData
void setSSLMetaData()
Call this if you use persistent connections and want all the metadata restored.
Definition: tcpslavebase.cpp:516

tdeio/tdeio

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

tdeio/tdeio

Skip menu "tdeio/tdeio"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdeio by doxygen 1.8.8
This website is maintained by Timothy Pearson.