• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • conf
smimevalidationconfigurationwidget.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  conf/smimevalidationconfigurationwidget.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2008 Klarälvdalens Datakonsult AB
6 
7  Kleopatra is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  Kleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "smimevalidationconfigurationwidget.h"
36 
37 #include "ui_smimevalidationconfigurationwidget.h"
38 
39 #include "smimevalidationpreferences.h"
40 
41 #include <kleo/cryptoconfig.h>
42 #include <kleo/cryptobackendfactory.h>
43 
44 #include <kdebug.h>
45 
46 #include <QDBusConnection>
47 
48 using namespace Kleo;
49 using namespace Kleo::Config;
50 
51 class SMimeValidationConfigurationWidget::Private {
52  friend class ::Kleo::Config::SMimeValidationConfigurationWidget;
53  SMimeValidationConfigurationWidget * const q;
54 public:
55  explicit Private( SMimeValidationConfigurationWidget * qq )
56  : q( qq ),
57  customHTTPProxyWritable( false ),
58  ui( q )
59  {
60  QDBusConnection::sessionBus().connect(QString(), QString(), QLatin1String("org.kde.kleo.CryptoConfig"), QLatin1String("changed"), q, SLOT(load()) );
61  }
62 
63  bool customHTTPProxyWritable;
64 
65 private:
66  void enableDisableActions() {
67  ui.customHTTPProxy->setEnabled( ui.useCustomHTTPProxyRB->isChecked() &&
68  !ui.disableHTTPCB->isChecked() &&
69  customHTTPProxyWritable );
70  }
71 
72 private:
73  struct UI : Ui_SMimeValidationConfigurationWidget {
74  explicit UI( SMimeValidationConfigurationWidget * q )
75  : Ui_SMimeValidationConfigurationWidget()
76  {
77  setupUi( q );
78 
79  if ( QLayout * l = q->layout() )
80  l->setMargin( 0 );
81 
82  const struct {
83  QObject * object;
84  const char * signal;
85  } sources[] = {
86  { intervalRefreshCB, SIGNAL(toggled(bool)) },
87  { intervalRefreshSB, SIGNAL(valueChanged(int)) },
88  { CRLRB, SIGNAL(toggled(bool)) },
89  { OCSPRB, SIGNAL(toggled(bool)) },
90  { OCSPResponderURL, SIGNAL(textChanged(QString)) },
91  { OCSPResponderSignature, SIGNAL(selectedCertificatesChanged(QStringList)) },
92  { doNotCheckCertPolicyCB, SIGNAL(toggled(bool)) },
93  { neverConsultCB, SIGNAL(toggled(bool)) },
94  { allowMarkTrustedCB, SIGNAL(toggled(bool)) },
95  { fetchMissingCB, SIGNAL(toggled(bool)) },
96  { ignoreServiceURLCB, SIGNAL(toggled(bool)) },
97  { ignoreHTTPDPCB, SIGNAL(toggled(bool)) },
98  { disableHTTPCB, SIGNAL(toggled(bool)) },
99  { honorHTTPProxyRB, SIGNAL(toggled(bool)) },
100  { useCustomHTTPProxyRB, SIGNAL(toggled(bool)) },
101  { customHTTPProxy, SIGNAL(textChanged(QString)) },
102  { ignoreLDAPDPCB, SIGNAL(toggled(bool)) },
103  { disableLDAPCB, SIGNAL(toggled(bool)) },
104  { customLDAPProxy, SIGNAL(textChanged(QString)) },
105  };
106  for ( unsigned int i = 0 ; i < sizeof sources / sizeof *sources ; ++i )
107  connect( sources[i].object, sources[i].signal, q, SIGNAL(changed()) );
108  connect( useCustomHTTPProxyRB, SIGNAL(toggled(bool)),
109  q, SLOT(enableDisableActions()) );
110  connect( disableHTTPCB, SIGNAL(toggled(bool)),
111  q, SLOT(enableDisableActions()) );
112 
113  OCSPResponderSignature->setOnlyX509CertificatesAllowed( true );
114  OCSPResponderSignature->setOnlySigningCertificatesAllowed( true );
115  OCSPResponderSignature->setMultipleCertificatesAllowed( false );
116  //OCSPResponderSignature->setAllowedKeys( KeySelectionDialog::TrustedKeys|KeySelectionDialog::ValidKeys );
117  }
118  } ui;
119 };
120 
121 SMimeValidationConfigurationWidget::SMimeValidationConfigurationWidget( QWidget * p, Qt::WindowFlags f )
122  : QWidget( p, f ), d( new Private( this ) )
123 {
124 
125 }
126 
127 SMimeValidationConfigurationWidget::~SMimeValidationConfigurationWidget() {}
128 
129 
130 static void disableDirmngrWidget( QWidget* w ) {
131  w->setEnabled( false );
132  w->setWhatsThis( i18n( "This option requires dirmngr >= 0.9.0" ) );
133 }
134 
135 static void initializeDirmngrCheckbox( QCheckBox* cb, CryptoConfigEntry* entry ) {
136  if ( entry )
137  cb->setChecked( entry->boolValue() );
138  if ( !entry || entry->isReadOnly() )
139  disableDirmngrWidget( cb );
140 }
141 
142 struct SMIMECryptoConfigEntries {
143  SMIMECryptoConfigEntries( CryptoConfig * config )
144  : mConfig( config ),
145  // Checkboxes
146  mCheckUsingOCSPConfigEntry( configEntry( "gpgsm", "Security", "enable-ocsp", CryptoConfigEntry::ArgType_None, false ) ),
147  mEnableOCSPsendingConfigEntry( configEntry( "dirmngr", "OCSP", "allow-ocsp", CryptoConfigEntry::ArgType_None, false ) ),
148  mDoNotCheckCertPolicyConfigEntry( configEntry( "gpgsm", "Security", "disable-policy-checks", CryptoConfigEntry::ArgType_None, false ) ),
149  mNeverConsultConfigEntry( configEntry( "gpgsm", "Security", "disable-crl-checks", CryptoConfigEntry::ArgType_None, false ) ),
150  mAllowMarkTrustedConfigEntry( configEntry( "gpg-agent", "Security", "allow-mark-trusted", CryptoConfigEntry::ArgType_None, false ) ),
151  mFetchMissingConfigEntry( configEntry( "gpgsm", "Security", "auto-issuer-key-retrieve", CryptoConfigEntry::ArgType_None, false ) ),
152  mNoAllowMarkTrustedConfigEntry( configEntry( "gpg-agent", "Security", "no-allow-mark-trusted", CryptoConfigEntry::ArgType_None, false ) ),
153  // dirmngr-0.9.0 options
154  mIgnoreServiceURLEntry( configEntry( "dirmngr", "OCSP", "ignore-ocsp-service-url", CryptoConfigEntry::ArgType_None, false ) ),
155  mIgnoreHTTPDPEntry( configEntry( "dirmngr", "HTTP", "ignore-http-dp", CryptoConfigEntry::ArgType_None, false ) ),
156  mDisableHTTPEntry( configEntry( "dirmngr", "HTTP", "disable-http", CryptoConfigEntry::ArgType_None, false ) ),
157  mHonorHTTPProxy( configEntry( "dirmngr", "HTTP", "honor-http-proxy", CryptoConfigEntry::ArgType_None, false ) ),
158  mIgnoreLDAPDPEntry( configEntry( "dirmngr", "LDAP", "ignore-ldap-dp", CryptoConfigEntry::ArgType_None, false ) ),
159  mDisableLDAPEntry( configEntry( "dirmngr", "LDAP", "disable-ldap", CryptoConfigEntry::ArgType_None, false ) ),
160  // Other widgets
161  mOCSPResponderURLConfigEntry( configEntry( "dirmngr", "OCSP", "ocsp-responder", CryptoConfigEntry::ArgType_String, false ) ),
162  mOCSPResponderSignature( configEntry( "dirmngr", "OCSP", "ocsp-signer", CryptoConfigEntry::ArgType_String, false ) ),
163  mCustomHTTPProxy( configEntry( "dirmngr", "HTTP", "http-proxy", CryptoConfigEntry::ArgType_String, false ) ),
164  mCustomLDAPProxy( configEntry( "dirmngr", "LDAP", "ldap-proxy", CryptoConfigEntry::ArgType_String, false ) )
165  {
166 
167  }
168 
169  CryptoConfigEntry* configEntry( const char* componentName,
170  const char* groupName,
171  const char* entryName,
172  int argType,
173  bool isList );
174 
175  CryptoConfig * const mConfig;
176 
177  // Checkboxes
178  CryptoConfigEntry * const mCheckUsingOCSPConfigEntry;
179  CryptoConfigEntry * const mEnableOCSPsendingConfigEntry;
180  CryptoConfigEntry * const mDoNotCheckCertPolicyConfigEntry;
181  CryptoConfigEntry * const mNeverConsultConfigEntry;
182  CryptoConfigEntry * const mAllowMarkTrustedConfigEntry;
183  CryptoConfigEntry * const mFetchMissingConfigEntry;
184  // gnupg 2.0.17+ option that should inhibit allow-mark-trusted display
185  CryptoConfigEntry * const mNoAllowMarkTrustedConfigEntry;
186  // dirmngr-0.9.0 options
187  CryptoConfigEntry * const mIgnoreServiceURLEntry;
188  CryptoConfigEntry * const mIgnoreHTTPDPEntry;
189  CryptoConfigEntry * const mDisableHTTPEntry;
190  CryptoConfigEntry * const mHonorHTTPProxy;
191  CryptoConfigEntry * const mIgnoreLDAPDPEntry;
192  CryptoConfigEntry * const mDisableLDAPEntry;
193  // Other widgets
194  CryptoConfigEntry * const mOCSPResponderURLConfigEntry;
195  CryptoConfigEntry * const mOCSPResponderSignature;
196  CryptoConfigEntry * const mCustomHTTPProxy;
197  CryptoConfigEntry * const mCustomLDAPProxy;
198 
199 };
200 
201 void SMimeValidationConfigurationWidget::defaults() {
202  kDebug() << "not implemented";
203 }
204 
205 void SMimeValidationConfigurationWidget::load() {
206  const SMimeValidationPreferences preferences;
207  const unsigned int refreshInterval = preferences.refreshInterval();
208  d->ui.intervalRefreshCB->setChecked( refreshInterval > 0 );
209  d->ui.intervalRefreshSB->setValue( refreshInterval );
210 
211  CryptoConfig * const config = CryptoBackendFactory::instance()->config();
212  if ( !config ) {
213  setEnabled( false );
214  return;
215  }
216 
217 #if 0
218  // crashes other pages' save() by nuking the CryptoConfigEntries under their feet.
219  // This was probably not a problem in KMail, where this code comes
220  // from. But here, it's fatal.
221 
222  // Force re-parsing gpgconf data, in case e.g. kleopatra or "configure backend" was used
223  // (which ends up calling us via D-Bus)
224  config->clear();
225 #endif
226 
227  // Create config entries
228  // Don't keep them around, they'll get deleted by clear(), which could be
229  // done by the "configure backend" button even before we save().
230  const SMIMECryptoConfigEntries e( config );
231 
232  // Initialize GUI items from the config entries
233 
234  if ( e.mCheckUsingOCSPConfigEntry ) {
235  const bool b = e.mCheckUsingOCSPConfigEntry->boolValue();
236  d->ui.OCSPRB->setChecked( b );
237  d->ui.CRLRB->setChecked( !b );
238  d->ui.OCSPGroupBox->setEnabled( b );
239  } else {
240  d->ui.OCSPGroupBox->setEnabled( false );
241  }
242 
243 
244  if ( e.mDoNotCheckCertPolicyConfigEntry )
245  d->ui.doNotCheckCertPolicyCB->setChecked( e.mDoNotCheckCertPolicyConfigEntry->boolValue() );
246  if ( e.mNeverConsultConfigEntry )
247  d->ui.neverConsultCB->setChecked( e.mNeverConsultConfigEntry->boolValue() );
248  if ( e.mNoAllowMarkTrustedConfigEntry )
249  d->ui.allowMarkTrustedCB->hide(); // this option was only here to _enable_ allow-mark-trusted, and makes no sense if it's already default on
250  if ( e.mAllowMarkTrustedConfigEntry )
251  d->ui.allowMarkTrustedCB->setChecked( e.mAllowMarkTrustedConfigEntry->boolValue() );
252  if ( e.mFetchMissingConfigEntry )
253  d->ui.fetchMissingCB->setChecked( e.mFetchMissingConfigEntry->boolValue() );
254 
255  if ( e.mOCSPResponderURLConfigEntry )
256  d->ui.OCSPResponderURL->setText( e.mOCSPResponderURLConfigEntry->stringValue() );
257  if ( e.mOCSPResponderSignature )
258  d->ui.OCSPResponderSignature->setSelectedCertificate( e.mOCSPResponderSignature->stringValue() );
259 
260  // dirmngr-0.9.0 options
261  initializeDirmngrCheckbox( d->ui.ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
262  initializeDirmngrCheckbox( d->ui.ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
263  initializeDirmngrCheckbox( d->ui.disableHTTPCB, e.mDisableHTTPEntry );
264  initializeDirmngrCheckbox( d->ui.ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
265  initializeDirmngrCheckbox( d->ui.disableLDAPCB, e.mDisableLDAPEntry );
266  if ( e.mCustomHTTPProxy ) {
267  QString systemProxy = QString::fromLocal8Bit( qgetenv( "http_proxy" ) );
268  if ( systemProxy.isEmpty() )
269  systemProxy = i18n( "no proxy" );
270  d->ui.systemHTTPProxy->setText( i18n( "(Current system setting: %1)", systemProxy ) );
271  const bool honor = e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue();
272  d->ui.honorHTTPProxyRB->setChecked( honor );
273  d->ui.useCustomHTTPProxyRB->setChecked( !honor );
274  d->ui.customHTTPProxy->setText( e.mCustomHTTPProxy->stringValue() );
275  }
276  d->customHTTPProxyWritable = e.mCustomHTTPProxy && !e.mCustomHTTPProxy->isReadOnly();
277  if ( !d->customHTTPProxyWritable ) {
278  disableDirmngrWidget( d->ui.honorHTTPProxyRB );
279  disableDirmngrWidget( d->ui.useCustomHTTPProxyRB );
280  disableDirmngrWidget( d->ui.systemHTTPProxy );
281  disableDirmngrWidget( d->ui.customHTTPProxy );
282  }
283  if ( e.mCustomLDAPProxy )
284  d->ui.customLDAPProxy->setText( e.mCustomLDAPProxy->stringValue() );
285  if ( !e.mCustomLDAPProxy || e.mCustomLDAPProxy->isReadOnly() ) {
286  disableDirmngrWidget( d->ui.customLDAPProxy );
287  disableDirmngrWidget( d->ui.customLDAPLabel );
288  }
289  d->enableDisableActions();
290 }
291 
292 static void saveCheckBoxToKleoEntry( QCheckBox * cb, CryptoConfigEntry * entry ) {
293  const bool b = cb->isChecked();
294  if ( entry && entry->boolValue() != b )
295  entry->setBoolValue( b );
296 }
297 
298 void SMimeValidationConfigurationWidget::save() const {
299  CryptoConfig * const config = CryptoBackendFactory::instance()->config();
300  if ( !config )
301  return;
302 
303  {
304  SMimeValidationPreferences preferences;
305  preferences.setRefreshInterval( d->ui.intervalRefreshCB->isChecked() ? d->ui.intervalRefreshSB->value() : 0 );
306  preferences.writeConfig();
307  }
308 
309  // Create config entries
310  // Don't keep them around, they'll get deleted by clear(), which could be done by the
311  // "configure backend" button.
312  const SMIMECryptoConfigEntries e( config );
313 
314  const bool b = d->ui.OCSPRB->isChecked();
315  if ( e.mCheckUsingOCSPConfigEntry && e.mCheckUsingOCSPConfigEntry->boolValue() != b )
316  e.mCheckUsingOCSPConfigEntry->setBoolValue( b );
317  // Set allow-ocsp together with enable-ocsp
318  if ( e.mEnableOCSPsendingConfigEntry && e.mEnableOCSPsendingConfigEntry->boolValue() != b )
319  e.mEnableOCSPsendingConfigEntry->setBoolValue( b );
320 
321  saveCheckBoxToKleoEntry( d->ui.doNotCheckCertPolicyCB, e.mDoNotCheckCertPolicyConfigEntry );
322  saveCheckBoxToKleoEntry( d->ui.neverConsultCB, e.mNeverConsultConfigEntry );
323  saveCheckBoxToKleoEntry( d->ui.allowMarkTrustedCB, e.mAllowMarkTrustedConfigEntry );
324  saveCheckBoxToKleoEntry( d->ui.fetchMissingCB, e.mFetchMissingConfigEntry );
325 
326  QString txt = d->ui.OCSPResponderURL->text();
327  if ( e.mOCSPResponderURLConfigEntry && e.mOCSPResponderURLConfigEntry->stringValue() != txt )
328  e.mOCSPResponderURLConfigEntry->setStringValue( txt );
329 
330  txt = d->ui.OCSPResponderSignature->selectedCertificate();
331  if ( e.mOCSPResponderSignature && e.mOCSPResponderSignature->stringValue() != txt )
332  e.mOCSPResponderSignature->setStringValue( txt );
333 
334  //dirmngr-0.9.0 options
335  saveCheckBoxToKleoEntry( d->ui.ignoreServiceURLCB, e.mIgnoreServiceURLEntry );
336  saveCheckBoxToKleoEntry( d->ui.ignoreHTTPDPCB, e.mIgnoreHTTPDPEntry );
337  saveCheckBoxToKleoEntry( d->ui.disableHTTPCB, e.mDisableHTTPEntry );
338  saveCheckBoxToKleoEntry( d->ui.ignoreLDAPDPCB, e.mIgnoreLDAPDPEntry );
339  saveCheckBoxToKleoEntry( d->ui.disableLDAPCB, e.mDisableLDAPEntry );
340  if ( e.mCustomHTTPProxy ) {
341  const bool honor = d->ui.honorHTTPProxyRB->isChecked();
342  if ( e.mHonorHTTPProxy && e.mHonorHTTPProxy->boolValue() != honor )
343  e.mHonorHTTPProxy->setBoolValue( honor );
344 
345  const QString chosenProxy = d->ui.customHTTPProxy->text();
346  if ( chosenProxy != e.mCustomHTTPProxy->stringValue() )
347  e.mCustomHTTPProxy->setStringValue( chosenProxy );
348  }
349  txt = d->ui.customLDAPProxy->text();
350  if ( e.mCustomLDAPProxy && e.mCustomLDAPProxy->stringValue() != txt )
351  e.mCustomLDAPProxy->setStringValue( d->ui.customLDAPProxy->text() );
352 
353  config->sync( true );
354 }
355 
356 CryptoConfigEntry * SMIMECryptoConfigEntries::configEntry( const char * componentName,
357  const char * groupName,
358  const char * entryName,
359  int /*CryptoConfigEntry::ArgType*/ argType,
360  bool isList )
361 {
362  CryptoConfigEntry * const entry = mConfig->entry( QLatin1String(componentName), QLatin1String(groupName), QLatin1String(entryName) );
363  if ( !entry ) {
364  kWarning(5151) << QString::fromLatin1("Backend error: gpgconf doesn't seem to know the entry for %1/%2/%3" ).arg( QLatin1String(componentName), QLatin1String(groupName), QLatin1String(entryName) );
365  return 0;
366  }
367  if( entry->argType() != argType || entry->isList() != isList ) {
368  kWarning(5151) << QString::fromLatin1("Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5" ).arg( QLatin1String(componentName), QLatin1String(groupName), QLatin1String(entryName) ).arg( entry->argType() ).arg( entry->isList() );
369  return 0;
370  }
371  return entry;
372 }
373 
374 
375 #include "moc_smimevalidationconfigurationwidget.cpp"
smimevalidationpreferences.h
Kleo::SMimeValidationPreferences
Definition: smimevalidationpreferences.h:12
signal
const char * signal
Definition: keytreeview.cpp:359
Kleo::Config::SMimeValidationConfigurationWidget::save
void save() const
Definition: smimevalidationconfigurationwidget.cpp:298
Kleo::Config::SMimeValidationConfigurationWidget::changed
void changed()
disableDirmngrWidget
static void disableDirmngrWidget(QWidget *w)
Definition: smimevalidationconfigurationwidget.cpp:130
Kleo::Config::SMimeValidationConfigurationWidget::~SMimeValidationConfigurationWidget
~SMimeValidationConfigurationWidget()
Definition: smimevalidationconfigurationwidget.cpp:127
QWidget
Kleo::Config::SMimeValidationConfigurationWidget::SMimeValidationConfigurationWidget
SMimeValidationConfigurationWidget(QWidget *parent=0, Qt::WindowFlags f=0)
Definition: smimevalidationconfigurationwidget.cpp:121
Kleo::SMimeValidationPreferences::refreshInterval
uint refreshInterval() const
Get Certificate refresh interval (in hours).
Definition: smimevalidationpreferences.h:38
d
#define d
Definition: adduseridcommand.cpp:90
saveCheckBoxToKleoEntry
static void saveCheckBoxToKleoEntry(QCheckBox *cb, CryptoConfigEntry *entry)
Definition: smimevalidationconfigurationwidget.cpp:292
Kleo::Config::SMimeValidationConfigurationWidget::load
void load()
Definition: smimevalidationconfigurationwidget.cpp:205
q
#define q
Definition: adduseridcommand.cpp:91
Kleo::Config::SMimeValidationConfigurationWidget
Definition: smimevalidationconfigurationwidget.h:43
Kleo::Config::SMimeValidationConfigurationWidget::defaults
void defaults()
Definition: smimevalidationconfigurationwidget.cpp:201
smimevalidationconfigurationwidget.h
Kleo::SMimeValidationPreferences::setRefreshInterval
void setRefreshInterval(uint v)
Set Certificate refresh interval (in hours).
Definition: smimevalidationpreferences.h:22
initializeDirmngrCheckbox
static void initializeDirmngrCheckbox(QCheckBox *cb, CryptoConfigEntry *entry)
Definition: smimevalidationconfigurationwidget.cpp:135
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



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