summaryrefslogtreecommitdiffstats
path: root/certmanager
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /certmanager
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'certmanager')
-rw-r--r--certmanager/Makefile.am32
-rw-r--r--certmanager/aboutdata.cpp93
-rw-r--r--certmanager/aboutdata.h43
-rw-r--r--certmanager/certificateinfowidget.ui215
-rw-r--r--certmanager/certificateinfowidgetimpl.cpp440
-rw-r--r--certmanager/certificateinfowidgetimpl.h87
-rw-r--r--certmanager/certificatewizard.ui558
-rw-r--r--certmanager/certificatewizardimpl.cpp515
-rw-r--r--certmanager/certificatewizardimpl.h88
-rw-r--r--certmanager/certlistview.cpp44
-rw-r--r--certmanager/certlistview.h28
-rw-r--r--certmanager/certmanager.cpp1432
-rw-r--r--certmanager/certmanager.h217
-rw-r--r--certmanager/conf/Makefile.am26
-rw-r--r--certmanager/conf/appearanceconfigpage.cpp87
-rw-r--r--certmanager/conf/appearanceconfigpage.h60
-rw-r--r--certmanager/conf/appearanceconfigwidget.cpp358
-rw-r--r--certmanager/conf/appearanceconfigwidget.h73
-rw-r--r--certmanager/conf/appearanceconfigwidgetbase.ui215
-rw-r--r--certmanager/conf/configuredialog.cpp73
-rw-r--r--certmanager/conf/configuredialog.h52
-rw-r--r--certmanager/conf/dirservconfigpage.cpp296
-rw-r--r--certmanager/conf/dirservconfigpage.h84
-rw-r--r--certmanager/conf/dnorderconfigpage.cpp77
-rw-r--r--certmanager/conf/dnorderconfigpage.h63
-rw-r--r--certmanager/conf/kleopatra_config_appear.desktop181
-rw-r--r--certmanager/conf/kleopatra_config_dirserv.desktop169
-rw-r--r--certmanager/conf/kleopatra_config_dnorder.desktop164
-rw-r--r--certmanager/configure.in.in1
-rw-r--r--certmanager/crlview.cpp138
-rw-r--r--certmanager/crlview.h69
-rw-r--r--certmanager/customactions.cpp136
-rw-r--r--certmanager/customactions.h86
-rw-r--r--certmanager/hierarchyanalyser.cpp81
-rw-r--r--certmanager/hierarchyanalyser.h66
-rw-r--r--certmanager/kleopatra_import.desktop13
-rw-r--r--certmanager/kleopatraui.rc73
-rw-r--r--certmanager/kwatchgnupg/Makefile.am30
-rw-r--r--certmanager/kwatchgnupg/aboutdata.cpp73
-rw-r--r--certmanager/kwatchgnupg/aboutdata.h43
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupg.pngbin0 -> 1137 bytes
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupg2.pngbin0 -> 1280 bytes
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupgconfig.cpp206
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupgconfig.h68
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupgmainwin.cpp292
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupgmainwin.h78
-rw-r--r--certmanager/kwatchgnupg/kwatchgnupgui.rc21
-rw-r--r--certmanager/kwatchgnupg/main.cpp96
-rw-r--r--certmanager/kwatchgnupg/tray.cpp66
-rw-r--r--certmanager/kwatchgnupg/tray.h55
-rw-r--r--certmanager/lib/Makefile.am49
-rw-r--r--certmanager/lib/backends/Makefile.am1
-rw-r--r--certmanager/lib/backends/chiasmus/Makefile.am16
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmusbackend.cpp480
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmusbackend.h86
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmusjob.cpp220
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmusjob.h116
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp115
-rw-r--r--certmanager/lib/backends/chiasmus/chiasmuslibrary.h68
-rw-r--r--certmanager/lib/backends/chiasmus/config_data.c95
-rw-r--r--certmanager/lib/backends/chiasmus/config_data.h34
-rw-r--r--certmanager/lib/backends/chiasmus/configure.in.in16
-rw-r--r--certmanager/lib/backends/chiasmus/obtainkeysjob.cpp126
-rw-r--r--certmanager/lib/backends/chiasmus/obtainkeysjob.h101
-rw-r--r--certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp109
-rw-r--r--certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h81
-rw-r--r--certmanager/lib/backends/kpgp/Makefile.am12
-rw-r--r--certmanager/lib/backends/kpgp/gpg1backend.h52
-rw-r--r--certmanager/lib/backends/kpgp/kpgpbackendbase.cpp111
-rw-r--r--certmanager/lib/backends/kpgp/kpgpbackendbase.h73
-rw-r--r--certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp303
-rw-r--r--certmanager/lib/backends/kpgp/kpgpkeylistjob.h79
-rw-r--r--certmanager/lib/backends/kpgp/kpgpwrapper.cpp173
-rw-r--r--certmanager/lib/backends/kpgp/kpgpwrapper.h97
-rw-r--r--certmanager/lib/backends/kpgp/pgp2backend.h52
-rw-r--r--certmanager/lib/backends/kpgp/pgp5backend.h52
-rw-r--r--certmanager/lib/backends/kpgp/pgp6backend.h52
-rw-r--r--certmanager/lib/backends/qgpgme/Makefile.am34
-rw-r--r--certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp198
-rw-r--r--certmanager/lib/backends/qgpgme/gnupgprocessbase.h91
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmebackend.cpp153
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmebackend.h82
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp837
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h186
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp91
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h74
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp95
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h75
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp70
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedeletejob.h68
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp78
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h67
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp108
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h86
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp78
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeexportjob.h69
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp86
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeimportjob.h73
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmejob.cpp304
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmejob.h160
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp86
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h78
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp187
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h81
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp159
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h58
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp207
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h80
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp196
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h85
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp121
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h91
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp113
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmesignjob.h87
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp96
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h75
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp91
-rw-r--r--certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h73
-rw-r--r--certmanager/lib/cryptplug.cpp1123
-rw-r--r--certmanager/lib/cryptplug.h954
-rw-r--r--certmanager/lib/cryptplugfactory.cpp119
-rw-r--r--certmanager/lib/cryptplugfactory.h83
-rw-r--r--certmanager/lib/cryptplugwrapper.cpp850
-rw-r--r--certmanager/lib/cryptplugwrapper.h839
-rw-r--r--certmanager/lib/cryptplugwrapperlist.cpp34
-rw-r--r--certmanager/lib/cryptplugwrapperlist.h37
-rw-r--r--certmanager/lib/kleo/Makefile.am37
-rw-r--r--certmanager/lib/kleo/cryptobackend.cpp36
-rw-r--r--certmanager/lib/kleo/cryptobackend.h122
-rw-r--r--certmanager/lib/kleo/cryptobackendfactory.cpp275
-rw-r--r--certmanager/lib/kleo/cryptobackendfactory.h117
-rw-r--r--certmanager/lib/kleo/cryptoconfig.h387
-rw-r--r--certmanager/lib/kleo/decryptjob.h84
-rw-r--r--certmanager/lib/kleo/decryptverifyjob.h90
-rw-r--r--certmanager/lib/kleo/deletejob.h78
-rw-r--r--certmanager/lib/kleo/dn.cpp538
-rw-r--r--certmanager/lib/kleo/dn.h142
-rw-r--r--certmanager/lib/kleo/downloadjob.h83
-rw-r--r--certmanager/lib/kleo/encryptjob.h92
-rw-r--r--certmanager/lib/kleo/enum.cpp206
-rw-r--r--certmanager/lib/kleo/enum.h93
-rw-r--r--certmanager/lib/kleo/exportjob.h82
-rw-r--r--certmanager/lib/kleo/hierarchicalkeylistjob.cpp158
-rw-r--r--certmanager/lib/kleo/hierarchicalkeylistjob.h116
-rw-r--r--certmanager/lib/kleo/importjob.h83
-rw-r--r--certmanager/lib/kleo/job.cpp116
-rw-r--r--certmanager/lib/kleo/job.h81
-rw-r--r--certmanager/lib/kleo/kconfigbasedkeyfilter.cpp251
-rw-r--r--certmanager/lib/kleo/kconfigbasedkeyfilter.h104
-rw-r--r--certmanager/lib/kleo/keyfilter.h68
-rw-r--r--certmanager/lib/kleo/keyfiltermanager.cpp118
-rw-r--r--certmanager/lib/kleo/keyfiltermanager.h69
-rw-r--r--certmanager/lib/kleo/keygenerationjob.h81
-rw-r--r--certmanager/lib/kleo/keylistjob.h96
-rw-r--r--certmanager/lib/kleo/multideletejob.cpp110
-rw-r--r--certmanager/lib/kleo/multideletejob.h101
-rw-r--r--certmanager/lib/kleo/oidmap.h57
-rw-r--r--certmanager/lib/kleo/refreshkeysjob.h90
-rw-r--r--certmanager/lib/kleo/signencryptjob.h103
-rw-r--r--certmanager/lib/kleo/signjob.h90
-rw-r--r--certmanager/lib/kleo/specialjob.h86
-rw-r--r--certmanager/lib/kleo/verifydetachedjob.h86
-rw-r--r--certmanager/lib/kleo/verifyopaquejob.h85
-rw-r--r--certmanager/lib/libkleopatrarc.desktop323
-rw-r--r--certmanager/lib/pics/Makefile.am4
-rw-r--r--certmanager/lib/pics/chiasmus_chi.pngbin0 -> 18632 bytes
-rw-r--r--certmanager/lib/pics/cr16-app-gpg.pngbin0 -> 750 bytes
-rw-r--r--certmanager/lib/pics/cr16-app-gpgsm.pngbin0 -> 750 bytes
-rw-r--r--certmanager/lib/pics/cr22-app-gpg.pngbin0 -> 3604 bytes
-rw-r--r--certmanager/lib/pics/cr22-app-gpgsm.pngbin0 -> 3604 bytes
-rw-r--r--certmanager/lib/pics/cr32-app-gpg.pngbin0 -> 1583 bytes
-rw-r--r--certmanager/lib/pics/cr32-app-gpgsm.pngbin0 -> 1583 bytes
-rw-r--r--certmanager/lib/pics/key.pngbin0 -> 311 bytes
-rw-r--r--certmanager/lib/pics/key_bad.pngbin0 -> 339 bytes
-rw-r--r--certmanager/lib/pics/key_ok.pngbin0 -> 360 bytes
-rw-r--r--certmanager/lib/pics/key_unknown.pngbin0 -> 360 bytes
-rw-r--r--certmanager/lib/tests/Makefile.am20
-rw-r--r--certmanager/lib/tests/gnupg_home/pubring.gpgbin0 -> 1233 bytes
-rw-r--r--certmanager/lib/tests/gnupg_home/secring.gpgbin0 -> 1381 bytes
-rw-r--r--certmanager/lib/tests/gnupg_home/trustdb.gpgbin0 -> 1280 bytes
-rw-r--r--certmanager/lib/tests/gnupgviewer.h64
-rw-r--r--certmanager/lib/tests/test.data295
-rw-r--r--certmanager/lib/tests/test.data.gpgbin0 -> 3010 bytes
-rw-r--r--certmanager/lib/tests/test.data.sigbin0 -> 65 bytes
-rw-r--r--certmanager/lib/tests/test_cryptoconfig.cpp365
-rw-r--r--certmanager/lib/tests/test_gnupgprocessbase.cpp143
-rw-r--r--certmanager/lib/tests/test_jobs.cpp108
-rw-r--r--certmanager/lib/tests/test_keygen.cpp160
-rw-r--r--certmanager/lib/tests/test_keygen.h62
-rw-r--r--certmanager/lib/tests/test_keylister.cpp146
-rw-r--r--certmanager/lib/tests/test_keylister.h52
-rw-r--r--certmanager/lib/tests/test_keyselectiondialog.cpp67
-rw-r--r--certmanager/lib/tests/test_verify.cpp99
-rw-r--r--certmanager/lib/ui/Makefile.am42
-rw-r--r--certmanager/lib/ui/adddirectoryservicedialog.ui207
-rw-r--r--certmanager/lib/ui/adddirectoryservicedialogimpl.cpp63
-rw-r--r--certmanager/lib/ui/adddirectoryservicedialogimpl.h47
-rw-r--r--certmanager/lib/ui/backendconfigwidget.cpp323
-rw-r--r--certmanager/lib/ui/backendconfigwidget.h76
-rw-r--r--certmanager/lib/ui/cryptoconfigdialog.cpp89
-rw-r--r--certmanager/lib/ui/cryptoconfigdialog.h69
-rw-r--r--certmanager/lib/ui/cryptoconfigmodule.cpp634
-rw-r--r--certmanager/lib/ui/cryptoconfigmodule.h68
-rw-r--r--certmanager/lib/ui/cryptoconfigmodule_p.h280
-rw-r--r--certmanager/lib/ui/directoryserviceswidget.cpp308
-rw-r--r--certmanager/lib/ui/directoryserviceswidget.h82
-rw-r--r--certmanager/lib/ui/directoryserviceswidgetbase.ui342
-rw-r--r--certmanager/lib/ui/dnattributeorderconfigwidget.cpp309
-rw-r--r--certmanager/lib/ui/dnattributeorderconfigwidget.h87
-rw-r--r--certmanager/lib/ui/kdhorizontalline.cpp171
-rw-r--r--certmanager/lib/ui/kdhorizontalline.h82
-rw-r--r--certmanager/lib/ui/keyapprovaldialog.cpp227
-rw-r--r--certmanager/lib/ui/keyapprovaldialog.h92
-rw-r--r--certmanager/lib/ui/keylistview.cpp869
-rw-r--r--certmanager/lib/ui/keylistview.h323
-rw-r--r--certmanager/lib/ui/keyrequester.cpp481
-rw-r--r--certmanager/lib/ui/keyrequester.h227
-rw-r--r--certmanager/lib/ui/keyselectiondialog.cpp806
-rw-r--r--certmanager/lib/ui/keyselectiondialog.h179
-rw-r--r--certmanager/lib/ui/messagebox.cpp265
-rw-r--r--certmanager/lib/ui/messagebox.h83
-rw-r--r--certmanager/lib/ui/passphrasedialog.cpp123
-rw-r--r--certmanager/lib/ui/passphrasedialog.h91
-rw-r--r--certmanager/lib/ui/progressbar.cpp111
-rw-r--r--certmanager/lib/ui/progressbar.h74
-rw-r--r--certmanager/lib/ui/progressdialog.cpp98
-rw-r--r--certmanager/lib/ui/progressdialog.h66
-rw-r--r--certmanager/main.cpp84
-rw-r--r--certmanager/storedtransferjob.cpp98
-rw-r--r--certmanager/storedtransferjob.h113
230 files changed, 33604 insertions, 0 deletions
diff --git a/certmanager/Makefile.am b/certmanager/Makefile.am
new file mode 100644
index 000000000..f86b7bc7b
--- /dev/null
+++ b/certmanager/Makefile.am
@@ -0,0 +1,32 @@
+SUBDIRS = lib conf kwatchgnupg .
+
+KDE_CXXFLAGS = -DLIBKLEOPATRA_NO_COMPAT
+
+INCLUDES = -I$(srcdir)/lib -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+bin_PROGRAMS = kleopatra
+
+kleopatra_SOURCES = \
+ customactions.cpp \
+ aboutdata.cpp \
+ main.cpp certmanager.cpp \
+ hierarchyanalyser.cpp \
+ certificatewizard.ui certificatewizardimpl.cpp \
+ certificateinfowidget.ui certificateinfowidgetimpl.cpp \
+ crlview.cpp storedtransferjob.cpp certlistview.cpp
+
+METASOURCES = AUTO
+
+kleopatra_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kleopatra_LDADD = conf/libconf.la lib/libkleopatra.la $(LIB_KUTILS) $(LIB_KABC)
+
+rcdir = $(kde_datadir)/kleopatra
+rc_DATA = kleopatraui.rc
+
+xdg_apps_DATA = kleopatra_import.desktop
+
+messages: rc.cpp
+ $(EXTRACTRC) conf/*.ui >> rc.cpp
+ $(XGETTEXT) conf/*.cpp *.cpp *.h -o $(podir)/kleopatra.pot
+
+include $(top_srcdir)/admin/Doxyfile.am
diff --git a/certmanager/aboutdata.cpp b/certmanager/aboutdata.cpp
new file mode 100644
index 000000000..fb5813ec4
--- /dev/null
+++ b/certmanager/aboutdata.cpp
@@ -0,0 +1,93 @@
+/*
+ aboutdata.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "aboutdata.h"
+
+#include <klocale.h>
+
+static const char kleopatra_version[] = "0.40";
+static const char description[] = I18N_NOOP("KDE Key Manager");
+
+struct about_data {
+ const char * name;
+ const char * desc;
+ const char * email;
+ const char * web;
+};
+
+static const about_data authors[] = {
+ { "Marc Mutz", I18N_NOOP("Current Maintainer"), "mutz@kde.org", 0 },
+ { "Steffen Hansen", I18N_NOOP("Former Maintainer"), "hansen@kde.org", 0 },
+ { "Kalle Dalheimer", I18N_NOOP("Original Author"), "kalle@kde.org", 0 },
+ { "Jesper Petersen", I18N_NOOP("Original Author"), "blackie@kde.org", 0 },
+};
+
+
+static const about_data credits[] = {
+ { "David Faure",
+ I18N_NOOP("Backend configuration framework, KIO integration"),
+ "faure@kde.org", 0 },
+ { "Michel Boyer de la Giroday",
+ I18N_NOOP("Key-state dependant colors and fonts in the key list"),
+ "michel@klaralvdalens-datakonsult.se", 0 },
+ { "Daniel Molkentin",
+ I18N_NOOP("Certificate Wizard KIOSK integration, infrastructure"),
+ "molkentin@kde.org", 0 },
+ { "Ralf Nolden",
+ I18N_NOOP("Support for obsolete EMAIL RDN in Certificate Wizard"),
+ "nolden@kde.org", 0 },
+ { "Karl-Heinz Zimmer",
+ I18N_NOOP("DN display ordering support, infrastructure"),
+ "khz@kde.org", 0 },
+};
+
+
+AboutData::AboutData()
+ : KAboutData( "kleopatra", I18N_NOOP("Kleopatra"),
+ kleopatra_version, description, License_GPL,
+ "(c) 2002 Steffen Hansen, Jesper Pedersen,\n"
+ "Kalle Dalheimer, Klar\xC3\xA4lvdalens Datakonsult AB\n\n"
+ "(c) 2004 Marc Mutz, Klar\xC3\xA4lvdalens Datakonsult AB" )
+{
+ using ::authors;
+ using ::credits;
+ for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i )
+ addAuthor( authors[i].name, authors[i].desc,
+ authors[i].email, authors[i].web );
+ for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i )
+ addCredit( credits[i].name, credits[i].desc,
+ credits[i].email, credits[i].web );
+}
diff --git a/certmanager/aboutdata.h b/certmanager/aboutdata.h
new file mode 100644
index 000000000..29e516f5c
--- /dev/null
+++ b/certmanager/aboutdata.h
@@ -0,0 +1,43 @@
+/*
+ aboutdata.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __ABOUTDATA_H__
+#define __ABOUTDATA_H__
+
+#include <kaboutdata.h>
+
+class AboutData : public KAboutData {
+public:
+ AboutData();
+};
+
+#endif // __ABOUTDATA_H__
diff --git a/certmanager/certificateinfowidget.ui b/certmanager/certificateinfowidget.ui
new file mode 100644
index 000000000..967d32982
--- /dev/null
+++ b/certmanager/certificateinfowidget.ui
@@ -0,0 +1,215 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>CertificateInfoWidget</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>CertificateInfoWidget</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>423</width>
+ <height>403</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>250</width>
+ <height>0</height>
+ </size>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QFrame" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Frame3</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ <widget class="QTabWidget" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>tabWidget</cstring>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Details</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>6</number>
+ </property>
+ <widget class="QListView" row="0" column="0">
+ <column>
+ <property name="text">
+ <string>Description</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Information</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>listView</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="showSortIndicator">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QTextEdit" row="1" column="0">
+ <property name="name">
+ <cstring>textView</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>tab</cstring>
+ </property>
+ <attribute name="title">
+ <string>&amp;Chain</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>6</number>
+ </property>
+ <widget class="QListView" row="0" column="0">
+ <column>
+ <property name="text">
+ <string>Path</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>pathView</cstring>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>dump</cstring>
+ </property>
+ <attribute name="title">
+ <string>Du&amp;mp</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>6</number>
+ </property>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>dumpView</cstring>
+ </property>
+ <property name="textFormat">
+ <enum>LogText</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>importButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Import to Local</string>
+ </property>
+ </widget>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>291</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>4</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <bold>1</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>Certificate Information</string>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<layoutdefaults spacing="6" margin="0"/>
+</UI>
diff --git a/certmanager/certificateinfowidgetimpl.cpp b/certmanager/certificateinfowidgetimpl.cpp
new file mode 100644
index 000000000..c6e810109
--- /dev/null
+++ b/certmanager/certificateinfowidgetimpl.cpp
@@ -0,0 +1,440 @@
+/*
+ certificateinfowidgetimpl.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "certificateinfowidgetimpl.h"
+
+// libkleopatra
+#include <kleo/keylistjob.h>
+#include <kleo/dn.h>
+#include <kleo/cryptobackendfactory.h>
+
+#include <ui/progressdialog.h>
+
+// gpgme++
+#include <gpgmepp/keylistresult.h>
+
+// KDE
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+#include <kprocio.h>
+#include <kglobalsettings.h>
+
+// Qt
+#include <qlistview.h>
+#include <qtextedit.h>
+#include <qheader.h>
+#include <qpushbutton.h>
+#include <qcursor.h>
+#include <qapplication.h>
+#include <qdatetime.h>
+#include <qstylesheet.h>
+#include <qtextcodec.h>
+
+// other
+#include <assert.h>
+
+CertificateInfoWidgetImpl::CertificateInfoWidgetImpl( const GpgME::Key & key, bool external,
+ QWidget * parent, const char * name )
+ : CertificateInfoWidget( parent, name ),
+ mExternal( external ),
+ mFoundIssuer( true ),
+ mHaveKeyLocally( false )
+{
+ importButton->setEnabled( false );
+
+ listView->setColumnWidthMode( 1, QListView::Maximum );
+ QFontMetrics fm = fontMetrics();
+ listView->setColumnWidth( 1, fm.width( i18n("Information") ) * 5 );
+
+ listView->header()->setClickEnabled( false );
+ listView->setSorting( -1 );
+
+ connect( listView, SIGNAL( selectionChanged( QListViewItem* ) ),
+ this, SLOT( slotShowInfo( QListViewItem* ) ) );
+ pathView->setColumnWidthMode( 0, QListView::Maximum );
+ pathView->header()->hide();
+
+ connect( pathView, SIGNAL( doubleClicked( QListViewItem* ) ),
+ this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) );
+ connect( pathView, SIGNAL( returnPressed( QListViewItem* ) ),
+ this, SLOT( slotShowCertPathDetails( QListViewItem* ) ) );
+ connect( importButton, SIGNAL( clicked() ),
+ this, SLOT( slotImportCertificate() ) );
+
+ dumpView->setFont( KGlobalSettings::fixedFont() );
+
+ if ( !key.isNull() )
+ setKey( key );
+}
+
+static QString time_t2string( time_t t ) {
+ QDateTime dt;
+ dt.setTime_t( t );
+ return dt.toString();
+}
+
+void CertificateInfoWidgetImpl::setKey( const GpgME::Key & key ) {
+ mChain.clear();
+ mFoundIssuer = true;
+ mHaveKeyLocally = false;
+
+ listView->clear();
+ pathView->clear();
+ importButton->setEnabled( false );
+
+ if ( key.isNull() )
+ return;
+
+ mChain.push_front( key );
+ startKeyExistanceCheck(); // starts a local keylisting to enable the
+ // importButton if needed
+
+ QListViewItem * item = 0;
+ item = new QListViewItem( listView, item, i18n("Valid"), QString("From %1 to %2")
+ .arg( time_t2string( key.subkey(0).creationTime() ),
+ time_t2string( key.subkey(0).expirationTime() ) ) );
+ item = new QListViewItem( listView, item, i18n("Can be used for signing"),
+ key.canSign() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for encryption"),
+ key.canEncrypt() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for certification"),
+ key.canCertify() ? i18n("Yes") : i18n("No") );
+ item = new QListViewItem( listView, item, i18n("Can be used for authentication"),
+ key.canAuthenticate() ? i18n("Yes") : i18n("No" ) );
+ item = new QListViewItem( listView, item, i18n("Fingerprint"), key.primaryFingerprint() );
+ item = new QListViewItem( listView, item, i18n("Issuer"), Kleo::DN( key.issuerName() ).prettyDN() );
+ item = new QListViewItem( listView, item, i18n("Serial Number"), key.issuerSerial() );
+
+ const Kleo::DN dn = key.userID(0).id();
+
+ // FIXME: use the attributeLabelMap from certificatewizardimpl.cpp:
+ static QMap<QString,QString> dnComponentNames;
+ if ( dnComponentNames.isEmpty() ) {
+ dnComponentNames["C"] = i18n("Country");
+ dnComponentNames["OU"] = i18n("Organizational Unit");
+ dnComponentNames["O"] = i18n("Organization");
+ dnComponentNames["L"] = i18n("Location");
+ dnComponentNames["CN"] = i18n("Common Name");
+ dnComponentNames["EMAIL"] = i18n("Email");
+ }
+
+ for ( Kleo::DN::const_iterator dnit = dn.begin() ; dnit != dn.end() ; ++dnit ) {
+ QString displayName = (*dnit).name();
+ if( dnComponentNames.contains(displayName) ) displayName = dnComponentNames[displayName];
+ item = new QListViewItem( listView, item, displayName, (*dnit).value() );
+ }
+
+ const std::vector<GpgME::UserID> uids = key.userIDs();
+ if ( !uids.empty() ) {
+ item = new QListViewItem( listView, item, i18n("Subject"),
+ Kleo::DN( uids.front().id() ).prettyDN() );
+ for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() + 1 ; it != uids.end() ; ++it ) {
+ if ( !(*it).id() )
+ continue;
+ const QString email = QString::fromUtf8( (*it).id() ).stripWhiteSpace();
+ if ( email.isEmpty() )
+ continue;
+ if ( email.startsWith( "<" ) )
+ item = new QListViewItem( listView, item, i18n("Email"),
+ email.mid( 1, email.length()-2 ) );
+ else
+ item = new QListViewItem( listView, item, i18n("A.k.a."), email );
+ }
+ }
+
+ updateChainView();
+ startCertificateChainListing();
+ startCertificateDump();
+}
+
+static void showChainListError( QWidget * parent, const GpgME::Error & err, const char * subject ) {
+ assert( err );
+ const QString msg = i18n("<qt><p>An error occurred while fetching "
+ "the certificate <b>%1</b> from the backend:</p>"
+ "<p><b>%2</b></p></qt>")
+ .arg( subject ? QString::fromUtf8( subject ) : QString::null,
+ QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n("Certificate Listing Failed" ) );
+}
+
+void CertificateInfoWidgetImpl::startCertificateChainListing() {
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing()" << endl;
+
+ if ( mChain.empty() ) {
+ // we need a seed...
+ kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): mChain is empty!" << endl;
+ return;
+ }
+ const char * chainID = mChain.front().chainID();
+ if ( !chainID || !*chainID ) {
+ // cert not found:
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): empty chain ID - root not found" << endl;
+ return;
+ }
+ const char * fpr = mChain.front().primaryFingerprint();
+ if ( qstricmp( fpr, chainID ) == 0 ) {
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): chain_id equals fingerprint -> found root" << endl;
+ return;
+ }
+ if ( mChain.size() > 100 ) {
+ // safe guard against certificate loops (paranoia factor 8 out of 10)...
+ kdWarning() << "CertificateInfoWidgetImpl::startCertificateChainListing(): maximum chain length of 100 exceeded!" << endl;
+ return;
+ }
+ if ( !mFoundIssuer ) {
+ // key listing failed. Don't end up in endless loop
+ kdDebug() << "CertificateInfoWidgetImpl::startCertificateChainListing(): issuer not found - giving up" << endl;
+ return;
+ }
+
+ mFoundIssuer = false;
+
+ // gpgsm / dirmngr / LDAP / whoever doesn't support looking up
+ // external keys by fingerprint. Furthermore, since we actually got
+ // a chain-id set on the key, we know that we have the issuer's cert
+ // in the local keyring, so just use local keylisting.
+ Kleo::KeyListJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotCertificateChainListingResult(const GpgME::KeyListResult&)) );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotNextKey(const GpgME::Key&)) );
+
+ kdDebug() << "Going to fetch" << endl
+ << " issuer : \"" << mChain.front().issuerName() << "\"" << endl
+ << " chain id: " << mChain.front().chainID() << endl
+ << "for" << endl
+ << " subject : \"" << mChain.front().userID(0).id() << "\"" << endl
+ << " subj.fpr: " << mChain.front().primaryFingerprint() << endl;
+
+ const GpgME::Error err = job->start( mChain.front().chainID() );
+
+ if ( err )
+ showChainListError( this, err, mChain.front().issuerName() );
+ else
+ (void)new Kleo::ProgressDialog( job, i18n("Fetching Certificate Chain"), this );
+}
+
+void CertificateInfoWidgetImpl::startCertificateDump() {
+ KProcess* proc = new KProcess( this );
+ (*proc) << "gpgsm"; // must be in the PATH
+ (*proc) << "--dump-keys";
+ (*proc) << mChain.front().primaryFingerprint();
+
+ QObject::connect( proc, SIGNAL( receivedStdout(KProcess *, char *, int) ),
+ this, SLOT( slotCollectStdout(KProcess *, char *, int) ) );
+ QObject::connect( proc, SIGNAL( receivedStderr(KProcess *, char *, int) ),
+ this, SLOT( slotCollectStderr(KProcess *, char *, int) ) );
+ QObject::connect( proc, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotDumpProcessExited(KProcess*) ) );
+
+ if ( !proc->start( KProcess::NotifyOnExit, (KProcess::Communication)(KProcess::Stdout | KProcess::Stderr) ) ) {
+ QString wmsg = i18n("Failed to execute gpgsm:\n%1").arg( i18n( "program not found" ) );
+ dumpView->setText( QStyleSheet::escape( wmsg ) );
+ delete proc;
+ }
+}
+
+void CertificateInfoWidgetImpl::slotCollectStdout(KProcess *, char *buffer, int buflen)
+{
+ mDumpOutput += QCString(buffer, buflen+1); // like KProcIO does
+}
+
+void CertificateInfoWidgetImpl::slotCollectStderr(KProcess *, char *buffer, int buflen)
+{
+ mDumpError += QCString(buffer, buflen+1); // like KProcIO does
+}
+
+void CertificateInfoWidgetImpl::slotDumpProcessExited(KProcess* proc) {
+ int rc = ( proc->normalExit() ) ? proc->exitStatus() : -1 ;
+
+ if ( rc == 0 ) {
+ dumpView->setText( QStyleSheet::escape( QString::fromUtf8( mDumpOutput ) ) );
+ } else {
+ if ( !mDumpError.isEmpty() ) {
+ dumpView->setText( QStyleSheet::escape( QString::fromUtf8( mDumpError ) ) );
+ } else
+ {
+ QString wmsg = i18n("Failed to execute gpgsm:\n%1");
+ if ( rc == -1 )
+ wmsg = wmsg.arg( i18n( "program cannot be executed" ) );
+ else
+ wmsg = wmsg.arg( strerror(rc) );
+ dumpView->setText( QStyleSheet::escape( wmsg ) );
+ }
+ }
+
+ proc->deleteLater();
+}
+
+void CertificateInfoWidgetImpl::slotNextKey( const GpgME::Key & key ) {
+ kdDebug() << "CertificateInfoWidgetImpl::slotNextKey( \""
+ << key.userID(0).id() << "\" )" << endl;
+ if ( key.isNull() )
+ return;
+
+ mFoundIssuer = true;
+ mChain.push_front( key );
+ updateChainView();
+ // FIXME: cancel the keylisting. We're only interested in _one_ key.
+}
+
+void CertificateInfoWidgetImpl::updateChainView() {
+ pathView->clear();
+ if ( mChain.empty() )
+ return;
+ QListViewItem * item = 0;
+
+ QValueList<GpgME::Key>::const_iterator it = mChain.begin();
+ // root item:
+ if ( (*it).chainID() && qstrcmp( (*it).chainID(), (*it).primaryFingerprint() ) == 0 )
+ item = new QListViewItem( pathView, Kleo::DN( (*it++).userID(0).id() ).prettyDN() );
+ else {
+ item = new QListViewItem( pathView, i18n("Issuer certificate not found ( %1)")
+ .arg( Kleo::DN( (*it).issuerName() ).prettyDN() ) );
+ item->setOpen( true ); // Qt bug: doesn't open after setEnabled( false ) :/
+ item->setEnabled( false );
+ }
+ item->setOpen( true );
+
+ // subsequent items:
+ while ( it != mChain.end() ) {
+ item = new QListViewItem( item, Kleo::DN( (*it++).userID(0).id() ).prettyDN() );
+ item->setOpen( true );
+ }
+}
+
+void CertificateInfoWidgetImpl::slotCertificateChainListingResult( const GpgME::KeyListResult & res ) {
+ if ( res.error() )
+ return showChainListError( this, res.error(), mChain.front().issuerName() );
+ else
+ startCertificateChainListing();
+}
+
+void CertificateInfoWidgetImpl::slotShowInfo( QListViewItem * item ) {
+ textView->setText( item->text(1) );
+}
+
+void CertificateInfoWidgetImpl::slotShowCertPathDetails( QListViewItem * item ) {
+ if ( !item )
+ return;
+
+ // find the key corresponding to "item". This hack would not be
+ // necessary if pathView was a Kleo::KeyListView, but it's
+ // Qt-Designer-generated and I don't feel like creating a custom
+ // widget spec for Kleo::KeyListView.
+ unsigned int totalCount = 0;
+ int itemIndex = -1;
+ for ( const QListViewItem * i = pathView->firstChild() ; i ; i = i->firstChild() ) {
+ if ( i == item )
+ itemIndex = totalCount;
+ ++totalCount;
+ }
+
+ assert( totalCount == mChain.size() || totalCount == mChain.size() + 1 );
+
+ // skip pseudo root item with "not found message":
+ if ( totalCount == mChain.size() + 1 )
+ --itemIndex;
+
+ assert( itemIndex >= 0 );
+
+ KDialogBase * dialog =
+ new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"),
+ KDialogBase::Close, KDialogBase::Close );
+ CertificateInfoWidgetImpl * top =
+ new CertificateInfoWidgetImpl( mChain[itemIndex], mExternal, dialog );
+ dialog->setMainWidget( top );
+ // proxy the signal to our receiver:
+ connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)),
+ SIGNAL(requestCertificateDownload(const QString&, const QString&)) );
+ dialog->show();
+}
+
+
+void CertificateInfoWidgetImpl::slotImportCertificate()
+{
+ if ( mChain.empty() || mChain.back().isNull() )
+ return;
+ const Kleo::DN dn = mChain.back().userID( 0 ).id();
+ emit requestCertificateDownload( mChain.back().primaryFingerprint(), dn.prettyDN() );
+ importButton->setEnabled( false );
+}
+
+void CertificateInfoWidgetImpl::startKeyExistanceCheck() {
+ if ( !mExternal )
+ // we already have it if it's from a local keylisting :)
+ return;
+ if ( mChain.empty() || mChain.back().isNull() )
+ // need a key to look for
+ return;
+ const QString fingerprint = mChain.back().primaryFingerprint();
+ if ( fingerprint.isEmpty() )
+ // empty pattern means list all keys. We don't want that
+ return;
+
+ // start _local_ keylistjob (no progressdialog needed here):
+ Kleo::KeyListJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false );
+ assert( job );
+
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotKeyExistanceCheckNextCandidate(const GpgME::Key&)) );
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotKeyExistanceCheckFinished()) );
+ // nor to check for errors:
+ job->start( fingerprint );
+}
+
+void CertificateInfoWidgetImpl::slotKeyExistanceCheckNextCandidate( const GpgME::Key & key ) {
+ if ( key.isNull() || mChain.empty() || !key.primaryFingerprint() )
+ return;
+
+ if ( qstrcmp( key.primaryFingerprint(),
+ mChain.back().primaryFingerprint() ) == 0 )
+ mHaveKeyLocally = true;
+}
+
+void CertificateInfoWidgetImpl::slotKeyExistanceCheckFinished() {
+ importButton->setEnabled( !mHaveKeyLocally );
+}
+
+
+#include "certificateinfowidgetimpl.moc"
diff --git a/certmanager/certificateinfowidgetimpl.h b/certmanager/certificateinfowidgetimpl.h
new file mode 100644
index 000000000..961d67c39
--- /dev/null
+++ b/certmanager/certificateinfowidgetimpl.h
@@ -0,0 +1,87 @@
+/*
+ certificateinfowidgetimpl.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CERTIFICATEINFOWIDGETIMPL_H
+#define CERTIFICATEINFOWIDGETIMPL_H
+
+#include "certificateinfowidget.h"
+
+#include <gpgmepp/key.h>
+
+#include <qvaluelist.h>
+
+class KProcess;
+class QListViewItem;
+
+namespace GpgME {
+ class KeyListResult;
+}
+
+class CertificateInfoWidgetImpl : public CertificateInfoWidget {
+ Q_OBJECT
+public:
+ CertificateInfoWidgetImpl( const GpgME::Key & key, bool external,
+ QWidget * parent=0, const char * name=0);
+
+ void setKey( const GpgME::Key & key );
+
+signals:
+ void requestCertificateDownload( const QString & fingerprint, const QString& displayName );
+
+private slots:
+ void slotShowInfo( QListViewItem* );
+ void slotShowCertPathDetails( QListViewItem* );
+ void slotImportCertificate();
+ void slotCertificateChainListingResult( const GpgME::KeyListResult & res );
+ void slotNextKey( const GpgME::Key & key );
+ void slotKeyExistanceCheckNextCandidate( const GpgME::Key & key );
+ void slotKeyExistanceCheckFinished();
+ void slotCollectStdout(KProcess *, char *, int);
+ void slotCollectStderr(KProcess *, char *, int);
+ void slotDumpProcessExited(KProcess*);
+
+private:
+ void startCertificateChainListing();
+ void startCertificateDump();
+ void startKeyExistanceCheck();
+ void updateChainView();
+
+private:
+ QCString mDumpOutput;
+ QCString mDumpError;
+ QValueList<GpgME::Key> mChain;
+ bool mExternal;
+ bool mFoundIssuer;
+ bool mHaveKeyLocally;
+};
+
+#endif // CERTIFICATEINFOWIDGETIMPL_H
diff --git a/certmanager/certificatewizard.ui b/certmanager/certificatewizard.ui
new file mode 100644
index 000000000..7edbd1a72
--- /dev/null
+++ b/certmanager/certificatewizard.ui
@@ -0,0 +1,558 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>CertificateWizard</class>
+<widget class="QWizard">
+ <property name="name">
+ <cstring>CertificateWizard</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>832</width>
+ <height>589</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Key Generation Wizard</string>
+ </property>
+ <property name="titleFont">
+ <font>
+ <pointsize>16</pointsize>
+ <bold>1</bold>
+ </font>
+ </property>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>introPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Key Generation Wizard</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;b&gt;Welcome to the Key Generation Wizard.&lt;/b&gt;
+&lt;br&gt;
+&lt;br&gt;
+In a few easy steps, this wizard will help you to create a new key pair and request a certificate for it. You can then use your certificate in order to sign messages, to encrypt messages and to decrypt messages that other people send to you in encrypted form.
+&lt;p&gt;
+The key pair will be generated in a decentralized manner. Please contact your local help desk if you are unsure how to obtain a certificate for your new key in your organization.</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>WizardPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Key Parameters</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>On this page, you will configure the cryptographic key length and the type of certificate to create.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer14</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Cryptographic Key Length</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Choose &amp;key length:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>keyLengthCB</cstring>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>keyLengthCB</cstring>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>61</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <widget class="QButtonGroup">
+ <property name="name">
+ <cstring>certTypeBG</cstring>
+ </property>
+ <property name="title">
+ <string>Certificate Usage</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>signOnlyCB</cstring>
+ </property>
+ <property name="text">
+ <string>For &amp;signing only</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>encryptOnlyCB</cstring>
+ </property>
+ <property name="text">
+ <string>For &amp;encrypting only</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton">
+ <property name="name">
+ <cstring>bothCB</cstring>
+ </property>
+ <property name="text">
+ <string>For signing &amp;and encrypting</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>60</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>personalDataPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Your Personal Data</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>On this page, you will enter some personal data that will be stored in your certificate and that will help other people to determine that it is actually you who is sending a message.</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer row="4" column="0">
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>440</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton" row="4" column="1">
+ <property name="name">
+ <cstring>insertAddressButton</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Insert My Address</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>This will insert your address if you have set the "Who am I" information in the address book</string>
+ </property>
+ </widget>
+ <spacer row="1" column="0">
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QFrame" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>edContainer</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>3</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>generatePage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Decentralized Key Generation</string>
+ </attribute>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>TextLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;qt&gt;&lt;p&gt;On this page, you will create a key pair in a decentralized way.
+&lt;/p&gt;&lt;p&gt;You can either store the certificate request in a file for later transmission or
+send it to the Certificate Authority (CA) directly. Please check with
+your local help desk if you are unsure what to select here.&lt;/p&gt;&lt;p&gt;
+Once you are done with your settings, click
+&lt;em&gt;Generate Key Pair and Certificate Request&lt;/em&gt; in order to generate your key pair and a corresponding certificate request.&lt;/p&gt;
+&lt;p&gt;&lt;b&gt;Note:&lt;/b&gt; if you choose to send via email directly,
+a kmail composer will be opened; you can add detailed information for the CA
+there.&lt;/p&gt;&lt;qt&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <spacer row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QButtonGroup" row="2" column="0" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>ButtonGroup7</cstring>
+ </property>
+ <property name="sizePolicy">
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>1</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Certificate Request Options</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="KURLRequester" row="0" column="1">
+ <property name="name">
+ <cstring>storeUR</cstring>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="0" column="0">
+ <property name="name">
+ <cstring>storeInFileRB</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Store in a file:</string>
+ </property>
+ </widget>
+ <widget class="QRadioButton" row="1" column="0">
+ <property name="name">
+ <cstring>sendToCARB</cstring>
+ </property>
+ <property name="text">
+ <string>Send to CA as an &amp;email message:</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1">
+ <property name="name">
+ <cstring>caEmailED</cstring>
+ </property>
+ </widget>
+ <widget class="QCheckBox" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>brokenCA</cstring>
+ </property>
+ <property name="text">
+ <string>Add email to DN in request for broken CAs</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QPushButton" row="3" column="1">
+ <property name="name">
+ <cstring>generatePB</cstring>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>30</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>&amp;Generate Key Pair &amp;&amp; Certificate Request</string>
+ </property>
+ </widget>
+ <spacer row="3" column="2">
+ <property name="name">
+ <cstring>Spacer12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>118</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ <spacer row="3" column="0">
+ <property name="name">
+ <cstring>Spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>119</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </grid>
+ </widget>
+ <widget class="QWidget">
+ <property name="name">
+ <cstring>finishPage</cstring>
+ </property>
+ <attribute name="title">
+ <string>Your Certificate Request is Ready to Be Sent</string>
+ </attribute>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>&lt;qt&gt;
+Your key pair has now been created and stored locally. The corresponding certificate request is now ready to be sent to the CA (certification authority) which will generate a certificate for you and send it back via email (unless you have selected storage in a file). Please review the certificate details shown below.
+&lt;p&gt;
+If you want to change anything, press Back and make your changes; otherwise, press Finish to send the certificate request to the CA.
+&lt;/qt&gt;</string>
+ </property>
+ <property name="alignment">
+ <set>WordBreak|AlignVCenter</set>
+ </property>
+ </widget>
+ <widget class="QTextEdit">
+ <property name="name">
+ <cstring>certificateTE</cstring>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+</widget>
+<customwidgets>
+</customwidgets>
+<connections>
+ <connection>
+ <sender>generatePB</sender>
+ <signal>clicked()</signal>
+ <receiver>CertificateWizard</receiver>
+ <slot>slotGenerateCertificate()</slot>
+ </connection>
+ <connection>
+ <sender>sendToCARB</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>caEmailED</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>storeInFileRB</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>storeUR</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>caEmailED</sender>
+ <signal>textChanged(const QString&amp;)</signal>
+ <receiver>CertificateWizard</receiver>
+ <slot>slotEmailAddressChanged(const QString&amp;)</slot>
+ </connection>
+ <connection>
+ <sender>sendToCARB</sender>
+ <signal>clicked()</signal>
+ <receiver>caEmailED</receiver>
+ <slot>setFocus()</slot>
+ </connection>
+ <connection>
+ <sender>storeInFileRB</sender>
+ <signal>clicked()</signal>
+ <receiver>storeUR</receiver>
+ <slot>setFocus()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>sendToCARB</tabstop>
+ <tabstop>caEmailED</tabstop>
+ <tabstop>certificateTE</tabstop>
+ <tabstop>generatePB</tabstop>
+</tabstops>
+<slots>
+ <slot access="protected">slotEmailAddressChanged(const QString&amp;)</slot>
+ <slot access="protected">slotGenerateCertificate()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>klineedit.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/certmanager/certificatewizardimpl.cpp b/certmanager/certificatewizardimpl.cpp
new file mode 100644
index 000000000..a88c54d84
--- /dev/null
+++ b/certmanager/certificatewizardimpl.cpp
@@ -0,0 +1,515 @@
+/*
+ certificatewizardimpl.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "certificatewizardimpl.h"
+#include "storedtransferjob.h"
+
+// libkleopatra
+#include <kleo/oidmap.h>
+#include <kleo/keygenerationjob.h>
+#include <kleo/dn.h>
+#include <kleo/cryptobackendfactory.h>
+
+#include <ui/progressdialog.h>
+
+// gpgme++
+#include <gpgmepp/keygenerationresult.h>
+
+// KDE
+#include <kabc/stdaddressbook.h>
+#include <kabc/addressee.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kurlrequester.h>
+#include <kdcopservicestarter.h>
+#include <dcopclient.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+
+// Qt
+#include <qlineedit.h>
+#include <qtextedit.h>
+#include <qpushbutton.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+
+#include <assert.h>
+#include <dcopref.h>
+
+static const unsigned int keyLengths[] = {
+ 1024, 1532, 2048, 3072, 4096
+};
+static const unsigned int numKeyLengths = sizeof keyLengths / sizeof *keyLengths;
+
+static QString attributeLabel( const QString & attr, bool required ) {
+ if ( attr.isEmpty() )
+ return QString::null;
+ const QString label = Kleo::DNAttributeMapper::instance()->name2label( attr );
+ if ( !label.isEmpty() )
+ if ( required )
+ return i18n("Format string for the labels in the \"Your Personal Data\" page - required field",
+ "*%1 (%2):").arg( label, attr );
+ else
+ return i18n("Format string for the labels in the \"Your Personal Data\" page",
+ "%1 (%2):").arg( label, attr );
+
+ else if ( required )
+ return '*' + attr + ':';
+ else
+ return attr + ':';
+}
+
+static QString attributeFromKey( QString key ) {
+ return key.remove( '!' );
+}
+
+static bool availForMod( const QLineEdit * le ) {
+ return le && le->isEnabled();
+}
+
+/*
+ * Constructs a CertificateWizardImpl which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The wizard will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal wizard.
+ */
+CertificateWizardImpl::CertificateWizardImpl( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : CertificateWizard( parent, name, modal, fl )
+{
+ // don't allow to go to last page until a key has been generated
+ setNextEnabled( generatePage, false );
+ // setNextEnabled( personalDataPage, false ); // ## disable again once we have a criteria when to enable again
+
+ createPersonalDataPage();
+
+ // Allow to select remote URLs
+ storeUR->setMode( KFile::File );
+ storeUR->setFilter( "application/pkcs10" );
+ connect( storeUR, SIGNAL( urlSelected( const QString& ) ),
+ this, SLOT( slotURLSelected( const QString& ) ) );
+
+ const KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" );
+ caEmailED->setText( config.readEntry( "CAEmailAddress" ) );
+
+ connect( this, SIGNAL( helpClicked() ),
+ this, SLOT( slotHelpClicked() ) );
+ connect( insertAddressButton, SIGNAL( clicked() ),
+ this, SLOT( slotSetValuesFromWhoAmI() ) );
+
+ for ( unsigned int i = 0 ; i < numKeyLengths ; ++i )
+ keyLengthCB->insertItem( i18n("%n bit", "%n bits", keyLengths[i] ) );
+}
+
+static bool requirementsAreMet( const CertificateWizardImpl::AttrPairList & list ) {
+ for ( CertificateWizardImpl::AttrPairList::const_iterator it = list.begin() ;
+ it != list.end() ; ++it ) {
+ const QLineEdit * le = (*it).second;
+ if ( !le )
+ continue;
+ const QString key = (*it).first;
+#ifndef NDEBUG
+ kdbgstream s = kdDebug();
+#else
+ kndbgstream s = kdDebug();
+#endif
+ s << "requirementsAreMet(): checking \"" << key << "\" against \"" << le->text() << "\": ";
+ if ( key.endsWith("!") && le->text().stripWhiteSpace().isEmpty() ) {
+ s << "required field is empty!" << endl;
+ return false;
+ }
+ s << "ok" << endl;
+ }
+ return true;
+}
+
+/*
+ This slot is called when the user changes the text.
+ */
+void CertificateWizardImpl::slotEnablePersonalDataPageExit() {
+ setNextEnabled( personalDataPage, requirementsAreMet( _attrPairList ) );
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+CertificateWizardImpl::~CertificateWizardImpl()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+static const char * oidForAttributeName( const QString & attr ) {
+ QCString attrUtf8 = attr.utf8();
+ for ( unsigned int i = 0 ; i < numOidMaps ; ++i )
+ if ( qstricmp( attrUtf8, oidmap[i].name ) == 0 )
+ return oidmap[i].oid;
+ return 0;
+}
+
+/*
+ * protected slot
+ */
+void CertificateWizardImpl::slotGenerateCertificate()
+{
+ // Ask gpgme to generate a key and return it
+ QString certParms;
+ certParms += "<GnupgKeyParms format=\"internal\">\n";
+ certParms += "Key-Type: RSA\n";
+ certParms += QString( "Key-Length: %1\n" ).arg( keyLengths[keyLengthCB->currentItem()] );
+ certParms += "Key-Usage: ";
+ if ( signOnlyCB->isChecked() )
+ certParms += "Sign";
+ else if ( encryptOnlyCB->isChecked() )
+ certParms += "Encrypt";
+ else
+ certParms += "Sign, Encrypt";
+ certParms += "\n";
+ certParms += "name-dn: ";
+
+ QString email;
+ QStringList rdns;
+ for( AttrPairList::const_iterator it = _attrPairList.begin(); it != _attrPairList.end(); ++it ) {
+ const QString attr = attributeFromKey( (*it).first.upper() );
+ const QLineEdit * le = (*it).second;
+ if ( !le )
+ continue;
+
+ const QString value = le->text().stripWhiteSpace();
+ if ( value.isEmpty() )
+ continue;
+
+ if ( attr == "EMAIL" ) {
+ // EMAIL is special, since it shouldn't be part of the DN,
+ // except for non-RFC-conformant CAs that require it to be
+ // there.
+ email = value;
+ if ( !brokenCA->isChecked() )
+ continue;
+ }
+
+ if ( const char * oid = oidForAttributeName( attr ) ) {
+ // we need to translate the attribute name for the backend:
+ rdns.push_back( QString::fromUtf8( oid ) + '=' + Kleo::DN::escape( value ) );
+ } else {
+ rdns.push_back( attr + '=' + Kleo::DN::escape( value ) );
+ }
+ }
+ certParms += rdns.join(",");
+ if( !email.isEmpty() )
+ certParms += "\nname-email: " + email;
+ certParms += "\n</GnupgKeyParms>\n";
+
+ kdDebug() << certParms << endl;
+
+ Kleo::KeyGenerationJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->keyGenerationJob();
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::KeyGenerationResult&,const QByteArray&)),
+ SLOT(slotResult(const GpgME::KeyGenerationResult&,const QByteArray&)) );
+
+ certificateTE->setText( certParms );
+
+ const GpgME::Error err = job->start( certParms );
+ if ( err )
+ KMessageBox::error( this,
+ i18n( "Could not start certificate generation: %1" )
+ .arg( QString::fromLocal8Bit( err.asString() ) ),
+ i18n( "Certificate Manager Error" ) );
+ else {
+ generatePB->setEnabled( false );
+ setBackEnabled( generatePage, false );
+ (void)new Kleo::ProgressDialog( job, i18n("Generating key"), this );
+ }
+}
+
+
+void CertificateWizardImpl::slotResult( const GpgME::KeyGenerationResult & res,
+ const QByteArray & keyData ) {
+ //kdDebug() << "keyData.size(): " << keyData.size() << endl;
+ _keyData = keyData;
+
+ if ( res.error().isCanceled() || res.error() ) {
+ setNextEnabled( generatePage, false );
+ setBackEnabled( generatePage, true );
+ setFinishEnabled( finishPage, false );
+ generatePB->setEnabled( true );
+ if ( !res.error().isCanceled() )
+ KMessageBox::error( this,
+ i18n( "Could not generate certificate: %1" )
+ .arg( QString::fromLatin1( res.error().asString() ) ),
+ i18n( "Certificate Manager Error" ) );
+ } else {
+ // next will stay enabled until the user clicks Generate
+ // Certificate again
+ setNextEnabled( generatePage, true );
+ setFinishEnabled( finishPage, true );
+ }
+}
+
+void CertificateWizardImpl::slotHelpClicked()
+{
+ kapp->invokeHelp( "newcert" );
+}
+
+void CertificateWizardImpl::slotSetValuesFromWhoAmI()
+{
+ const KABC::Addressee a = KABC::StdAddressBook::self( true )->whoAmI();
+ if ( a.isEmpty() )
+ return;
+ const KABC::Address adr = a.address(KABC::Address::Work);
+
+ for ( AttrPairList::const_iterator it = _attrPairList.begin() ;
+ it != _attrPairList.end() ; ++it ) {
+ QLineEdit * le = (*it).second;
+ if ( !availForMod( le ) )
+ continue;
+
+ const QString attr = attributeFromKey( (*it).first.upper() );
+ if ( attr == "CN" )
+ le->setText( a.formattedName() );
+ else if ( attr == "EMAIL" )
+ le->setText( a.preferredEmail() );
+ else if ( attr == "O" )
+ le->setText( a.organization() );
+ else if ( attr == "OU" )
+ le->setText( a.custom( "KADDRESSBOOK", "X-Department" ) );
+ else if ( attr == "L" )
+ le->setText( adr.locality() );
+ else if ( attr == "SP" )
+ le->setText( adr.region() );
+ else if ( attr == "PC" )
+ le->setText( adr.postalCode() );
+ else if ( attr == "SN" )
+ le->setText( a.familyName() );
+ else if ( attr == "GN" )
+ le->setText( a.givenName() );
+ else if ( attr == "T" )
+ le->setText( a.title() );
+ else if ( attr == "BC" )
+ le->setText( a.role() ); // correct mapping?
+ }
+}
+
+void CertificateWizardImpl::createPersonalDataPage()
+{
+ QGridLayout* grid = new QGridLayout( edContainer, 2, 1,
+ KDialog::marginHint(), KDialog::spacingHint() );
+
+ KConfigGroup config( KGlobal::config(), "CertificateCreationWizard" );
+ QStringList attrOrder = config.readListEntry( "DNAttributeOrder" );
+ if ( attrOrder.empty() )
+ attrOrder << "CN!" << "L" << "OU" << "O!" << "C!" << "EMAIL!";
+ int row = 0;
+
+ for ( QStringList::const_iterator it = attrOrder.begin() ; it != attrOrder.end() ; ++it, ++row ) {
+ const QString key = (*it).stripWhiteSpace().upper();
+ const QString attr = attributeFromKey( key );
+ if ( attr.isEmpty() ) {
+ --row;
+ continue;
+ }
+ const QString preset = config.readEntry( attr );
+ const QString label = config.readEntry( attr + "_label",
+ attributeLabel( attr, key.endsWith("!") ) );
+
+ QLineEdit * le = new QLineEdit( edContainer );
+ grid->addWidget( le, row, 1 );
+ grid->addWidget( new QLabel( le, label.isEmpty() ? attr : label, edContainer ), row, 0 );
+
+ le->setText( preset );
+ if ( config.entryIsImmutable( attr ) )
+ le->setEnabled( false );
+
+ _attrPairList.append(qMakePair(key, le));
+
+ connect( le, SIGNAL(textChanged(const QString&)),
+ SLOT(slotEnablePersonalDataPageExit()) );
+ }
+
+ // enable button only if administrator wants to allow it
+ if (KABC::StdAddressBook::self( true )->whoAmI().isEmpty() ||
+ !config.readBoolEntry("ShowSetWhoAmI", true))
+ insertAddressButton->setEnabled( false );
+
+ slotEnablePersonalDataPageExit();
+}
+
+bool CertificateWizardImpl::sendToCA() const {
+ return sendToCARB->isChecked();
+}
+
+QString CertificateWizardImpl::caEMailAddress() const {
+ return caEmailED->text().stripWhiteSpace();
+}
+
+void CertificateWizardImpl::slotURLSelected( const QString& _url )
+{
+ KURL url = KURL::fromPathOrURL( _url.stripWhiteSpace() );
+#if ! KDE_IS_VERSION(3,2,90)
+ // The application/pkcs10 mimetype didn't have a native extension,
+ // so the filedialog didn't have the checkbox for auto-adding it.
+ QString fileName = url.fileName();
+ int pos = fileName.findRev( '.' );
+ if ( pos < 0 ) // no extension
+ url.setFileName( fileName + ".p10" );
+#endif
+ storeUR->setURL( url.prettyURL() );
+}
+
+KURL CertificateWizardImpl::saveFileUrl() const {
+ return KURL::fromPathOrURL( storeUR->url().stripWhiteSpace() );
+}
+
+void CertificateWizardImpl::showPage( QWidget * page )
+{
+ CertificateWizard::showPage( page );
+ if ( page == generatePage ) {
+ // Initial settings for the generation page: focus the correct lineedit
+ // and disable the other one
+ if ( storeInFileRB->isChecked() ) {
+ storeUR->setEnabled( true );
+ caEmailED->setEnabled( false );
+ storeUR->setFocus();
+ } else {
+ storeUR->setEnabled( false );
+ caEmailED->setEnabled( true );
+ caEmailED->setFocus();
+ }
+ }
+}
+
+static const char* const dcopObjectId = "KMailIface";
+/**
+ Send the new certificate by mail using KMail
+ */
+void CertificateWizardImpl::sendCertificate( const QString& email, const QByteArray& certificateData )
+{
+ QString error;
+ QCString dcopService;
+ int result = KDCOPServiceStarter::self()->
+ findServiceFor( "DCOP/Mailer", QString::null,
+ QString::null, &error, &dcopService );
+ if ( result != 0 ) {
+ kdDebug() << "Couldn't connect to KMail\n";
+ KMessageBox::error( this,
+ i18n( "DCOP Communication Error, unable to send certificate using KMail.\n%1" ).arg( error ) );
+ return;
+ }
+
+ QCString dummy;
+ // OK, so kmail (or kontact) is running. Now ensure the object we want is available.
+ // [that's not the case when kontact was already running, but kmail not loaded into it... in theory.]
+ if ( !kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) ) {
+ DCOPRef ref( dcopService, dcopService ); // talk to the KUniqueApplication or its kontact wrapper
+ DCOPReply reply = ref.call( "load()" );
+ if ( reply.isValid() && (bool)reply ) {
+ Q_ASSERT( kapp->dcopClient()->findObject( dcopService, dcopObjectId, "", QByteArray(), dummy, dummy ) );
+ } else
+ kdWarning() << "Error loading " << dcopService << endl;
+ }
+
+ DCOPClient* dcopClient = kapp->dcopClient();
+ QByteArray data;
+ QDataStream arg( data, IO_WriteOnly );
+ arg << email;
+ arg << certificateData;
+ if( !dcopClient->send( dcopService, dcopObjectId,
+ "sendCertificate(QString,QByteArray)", data ) ) {
+ KMessageBox::error( this,
+ i18n( "DCOP Communication Error, unable to send certificate using KMail." ) );
+ return;
+ }
+ // All good, close dialog
+ CertificateWizard::accept();
+}
+
+// Called when pressing Finish
+// We want to do the emailing/uploading first, before closing the dialog,
+// in case of errors during the upload.
+void CertificateWizardImpl::accept()
+{
+ if( sendToCA() ) {
+ // Ask KMail to send this key to the CA.
+ sendCertificate( caEMailAddress(), _keyData );
+ } else {
+ // Save in file/URL
+ KURL url = saveFileUrl();
+ bool overwrite = false;
+ if ( KIO::NetAccess::exists( url, false /*dest*/, this ) ) {
+ if ( KMessageBox::Cancel == KMessageBox::warningContinueCancel(
+ this,
+ i18n( "A file named \"%1\" already exists. "
+ "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
+ i18n( "Overwrite File?" ),
+ i18n( "&Overwrite" ) ) )
+ return;
+ overwrite = true;
+ }
+
+ KIO::Job* uploadJob = KIOext::put( _keyData, url, -1, overwrite, false /*resume*/ );
+ uploadJob->setWindow( this );
+ connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( slotUploadResult( KIO::Job* ) ) );
+ // Can't press finish again during the upload
+ setFinishEnabled( finishPage, false );
+ }
+}
+
+/**
+ This slot is invoked by the KIO job used in newCertificate
+ to save/upload the certificate, when finished (success or error).
+*/
+void CertificateWizardImpl::slotUploadResult( KIO::Job* job )
+{
+ if ( job->error() ) {
+ job->showErrorDialog();
+ setFinishEnabled( finishPage, true );
+ } else {
+ // All good, close dialog
+ CertificateWizard::accept();
+ }
+}
+
+#include "certificatewizardimpl.moc"
diff --git a/certmanager/certificatewizardimpl.h b/certmanager/certificatewizardimpl.h
new file mode 100644
index 000000000..d275cbc72
--- /dev/null
+++ b/certmanager/certificatewizardimpl.h
@@ -0,0 +1,88 @@
+/*
+ certificatewizardimpl.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CERTIFICATEWIZARDIMPL_H
+#define CERTIFICATEWIZARDIMPL_H
+#include "certificatewizard.h"
+
+#include <qcstring.h>
+#include <qvaluevector.h>
+#include <qlineedit.h>
+#include <kurl.h>
+
+namespace GpgME {
+ class KeyGenerationResult;
+}
+namespace KIO {
+ class Job;
+}
+
+class CertificateWizardImpl : public CertificateWizard
+{
+ Q_OBJECT
+
+public:
+ CertificateWizardImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~CertificateWizardImpl();
+
+ bool sendToCA() const;
+ QString caEMailAddress() const;
+ KURL saveFileUrl() const;
+
+ typedef QPair<QString, QLineEdit*> StringLEPair;
+ typedef QValueVector< StringLEPair > AttrPairList;
+
+public:
+ virtual void showPage( QWidget * page );
+ virtual void accept();
+
+private slots:
+ void slotGenerateCertificate();
+ void slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData );
+ void slotSetValuesFromWhoAmI();
+ void slotEnablePersonalDataPageExit();
+ void slotURLSelected( const QString& );
+
+ void slotHelpClicked();
+
+ void slotUploadResult( KIO::Job* );
+
+private:
+ void createPersonalDataPage();
+ void sendCertificate( const QString& email, const QByteArray& certificateData );
+
+private:
+ AttrPairList _attrPairList;
+ QByteArray _keyData;
+};
+
+#endif // CERTIFICATEWIZARDIMPL_H
diff --git a/certmanager/certlistview.cpp b/certmanager/certlistview.cpp
new file mode 100644
index 000000000..acb6e8916
--- /dev/null
+++ b/certmanager/certlistview.cpp
@@ -0,0 +1,44 @@
+#include <config.h>
+#include "certlistview.h"
+#include <kurldrag.h>
+#include <kdebug.h>
+
+CertKeyListView::CertKeyListView( const ColumnStrategy * strategy,
+ const DisplayStrategy * display,
+ QWidget * parent, const char * name, WFlags f )
+ : Kleo::KeyListView( strategy, display, parent, name, f )
+{
+ viewport()->setAcceptDrops( true );
+}
+
+void CertKeyListView::contentsDragEnterEvent( QDragEnterEvent * event )
+{
+ //const char* fmt;
+ //for (int i=0; (fmt = event->format(i)); i++)
+ // kdDebug() << fmt << endl;
+
+ // We only accept URL drops. We'll check the mimetype later on.
+ event->accept( QUriDrag::canDecode( event ) );
+}
+
+void CertKeyListView::contentsDragMoveEvent( QDragMoveEvent * event )
+{
+ event->accept( QUriDrag::canDecode( event ) );
+}
+
+
+void CertKeyListView::contentsDragLeaveEvent( QDragLeaveEvent * )
+{
+ // Don't let QListView do its stuff
+}
+
+void CertKeyListView::contentsDropEvent( QDropEvent * event )
+{
+ KURL::List lst;
+ if ( KURLDrag::decode( event, lst ) ) {
+ event->accept();
+ emit dropped( lst );
+ }
+}
+
+#include "certlistview.moc"
diff --git a/certmanager/certlistview.h b/certmanager/certlistview.h
new file mode 100644
index 000000000..311b42050
--- /dev/null
+++ b/certmanager/certlistview.h
@@ -0,0 +1,28 @@
+#ifndef CERTLISTVIEW_H
+#define CERTLISTVIEW_H
+
+#include <ui/keylistview.h>
+#include <kurl.h>
+
+/// We need to derive from Kleo::KeyListView simply to add support for drop events
+class CertKeyListView : public Kleo::KeyListView {
+ Q_OBJECT
+
+public:
+ CertKeyListView( const ColumnStrategy * strategy,
+ const DisplayStrategy * display=0,
+ QWidget * parent=0, const char * name=0, WFlags f=0 );
+
+signals:
+ void dropped( const KURL::List& urls );
+
+protected:
+ virtual void contentsDragEnterEvent ( QDragEnterEvent * );
+ virtual void contentsDragMoveEvent( QDragMoveEvent * );
+ virtual void contentsDragLeaveEvent( QDragLeaveEvent * );
+ virtual void contentsDropEvent ( QDropEvent * );
+
+};
+
+
+#endif /* CERTLISTVIEW_H */
diff --git a/certmanager/certmanager.cpp b/certmanager/certmanager.cpp
new file mode 100644
index 000000000..b27f2ad57
--- /dev/null
+++ b/certmanager/certmanager.cpp
@@ -0,0 +1,1432 @@
+/*
+ certmanager.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "certmanager.h"
+
+#include "certlistview.h"
+#include "certificatewizardimpl.h"
+#include "certificateinfowidgetimpl.h"
+#include "crlview.h"
+#include "customactions.h"
+#include "hierarchyanalyser.h"
+#include "storedtransferjob.h"
+#include "conf/configuredialog.h"
+
+// libkleopatra
+#include <kleo/cryptobackendfactory.h>
+#include <kleo/downloadjob.h>
+#include <kleo/importjob.h>
+#include <kleo/exportjob.h>
+#include <kleo/multideletejob.h>
+#include <kleo/deletejob.h>
+#include <kleo/keylistjob.h>
+#include <kleo/dn.h>
+#include <kleo/keyfilter.h>
+#include <kleo/keyfiltermanager.h>
+#include <kleo/hierarchicalkeylistjob.h>
+#include <kleo/refreshkeysjob.h>
+#include <kleo/cryptoconfig.h>
+
+#include <ui/progressdialog.h>
+#include <ui/progressbar.h>
+#include <ui/keyselectiondialog.h>
+#include <ui/cryptoconfigdialog.h>
+
+// GPGME++
+#include <gpgmepp/importresult.h>
+#include <gpgmepp/keylistresult.h>
+#include <gpgmepp/key.h>
+
+// KDE
+#include <kfiledialog.h>
+#include <kprocess.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <dcopclient.h>
+#include <ktoolbar.h>
+#include <kstatusbar.h>
+#include <kstandarddirs.h>
+#include <kdebug.h>
+#include <kdialogbase.h>
+#include <kkeydialog.h>
+#include <ktempfile.h>
+#include <kio/job.h>
+#include <kio/netaccess.h>
+#include <kstdaccel.h>
+
+// Qt
+#include <qfontmetrics.h>
+#include <qpopupmenu.h>
+
+// other
+#include <algorithm>
+#include <assert.h>
+#include <kdepimmacros.h>
+#include <kinputdialog.h>
+namespace {
+
+ class KDE_EXPORT DisplayStrategy : public Kleo::KeyListView::DisplayStrategy{
+ public:
+ ~DisplayStrategy() {}
+
+ virtual QFont keyFont( const GpgME::Key& key, const QFont& font ) const {
+ const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
+ return filter ? filter->font( font ) : font;
+ }
+ virtual QColor keyForeground( const GpgME::Key& key, const QColor& c ) const {
+ const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
+ if ( filter && filter->fgColor().isValid() )
+ return filter->fgColor();
+ return c;
+ }
+ virtual QColor keyBackground( const GpgME::Key& key, const QColor& c ) const {
+ const Kleo::KeyFilter* filter = Kleo::KeyFilterManager::instance()->filterMatching( key );
+ if ( filter && filter->bgColor().isValid() )
+ return filter->bgColor();
+ return c;
+ }
+ };
+
+ class KDE_EXPORT ColumnStrategy : public Kleo::KeyListView::ColumnStrategy {
+ public:
+ ~ColumnStrategy() {}
+
+ QString title( int col ) const;
+ QString text( const GpgME::Key & key, int col ) const;
+ int width( int col, const QFontMetrics & fm ) const;
+ };
+
+ QString ColumnStrategy::title( int col ) const {
+ switch ( col ) {
+ case 0: return i18n("Subject");
+ case 1: return i18n("Issuer");
+ case 2: return i18n("Serial");
+ default: return QString::null;
+ }
+ }
+
+ QString ColumnStrategy::text( const GpgME::Key & key, int col ) const {
+ switch ( col ) {
+ case 0: return Kleo::DN( key.userID(0).id() ).prettyDN();
+ case 1: return Kleo::DN( key.issuerName() ).prettyDN();
+ case 2: return key.issuerSerial() ? QString::fromUtf8( key.issuerSerial() ) : QString::null ;
+ default: return QString::null;
+ }
+ }
+
+ int ColumnStrategy::width( int col, const QFontMetrics & fm ) const {
+ int factor = -1;
+ switch ( col ) {
+ case 0: factor = 6; break;
+ case 1: factor = 4; break;
+ default: return -1;
+ }
+ return fm.width( title( col ) ) * factor;
+ }
+} // anon namespace
+
+CertManager::CertManager( bool remote, const QString& query, const QString & import,
+ QWidget* parent, const char* name, WFlags f )
+ : KMainWindow( parent, name, f|WDestructiveClose ),
+ mCrlView( 0 ),
+ mDirmngrProc( 0 ),
+ mHierarchyAnalyser( 0 ),
+ mLineEditAction( 0 ),
+ mComboAction( 0 ),
+ mFindAction( 0 ),
+ mImportCertFromFileAction( 0 ),
+ mImportCRLFromFileAction( 0 ),
+ mNextFindRemote( remote ),
+ mRemote( remote ),
+ mDirMngrFound( false )
+{
+ readConfig( query.isEmpty() );
+ createStatusBar();
+ createActions();
+
+ createGUI();
+ setAutoSaveSettings();
+
+ // Main Window --------------------------------------------------
+ mKeyListView = new CertKeyListView( new ColumnStrategy(), new DisplayStrategy(), this, "mKeyListView" );
+ mKeyListView->setSelectionMode( QListView::Extended );
+ setCentralWidget( mKeyListView );
+
+ connect( mKeyListView, SIGNAL(doubleClicked(Kleo::KeyListViewItem*,const QPoint&,int)),
+ SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
+ connect( mKeyListView, SIGNAL(returnPressed(Kleo::KeyListViewItem*)),
+ SLOT(slotViewDetails(Kleo::KeyListViewItem*)) );
+ connect( mKeyListView, SIGNAL(selectionChanged()),
+ SLOT(slotSelectionChanged()) );
+ connect( mKeyListView, SIGNAL(contextMenu(Kleo::KeyListViewItem*, const QPoint&)),
+ SLOT(slotContextMenu(Kleo::KeyListViewItem*, const QPoint&)) );
+
+ connect( mKeyListView, SIGNAL(dropped(const KURL::List&) ),
+ SLOT( slotDropped(const KURL::List&) ) );
+
+ mLineEditAction->setText(query);
+ if ( !mRemote && !mNextFindRemote || !query.isEmpty() )
+ slotSearch();
+
+ if ( !import.isEmpty() )
+ slotImportCertFromFile( KURL( import ) );
+
+ slotToggleHierarchicalView( mHierarchicalView );
+ updateStatusBarLabels();
+ slotSelectionChanged(); // initial state for selection-dependent actions
+}
+
+CertManager::~CertManager() {
+ writeConfig();
+ delete mDirmngrProc; mDirmngrProc = 0;
+ delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
+}
+
+void CertManager::readConfig( bool noQueryGiven ) {
+ KConfig config( "kleopatrarc" );
+ config.setGroup( "Display Options" );
+ mHierarchicalView = config.readBoolEntry( "hierarchicalView", false );
+ if ( noQueryGiven ) {
+ mNextFindRemote = config.readBoolEntry( "startInRemoteMode", false );
+ }
+}
+
+void CertManager::writeConfig() {
+ KConfig config( "kleopatrarc" );
+ config.setGroup( "Display Options" );
+ config.writeEntry( "hierarchicalView", mKeyListView->hierarchical() );
+ config.writeEntry( "startInRemoteMode", mNextFindRemote );
+}
+
+void CertManager::createStatusBar() {
+ KStatusBar * bar = statusBar();
+ mProgressBar = new Kleo::ProgressBar( bar, "mProgressBar" );
+ mProgressBar->reset();
+ mProgressBar->setFixedSize( QSize( 100, mProgressBar->height() * 3 / 5 ) );
+ bar->addWidget( mProgressBar, 0, true );
+ mStatusLabel = new QLabel( bar, "mStatusLabel" );
+ bar->addWidget( mStatusLabel, 1, false );
+}
+
+static inline void connectEnableOperationSignal( QObject * s, QObject * d ) {
+ QObject::connect( s, SIGNAL(enableOperations(bool)),
+ d, SLOT(setEnabled(bool)) );
+}
+
+
+void CertManager::createActions() {
+ KAction * action = 0;
+
+ (void)KStdAction::quit( this, SLOT(close()), actionCollection() );
+
+ action = KStdAction::redisplay( this, SLOT(slotRedisplay()), actionCollection() );
+ // work around the fact that the stdaction has no shortcut
+ KShortcut reloadShortcut = KStdAccel::shortcut(KStdAccel::Reload);
+ reloadShortcut.append(KKey(CTRL + Key_R));
+ action->setShortcut( reloadShortcut );
+
+ connectEnableOperationSignal( this, action );
+
+ action = new KAction( i18n("Stop Operation"), "stop", Key_Escape,
+ this, SIGNAL(stopOperations()),
+ actionCollection(), "view_stop_operations" );
+ action->setEnabled( false );
+
+ (void) new KAction( i18n("New Key Pair..."), "filenew", 0,
+ this, SLOT(newCertificate()),
+ actionCollection(), "file_new_certificate" );
+
+ connect( new KToggleAction( i18n("Hierarchical Key List"), 0,
+ actionCollection(), "view_hierarchical" ),
+ SIGNAL(toggled(bool)), SLOT(slotToggleHierarchicalView(bool)) );
+
+ action = new KAction( i18n("Expand All"), 0, CTRL+Key_Period,
+ this, SLOT(slotExpandAll()),
+ actionCollection(), "view_expandall" );
+ action = new KAction( i18n("Collapse All"), 0, CTRL+Key_Comma,
+ this, SLOT(slotCollapseAll()),
+ actionCollection(), "view_collapseall" );
+
+ (void) new KAction( i18n("Refresh CRLs"), 0, 0,
+ this, SLOT(slotRefreshKeys()),
+ actionCollection(), "certificates_refresh_clr" );
+
+#ifdef NOT_IMPLEMENTED_ANYWAY
+ mRevokeCertificateAction = new KAction( i18n("Revoke"), 0,
+ this, SLOT(revokeCertificate()),
+ actionCollection(), "edit_revoke_certificate" );
+ connectEnableOperationSignal( this, mRevokeCertificateAction );
+
+ mExtendCertificateAction = new KAction( i18n("Extend"), 0,
+ this, SLOT(extendCertificate()),
+ actionCollection(), "edit_extend_certificate" );
+ connectEnableOperationSignal( this, mExtendCertificateAction );
+#endif
+
+ mDeleteCertificateAction = new KAction( i18n("Delete"), "editdelete", Key_Delete,
+ this, SLOT(slotDeleteCertificate()),
+ actionCollection(), "edit_delete_certificate" );
+ connectEnableOperationSignal( this, mDeleteCertificateAction );
+
+ mValidateCertificateAction = new KAction( i18n("Validate"), "reload", SHIFT + Key_F5,
+ this, SLOT(slotValidate()),
+ actionCollection(), "certificates_validate" );
+ connectEnableOperationSignal( this, mValidateCertificateAction );
+
+ mImportCertFromFileAction = new KAction( i18n("Import Certificates..."), 0,
+ this, SLOT(slotImportCertFromFile()),
+ actionCollection(), "file_import_certificates" );
+ connectEnableOperationSignal( this, mImportCertFromFileAction );
+
+ mImportCRLFromFileAction = new KAction( i18n("Import CRLs..."), 0,
+ this, SLOT(importCRLFromFile()),
+ actionCollection(), "file_import_crls" );
+ connectEnableOperationSignal( this, mImportCRLFromFileAction );
+
+ mExportCertificateAction = new KAction( i18n("Export Certificates..."), "export", 0,
+ this, SLOT(slotExportCertificate()),
+ actionCollection(), "file_export_certificate" );
+
+ mExportSecretKeyAction = new KAction( i18n("Export Secret Key..."), "export", 0,
+ this, SLOT(slotExportSecretKey()),
+ actionCollection(), "file_export_secret_keys" );
+ connectEnableOperationSignal( this, mExportSecretKeyAction );
+
+ mViewCertDetailsAction = new KAction( i18n("Certificate Details..."), 0, 0,
+ this, SLOT(slotViewDetails()), actionCollection(),
+ "view_certificate_details" );
+ mDownloadCertificateAction = new KAction( i18n( "Download"), 0, 0,
+ this, SLOT(slotDownloadCertificate()), actionCollection(),
+ "download_certificate" );
+
+ const QString dirmngr = KStandardDirs::findExe( "gpgsm" );
+ mDirMngrFound = !dirmngr.isEmpty();
+
+ action = new KAction( i18n("Dump CRL Cache..."), 0,
+ this, SLOT(slotViewCRLs()),
+ actionCollection(), "crl_dump_crl_cache" );
+ action->setEnabled( mDirMngrFound ); // we also need dirmngr for this
+
+ action = new KAction( i18n("Clear CRL Cache..."), 0,
+ this, SLOT(slotClearCRLs()),
+ actionCollection(), "crl_clear_crl_cache" );
+ action->setEnabled( mDirMngrFound ); // we also need dirmngr for this
+
+ action = new KAction( i18n("GnuPG Log Viewer..."), "pgp-keys", 0, this,
+ SLOT(slotStartWatchGnuPG()), actionCollection(), "tools_start_kwatchgnupg");
+ // disable action if no kwatchgnupg binary is around
+ if (KStandardDirs::findExe("kwatchgnupg").isEmpty()) action->setEnabled(false);
+
+ (void)new LabelAction( i18n("Search:"), actionCollection(), "label_action" );
+
+ mLineEditAction = new LineEditAction( QString::null, actionCollection(), this,
+ SLOT(slotSearch()),
+ "query_lineedit_action");
+
+ QStringList lst;
+ lst << i18n("In Local Certificates") << i18n("In External Certificates");
+ mComboAction = new ComboAction( lst, actionCollection(), this, SLOT( slotToggleRemote(int) ),
+ "location_combo_action", mNextFindRemote? 1 : 0 );
+
+ mFindAction = new KAction( i18n("Find"), "find", 0, this, SLOT(slotSearch()),
+ actionCollection(), "find" );
+
+ KStdAction::keyBindings( this, SLOT(slotEditKeybindings()), actionCollection() );
+ KStdAction::preferences( this, SLOT(slotShowConfigurationDialog()), actionCollection() );
+
+ new KAction( i18n( "Configure &GpgME Backend" ), 0, 0, this, SLOT(slotConfigureGpgME()),
+ actionCollection(), "configure_gpgme" );
+
+ createStandardStatusBarAction();
+ updateImportActions( true );
+}
+
+void CertManager::updateImportActions( bool enable ) {
+ mImportCRLFromFileAction->setEnabled( mDirMngrFound && enable );
+ mImportCertFromFileAction->setEnabled( enable );
+}
+
+void CertManager::slotEditKeybindings() {
+ KKeyDialog::configure( actionCollection(), true );
+}
+
+void CertManager::slotShowConfigurationDialog() {
+ ConfigureDialog dlg( this );
+ connect( &dlg, SIGNAL( configCommitted() ), SLOT( slotRepaint() ) );
+ dlg.exec();
+}
+
+void CertManager::slotConfigureGpgME() {
+ Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
+ if ( config ) {
+ Kleo::CryptoConfigDialog dlg( config );
+
+ int result = dlg.exec();
+
+ // Forget all data parsed from gpgconf, so that we show updated information
+ // when reopening the configuration dialog.
+ config->clear();
+
+ if ( result == QDialog::Accepted )
+ {
+ // Tell other apps (e.g. kmail) that the gpgconf data might have changed
+ kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
+ }
+ }
+}
+
+void CertManager::slotRepaint()
+{
+ mKeyListView->repaintContents();
+}
+
+void CertManager::slotToggleRemote( int idx ) {
+ mNextFindRemote = idx != 0;
+}
+
+void CertManager::slotToggleHierarchicalView( bool hier ) {
+ mHierarchicalView = hier;
+ mKeyListView->setHierarchical( hier );
+ mKeyListView->setRootIsDecorated( hier );
+ if ( KAction * act = action("view_expandall") )
+ act->setEnabled( hier );
+ if ( KAction * act = action("view_collapseall" ) )
+ act->setEnabled( hier );
+ if ( KToggleAction * act =
+ static_cast<KToggleAction*>( action("view_hierarchical") ) )
+ act->setChecked( hier );
+
+ if ( hier && !mCurrentQuery.isEmpty() )
+ startRedisplay( false );
+}
+
+void CertManager::slotExpandAll() {
+ for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
+ it.current()->setOpen( true );
+}
+
+void CertManager::slotCollapseAll() {
+ for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
+ it.current()->setOpen( false );
+}
+
+void CertManager::connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText ) {
+ assert( mProgressBar );
+ if ( !job )
+ return;
+ if ( !initialText.isEmpty() )
+ statusBar()->message( initialText );
+ connect( job, SIGNAL(progress(const QString&,int,int)),
+ mProgressBar, SLOT(slotProgress(const QString&,int,int)) );
+ connect( job, SIGNAL(done()), mProgressBar, SLOT(reset()) );
+ connect( this, SIGNAL(stopOperations()), job, SLOT(slotCancel()) );
+
+ action("view_stop_operations")->setEnabled( true );
+ emit enableOperations( false );
+}
+
+void CertManager::disconnectJobFromStatusBarProgress( const GpgME::Error & err ) {
+ updateStatusBarLabels();
+ const QString msg = err.isCanceled() ? i18n("Canceled.")
+ : err ? i18n("Failed.")
+ : i18n("Done.") ;
+ statusBar()->message( msg, 4000 );
+
+ action("view_stop_operations")->setEnabled( false );
+ emit enableOperations( true );
+ slotSelectionChanged();
+}
+
+void CertManager::updateStatusBarLabels() {
+ mKeyListView->flushKeys();
+ int total = 0;
+ for ( QListViewItemIterator it( mKeyListView ) ; it.current() ; ++it )
+ ++total;
+ mStatusLabel->setText( i18n( "%n Key.","%n Keys.", total ) );
+}
+
+//
+//
+// Key Listing:
+//
+//
+
+
+static std::set<std::string> extractKeyFingerprints( const QPtrList<Kleo::KeyListViewItem> & items ) {
+ std::set<std::string> result;
+ for ( QPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
+ if ( const char * fpr = it.current()->key().primaryFingerprint() )
+ result.insert( fpr );
+ return result;
+}
+
+static QStringList stringlistFromSet( const std::set<std::string> & set ) {
+ // ARGH. This is madness. Shitty Qt containers don't support QStringList( patterns.begin(), patterns.end() ) :/
+ QStringList sl;
+ for ( std::set<std::string>::const_iterator it = set.begin() ; it != set.end() ; ++it )
+ // let's make extra sure, maybe someone tries to make Qt not support std::string->QString conversion
+ sl.push_back( QString::fromLatin1( it->c_str() ) );
+ return sl;
+}
+
+void CertManager::slotRefreshKeys() {
+ const QStringList keys = stringlistFromSet( extractKeyFingerprints( mKeyListView->selectedItems() ) );
+ Kleo::RefreshKeysJob * job = Kleo::CryptoBackendFactory::instance()->smime()->refreshKeysJob();
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::Error&)),
+ this, SLOT(slotRefreshKeysResult(const GpgME::Error&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Refreshing keys...") );
+ if ( const GpgME::Error err = job->start( keys ) )
+ slotRefreshKeysResult( err );
+}
+
+void CertManager::slotRefreshKeysResult( const GpgME::Error & err ) {
+ disconnectJobFromStatusBarProgress( err );
+ if ( err.isCanceled() )
+ return;
+ if ( err )
+ KMessageBox::error( this, i18n("An error occurred while trying to refresh "
+ "keys:\n%1").arg( QString::fromLocal8Bit( err.asString() ) ),
+ i18n("Refreshing Keys Failed") );
+}
+
+static void showKeyListError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n( "<qt><p>An error occurred while fetching "
+ "the certificates from the backend:</p>"
+ "<p><b>%1</b></p></qt>" )
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+
+ KMessageBox::error( parent, msg, i18n( "Certificate Listing Failed" ) );
+}
+
+void CertManager::slotSearch() {
+ mPreviouslySelectedFingerprints.clear();
+ // Clear display
+ mKeyListView->clear();
+ mCurrentQuery = mLineEditAction->text();
+ startKeyListing( false, false, mCurrentQuery );
+}
+
+void CertManager::startRedisplay( bool validate ) {
+ mPreviouslySelectedFingerprints = extractKeyFingerprints( mKeyListView->selectedItems() );
+ if ( mPreviouslySelectedFingerprints.empty() )
+ startKeyListing( validate, true, mCurrentQuery );
+ else
+ startKeyListing( validate, true, mPreviouslySelectedFingerprints );
+}
+
+void CertManager::startKeyListing( bool validating, bool refresh, const std::set<std::string> & patterns ) {
+ startKeyListing( validating, refresh, stringlistFromSet( patterns ) );
+}
+
+void CertManager::startKeyListing( bool validating, bool refresh, const QStringList & patterns ) {
+ mRemote = mNextFindRemote;
+ mLineEditAction->setEnabled( false );
+ mComboAction->setEnabled( false );
+ mFindAction->setEnabled( false );
+
+ Kleo::KeyListJob * job = 0;
+ if ( !validating && !refresh && mKeyListView->hierarchical() && !patterns.empty() )
+ job = new Kleo::HierarchicalKeyListJob( Kleo::CryptoBackendFactory::instance()->smime(),
+ mRemote, false, validating );
+ else
+ job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( mRemote, false, validating );
+ assert( job );
+
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ mKeyListView, refresh ? SLOT(slotRefreshKey(const GpgME::Key&)) : SLOT(slotAddKey(const GpgME::Key&)) );
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ this, SLOT(slotKeyListResult(const GpgME::KeyListResult&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Fetching keys...") );
+
+ const GpgME::Error err = job->start( patterns ) ;
+ if ( err ) {
+ showKeyListError( this, err );
+ return;
+ }
+ mProgressBar->setProgress( 0, 0 ); // enable busy indicator
+}
+
+static void selectKeys( Kleo::KeyListView * lv, const std::set<std::string> & fprs ) {
+ if ( !lv || fprs.empty() )
+ return;
+ for ( QListViewItemIterator it( lv ) ; it.current() ; ++it )
+ if ( Kleo::KeyListViewItem * item = Kleo::lvi_cast<Kleo::KeyListViewItem>( it.current() ) ) {
+ const char * fpr = item->key().primaryFingerprint();
+ item->setSelected( fpr && fprs.find( fpr ) != fprs.end() );
+ }
+}
+
+void CertManager::slotKeyListResult( const GpgME::KeyListResult & res ) {
+ if ( res.error() )
+ showKeyListError( this, res.error() );
+ else if ( res.isTruncated() )
+ KMessageBox::information( this,
+ i18n("The query result has been truncated.\n"
+ "Either the local or a remote limit on "
+ "the maximum number of returned hits has "
+ "been exceeded.\n"
+ "You can try to increase the local limit "
+ "in the configuration dialog, but if one "
+ "of the configured servers is the limiting "
+ "factor, you have to refine your search.") );
+
+ mLineEditAction->setEnabled( true );
+ mComboAction->setEnabled( true );
+ mFindAction->setEnabled( true );
+
+ mLineEditAction->focusAll();
+ disconnectJobFromStatusBarProgress( res.error() );
+ selectKeys( mKeyListView, mPreviouslySelectedFingerprints );
+}
+
+void CertManager::slotContextMenu(Kleo::KeyListViewItem* item, const QPoint& point) {
+ if ( !item )
+ return;
+ if ( QPopupMenu * popup = static_cast<QPopupMenu*>(factory()->container("listview_popup",this)) )
+ popup->exec( point );
+}
+
+/**
+ This slot is invoked when the user selects "New certificate"
+*/
+void CertManager::newCertificate()
+{
+ CertificateWizardImpl wizard( this );
+ wizard.exec();
+}
+
+/**
+ This slot is invoked when the user selects revoke certificate.
+ The slot will revoke the selected certificates
+*/
+void CertManager::revokeCertificate()
+{
+ qDebug("Not Yet Implemented");
+}
+
+/**
+ This slot is invoked when the user selects extend certificate.
+ It will send an extension request for the selected certificates
+*/
+void CertManager::extendCertificate()
+{
+ qDebug("Not Yet Implemented");
+}
+
+
+//
+//
+// Downloading / Importing Certificates
+//
+//
+
+
+/**
+ This slot is invoked when the user selects Certificates/Import/From File.
+*/
+void CertManager::slotImportCertFromFile()
+{
+ const QString filter = "application/x-x509-ca-cert application/x-pkcs12 application/pkcs7-mime";
+ //const QString filter = QString("*.pem *.der *.p7c *.p12|") + i18n("Certificates (*.pem *.der *.p7c *.p12)");
+ slotImportCertFromFile( KFileDialog::getOpenURL( QString::null, filter, this,
+ i18n( "Select Certificate File" ) ) );
+}
+
+void CertManager::slotImportCertFromFile( const KURL & certURL )
+{
+ if ( !certURL.isValid() ) // empty or malformed
+ return;
+
+ mPreviouslySelectedFingerprints.clear();
+
+ // Prevent two simultaneous imports
+ updateImportActions( false );
+
+ // Download the cert
+ KIOext::StoredTransferJob* importJob = KIOext::storedGet( certURL );
+ importJob->setWindow( this );
+ connect( importJob, SIGNAL(result(KIO::Job*)), SLOT(slotImportResult(KIO::Job*)) );
+}
+
+void CertManager::slotImportResult( KIO::Job* job )
+{
+ if ( job->error() ) {
+ job->showErrorDialog();
+ } else {
+ KIOext::StoredTransferJob* trJob = static_cast<KIOext::StoredTransferJob *>( job );
+ startCertificateImport( trJob->data(), trJob->url().fileName() );
+ }
+
+ updateImportActions( true );
+}
+
+static void showCertificateDownloadError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) {
+ assert( err );
+ const QString msg = i18n( "<qt><p>An error occurred while trying "
+ "to download the certificate %1:</p>"
+ "<p><b>%2</b></p></qt>" )
+ .arg( certDisplayName )
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+
+ KMessageBox::error( parent, msg, i18n( "Certificate Download Failed" ) );
+}
+
+void CertManager::slotDownloadCertificate() {
+ mPreviouslySelectedFingerprints.clear();
+ QPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
+ for ( QPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
+ if ( !it.current()->key().isNull() )
+ if ( const char * fpr = it.current()->key().primaryFingerprint() )
+ slotStartCertificateDownload( fpr, it.current()->text(0) );
+}
+
+// Called from slotDownloadCertificate and from the certificate-details widget
+void CertManager::slotStartCertificateDownload( const QString& fingerprint, const QString& displayName ) {
+ if ( fingerprint.isEmpty() )
+ return;
+
+ Kleo::DownloadJob * job =
+ Kleo::CryptoBackendFactory::instance()->smime()->downloadJob( false /* no armor */ );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
+ SLOT(slotCertificateDownloadResult(const GpgME::Error&,const QByteArray&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Fetching certificate from server...") );
+
+ const GpgME::Error err = job->start( fingerprint );
+ if ( err )
+ showCertificateDownloadError( this, err, displayName );
+ else {
+ mProgressBar->setProgress( 0, 0 );
+ mJobsDisplayNameMap.insert( job, displayName );
+ }
+}
+
+QString CertManager::displayNameForJob( const Kleo::Job *job )
+{
+ JobsDisplayNameMap::iterator it = mJobsDisplayNameMap.find( job );
+ QString displayName;
+ if ( it != mJobsDisplayNameMap.end() ) {
+ displayName = *it;
+ mJobsDisplayNameMap.remove( it );
+ } else {
+ kdWarning() << "Job not found in map: " << job << endl;
+ }
+ return displayName;
+}
+
+// Don't call directly!
+void CertManager::slotCertificateDownloadResult( const GpgME::Error & err, const QByteArray & keyData ) {
+
+ QString displayName = displayNameForJob( static_cast<const Kleo::Job *>( sender() ) );
+
+ if ( err )
+ showCertificateDownloadError( this, err, displayName );
+ else
+ startCertificateImport( keyData, displayName );
+ disconnectJobFromStatusBarProgress( err );
+}
+
+static void showCertificateImportError( QWidget * parent, const GpgME::Error & err, const QString& certDisplayName ) {
+ assert( err );
+ const QString msg = i18n( "<qt><p>An error occurred while trying "
+ "to import the certificate %1:</p>"
+ "<p><b>%2</b></p></qt>" )
+ .arg( certDisplayName )
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n( "Certificate Import Failed" ) );
+}
+
+void CertManager::startCertificateImport( const QByteArray & keyData, const QString& certDisplayName ) {
+ Kleo::ImportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->importJob();
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::ImportResult&)),
+ SLOT(slotCertificateImportResult(const GpgME::ImportResult&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Importing certificates...") );
+
+ kdDebug() << "Importing certificate. keyData size:" << keyData.size() << endl;
+ const GpgME::Error err = job->start( keyData );
+ if ( err )
+ showCertificateImportError( this, err, certDisplayName );
+ else {
+ mProgressBar->setProgress( 0, 0 );
+ mJobsDisplayNameMap.insert( job, certDisplayName );
+ }
+}
+
+void CertManager::slotCertificateImportResult( const GpgME::ImportResult & res ) {
+ QString displayName = displayNameForJob( static_cast<const Kleo::Job *>( sender() ) );
+
+ if ( res.error().isCanceled() ) {
+ // do nothing
+ } else if ( res.error() ) {
+ showCertificateImportError( this, res.error(), displayName );
+ } else {
+
+ const QString normalLine = i18n("<tr><td align=\"right\">%1</td><td>%2</td></tr>");
+ const QString boldLine = i18n("<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>");
+
+ QStringList lines;
+ lines.push_back( normalLine.arg( i18n("Total number processed:"),
+ QString::number( res.numConsidered() ) ) );
+ lines.push_back( normalLine.arg( i18n("Imported:"),
+ QString::number( res.numImported() ) ) );
+ if ( res.newSignatures() )
+ lines.push_back( normalLine.arg( i18n("New signatures:"),
+ QString::number( res.newSignatures() ) ) );
+ if ( res.newUserIDs() )
+ lines.push_back( normalLine.arg( i18n("New user IDs:"),
+ QString::number( res.newUserIDs() ) ) );
+ if ( res.numKeysWithoutUserID() )
+ lines.push_back( normalLine.arg( i18n("Keys without user IDs:"),
+ QString::number( res.numKeysWithoutUserID() ) ) );
+ if ( res.newSubkeys() )
+ lines.push_back( normalLine.arg( i18n("New subkeys:"),
+ QString::number( res.newSubkeys() ) ) );
+ if ( res.newRevocations() )
+ lines.push_back( boldLine.arg( i18n("Newly revoked:"),
+ QString::number( res.newRevocations() ) ) );
+ if ( res.notImported() )
+ lines.push_back( boldLine.arg( i18n("Not imported:"),
+ QString::number( res.notImported() ) ) );
+ if ( res.numUnchanged() )
+ lines.push_back( normalLine.arg( i18n("Unchanged:"),
+ QString::number( res.numUnchanged() ) ) );
+ if ( res.numSecretKeysConsidered() )
+ lines.push_back( normalLine.arg( i18n("Secret keys processed:"),
+ QString::number( res.numSecretKeysConsidered() ) ) );
+ if ( res.numSecretKeysImported() )
+ lines.push_back( normalLine.arg( i18n("Secret keys imported:"),
+ QString::number( res.numSecretKeysImported() ) ) );
+ if ( res.numSecretKeysConsidered() - res.numSecretKeysImported() - res.numSecretKeysUnchanged() > 0 )
+ lines.push_back( boldLine.arg( i18n("Secret keys <em>not</em> imported:"),
+ QString::number( res.numSecretKeysConsidered()
+ - res.numSecretKeysImported()
+ - res.numSecretKeysUnchanged() ) ) );
+ if ( res.numSecretKeysUnchanged() )
+ lines.push_back( normalLine.arg( i18n("Secret keys unchanged:"),
+ QString::number( res.numSecretKeysUnchanged() ) ) );
+
+ KMessageBox::information( this,
+ i18n( "<qt><p>Detailed results of importing %1:</p>"
+ "<table>%2</table></qt>" )
+ .arg( displayName ).arg( lines.join( QString::null ) ),
+ i18n( "Certificate Import Result" ) );
+
+ disconnectJobFromStatusBarProgress( res.error() );
+ // save the fingerprints of imported certs for later selection:
+ const std::vector<GpgME::Import> imports = res.imports();
+ for ( std::vector<GpgME::Import>::const_iterator it = imports.begin() ; it != imports.end() ; ++it )
+ mPreviouslySelectedFingerprints.insert( it->fingerprint() );
+ }
+ importNextURLOrRedisplay();
+}
+
+
+
+/**
+ This slot is called when the dirmngr process that imports a
+ certificate file exists.
+*/
+void CertManager::slotDirmngrExited() {
+ if ( !mDirmngrProc->normalExit() )
+ KMessageBox::error( this, i18n( "The GpgSM process that tried to import the CRL file ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
+ else if ( mDirmngrProc->exitStatus() )
+ KMessageBox::error( this, i18n( "An error occurred when trying to import the CRL file. The output from GpgSM was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) );
+ else
+ KMessageBox::information( this, i18n( "CRL file imported successfully." ), i18n( "Certificate Manager Information" ) );
+
+ delete mDirmngrProc; mDirmngrProc = 0;
+ if ( !mImportCRLTempFile.isEmpty() )
+ QFile::remove( mImportCRLTempFile );
+ updateImportActions( true );
+}
+
+/**
+ This slot will import CRLs from a file.
+*/
+void CertManager::importCRLFromFile() {
+ QString filter = QString("*.crl *.arl *-crl.der *-arl.der|") + i18n("Certificate Revocation List (*.crl *.arl *-crl.der *-arl.der)");
+ KURL url = KFileDialog::getOpenURL( QString::null,
+ filter,
+ this,
+ i18n( "Select CRL File" ) );
+ if ( url.isValid() ) {
+ updateImportActions( false );
+ if ( url.isLocalFile() ) {
+ startImportCRL( url.path(), false );
+ updateImportActions( true );
+ } else {
+ KTempFile tempFile;
+ KURL destURL;
+ destURL.setPath( tempFile.name() );
+ KIO::Job* copyJob = KIO::file_copy( url, destURL, 0600, true, false );
+ copyJob->setWindow( this );
+ connect( copyJob, SIGNAL( result( KIO::Job * ) ),
+ SLOT( slotImportCRLJobFinished( KIO::Job * ) ) );
+ }
+ }
+}
+
+void CertManager::slotImportCRLJobFinished( KIO::Job *job )
+{
+ KIO::FileCopyJob* fcjob = static_cast<KIO::FileCopyJob*>( job );
+ QString tempFilePath = fcjob->destURL().path();
+ if ( job->error() ) {
+ job->showErrorDialog();
+ QFile::remove( tempFilePath ); // unlink tempfile
+ updateImportActions( true );
+ return;
+ }
+ startImportCRL( tempFilePath, true );
+}
+
+bool CertManager::connectAndStartDirmngr( const char * slot, const char * processname ) {
+ assert( slot );
+ assert( processname );
+ assert( mDirmngrProc );
+ mErrorbuffer = QString::null;
+ connect( mDirmngrProc, SIGNAL(processExited(KProcess*)), slot );
+ connect( mDirmngrProc, SIGNAL(receivedStderr(KProcess*,char*,int) ),
+ this, SLOT(slotStderr(KProcess*,char*,int)) );
+ if( !mDirmngrProc->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) {
+ delete mDirmngrProc; mDirmngrProc = 0;
+ KMessageBox::error( this, i18n( "Unable to start %1 process. Please check your installation." ).arg( processname ), i18n( "Certificate Manager Error" ) );
+ return false;
+ }
+ return true;
+}
+
+void CertManager::startImportCRL( const QString& filename, bool isTempFile )
+{
+ assert( !mDirmngrProc );
+ mImportCRLTempFile = isTempFile ? filename : QString::null;
+ mDirmngrProc = new KProcess();
+ *mDirmngrProc << "gpgsm" << "--call-dirmngr" << "loadcrl" << filename;
+ if ( !connectAndStartDirmngr( SLOT(slotDirmngrExited()), "gpgsm" ) ) {
+ updateImportActions( true );
+ if ( isTempFile )
+ QFile::remove( mImportCRLTempFile ); // unlink tempfile
+ }
+}
+
+void CertManager::startClearCRLs() {
+ assert( !mDirmngrProc );
+ mDirmngrProc = new KProcess();
+ *mDirmngrProc << "dirmngr" << "--flush";
+ //*mDirmngrProc << "gpgsm" << "--call-dimngr" << "flush"; // use this once it's implemented!
+ connectAndStartDirmngr( SLOT(slotClearCRLsResult()), "dirmngr" );
+}
+
+void CertManager::slotStderr( KProcess*, char* buf, int len ) {
+ mErrorbuffer += QString::fromLocal8Bit( buf, len );
+}
+
+/**
+ This slot will import CRLs from an LDAP server.
+*/
+void CertManager::importCRLFromLDAP()
+{
+ qDebug("Not Yet Implemented");
+}
+
+void CertManager::slotViewCRLs() {
+ if ( !mCrlView )
+ mCrlView = new CRLView( this );
+
+ mCrlView->show();
+ mCrlView->slotUpdateView();
+}
+
+
+void CertManager::slotClearCRLs() {
+ startClearCRLs();
+}
+
+void CertManager::slotClearCRLsResult() {
+ assert( mDirmngrProc );
+ if ( !mDirmngrProc->normalExit() )
+ KMessageBox::error( this, i18n( "The DirMngr process that tried to clear the CRL cache ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
+ else if ( mDirmngrProc->exitStatus() )
+ KMessageBox::error( this, i18n( "An error occurred when trying to clear the CRL cache. The output from DirMngr was:\n%1").arg( mErrorbuffer ), i18n( "Certificate Manager Error" ) );
+ else
+ KMessageBox::information( this, i18n( "CRL cache cleared successfully." ), i18n( "Certificate Manager Information" ) );
+ delete mDirmngrProc; mDirmngrProc = 0;
+}
+
+static void showDeleteError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n("<qt><p>An error occurred while trying to delete "
+ "the certificates:</p>"
+ "<p><b>%1</b></p></qt>")
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n("Certificate Deletion Failed") );
+}
+
+static bool ByFingerprint( const GpgME::Key & left, const GpgME::Key & right ) {
+ return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) < 0 ;
+}
+
+static bool WithRespectToFingerprints( const GpgME::Key & left, const GpgME::Key & right ) {
+ return qstricmp( left.primaryFingerprint(), right.primaryFingerprint() ) == 0;
+}
+
+void CertManager::slotDeleteCertificate() {
+ mItemsToDelete = mKeyListView->selectedItems();
+ if ( mItemsToDelete.isEmpty() )
+ return;
+ std::vector<GpgME::Key> keys;
+ keys.reserve( mItemsToDelete.count() );
+ QStringList keyDisplayNames;
+ for ( QPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete ) ; it.current() ; ++it )
+ if ( !it.current()->key().isNull() ) {
+ keys.push_back( it.current()->key() );
+ keyDisplayNames.push_back( it.current()->text( 0 ) );
+ }
+ if ( keys.empty() )
+ return;
+
+ if ( !mHierarchyAnalyser ) {
+ mHierarchyAnalyser = new HierarchyAnalyser( this, "mHierarchyAnalyser" );
+ Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob();
+ assert( job );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ mHierarchyAnalyser, SLOT(slotNextKey(const GpgME::Key&)) );
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ this, SLOT(slotDeleteCertificate()) );
+ connectJobToStatusBarProgress( job, i18n("Checking key dependencies...") );
+ if ( const GpgME::Error error = job->start( QStringList() ) ) {
+ showKeyListError( this, error );
+ delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
+ }
+ return;
+ } else
+ disconnectJobFromStatusBarProgress( 0 );
+
+ std::vector<GpgME::Key> keysToDelete = keys;
+ for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
+ if ( !it->isNull() ) {
+ const std::vector<GpgME::Key> subjects
+ = mHierarchyAnalyser->subjectsForIssuerRecursive( it->primaryFingerprint() );
+ keysToDelete.insert( keysToDelete.end(), subjects.begin(), subjects.end() );
+ }
+
+ std::sort( keysToDelete.begin(), keysToDelete.end(), ByFingerprint );
+ keysToDelete.erase( std::unique( keysToDelete.begin(), keysToDelete.end(),
+ WithRespectToFingerprints ),
+ keysToDelete.end() );
+
+ delete mHierarchyAnalyser; mHierarchyAnalyser = 0;
+
+ if ( keysToDelete.size() > keys.size() )
+ if ( KMessageBox::warningContinueCancel( this,
+ i18n("Some or all of the selected "
+ "certificates are issuers (CA certificates) "
+ "for other, non-selected certificates.\n"
+ "Deleting a CA certificate will also delete "
+ "all certificates issued by it."),
+ i18n("Deleting CA Certificates") )
+ != KMessageBox::Continue )
+ return;
+
+ const QString msg = keysToDelete.size() > keys.size()
+ ? i18n("Do you really want to delete this certificate and the %1 certificates it certified?",
+ "Do you really want to delete these %n certificates and the %1 certificates they certified?",
+ keys.size() ).arg( keysToDelete.size() - keys.size() )
+ : i18n("Do you really want to delete this certificate?",
+ "Do you really want to delete these %n certificates?", keys.size() ) ;
+
+ if ( KMessageBox::warningContinueCancelList( this, msg, keyDisplayNames,
+ i18n( "Delete Certificates" ),
+ KGuiItem( i18n( "Delete" ), "editdelete" ),
+ "ConfirmDeleteCert", KMessageBox::Dangerous )
+ != KMessageBox::Continue )
+ return;
+
+ if ( Kleo::DeleteJob * job = Kleo::CryptoBackendFactory::instance()->smime()->deleteJob() )
+ job->slotCancel();
+ else {
+ QString str = keys.size() == 1
+ ? i18n("<qt><p>An error occurred while trying to delete "
+ "the certificate:</p>"
+ "<p><b>%1</b><p></qt>" )
+ : i18n( "<qt><p>An error occurred while trying to delete "
+ "the certificates:</p>"
+ "<p><b>%1</b><p></qt>" );
+ KMessageBox::error( this,
+ str.arg( i18n("Operation not supported by the backend.") ),
+ i18n("Certificate Deletion Failed") );
+ }
+
+ mItemsToDelete.clear(); // re-create according to the real selection
+ for ( std::vector<GpgME::Key>::const_iterator it = keysToDelete.begin() ; it != keysToDelete.end() ; ++it )
+ if ( Kleo::KeyListViewItem * item = mKeyListView->itemByFingerprint( it->primaryFingerprint() ) )
+ mItemsToDelete.append( item );
+
+ Kleo::MultiDeleteJob * job = new Kleo::MultiDeleteJob( Kleo::CryptoBackendFactory::instance()->smime() );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::Error&,const GpgME::Key&)),
+ SLOT(slotDeleteResult(const GpgME::Error&,const GpgME::Key&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Deleting keys...") );
+
+ const GpgME::Error err = job->start( keys, true );
+ if ( err )
+ showDeleteError( this, err );
+ else
+ mProgressBar->setProgress( 0, 0 );
+}
+
+void CertManager::slotDeleteResult( const GpgME::Error & err, const GpgME::Key & ) {
+ if ( err )
+ showDeleteError( this, err );
+ else {
+ const int infinity = 100; // infinite loop guard...
+ mItemsToDelete.setAutoDelete( true );
+ for ( int i = 0 ; i < infinity ; ++i ) {
+ QPtrListIterator<Kleo::KeyListViewItem> it( mItemsToDelete );
+ while ( Kleo::KeyListViewItem * cur = it.current() ) {
+ ++it;
+ if ( cur->childCount() == 0 ) {
+ mItemsToDelete.remove( cur );
+ }
+ }
+ if ( mItemsToDelete.isEmpty() )
+ break;
+ }
+ mItemsToDelete.setAutoDelete( false );
+ Q_ASSERT( mItemsToDelete.isEmpty() );
+ mItemsToDelete.clear();
+ }
+ disconnectJobFromStatusBarProgress( err );
+}
+
+void CertManager::slotViewDetails( Kleo::KeyListViewItem * item ) {
+ if ( !item || item->key().isNull() )
+ return;
+
+ // <UGH>
+ KDialogBase * dialog = new KDialogBase( this, "dialog", false, i18n("Additional Information for Key"), KDialogBase::Close, KDialogBase::Close );
+
+ CertificateInfoWidgetImpl * top = new CertificateInfoWidgetImpl( item->key(), isRemote(), dialog );
+ dialog->setMainWidget( top );
+ // </UGH>
+ connect( top, SIGNAL(requestCertificateDownload(const QString&, const QString&)),
+ SLOT(slotStartCertificateDownload(const QString&, const QString&)) );
+ dialog->show();
+}
+
+void CertManager::slotViewDetails()
+{
+ QPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
+ if ( items.isEmpty() )
+ return;
+
+ // selectedItem() doesn't work in Extended mode.
+ // But we only want to show the details of one item...
+ slotViewDetails( items.first() );
+}
+
+void CertManager::slotSelectionChanged()
+{
+ mKeyListView->flushKeys();
+ bool b = mKeyListView->hasSelection();
+ mExportCertificateAction->setEnabled( b );
+ mViewCertDetailsAction->setEnabled( b );
+ mDeleteCertificateAction->setEnabled( b );
+#ifdef NOT_IMPLEMENTED_ANYWAY
+ mRevokeCertificateAction->setEnabled( b );
+ mExtendCertificateAction->setEnabled( b );
+#endif
+ mDownloadCertificateAction->setEnabled( b && mRemote );
+ mValidateCertificateAction->setEnabled( !mRemote );
+}
+
+void CertManager::slotExportCertificate() {
+ QPtrList<Kleo::KeyListViewItem> items = mKeyListView->selectedItems();
+ if ( items.isEmpty() )
+ return;
+
+ QStringList fingerprints;
+ for ( QPtrListIterator<Kleo::KeyListViewItem> it( items ) ; it.current() ; ++it )
+ if ( !it.current()->key().isNull() )
+ if ( const char * fpr = it.current()->key().primaryFingerprint() )
+ fingerprints.push_back( fpr );
+
+ startCertificateExport( fingerprints );
+}
+
+static void showCertificateExportError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n("<qt><p>An error occurred while trying to export "
+ "the certificate:</p>"
+ "<p><b>%1</b></p></qt>")
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n("Certificate Export Failed") );
+}
+
+void CertManager::startCertificateExport( const QStringList & fingerprints ) {
+ if ( fingerprints.empty() )
+ return;
+
+ // we need to use PEM (ascii armoured) format, since DER (binary)
+ // can't transport more than one certificate *sigh* this is madness :/
+ Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->publicKeyExportJob( true );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
+ SLOT(slotCertificateExportResult(const GpgME::Error&,const QByteArray&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Exporting certificate...") );
+
+ const GpgME::Error err = job->start( fingerprints );
+ if ( err )
+ showCertificateExportError( this, err );
+ else
+ mProgressBar->setProgress( 0, 0 );
+}
+
+// return true if we should proceed, false if we should abort
+static bool checkOverwrite( const KURL& url, bool& overwrite, QWidget* w )
+{
+ if ( KIO::NetAccess::exists( url, false /*dest*/, w ) ) {
+ if ( KMessageBox::Cancel ==
+ KMessageBox::warningContinueCancel(
+ w,
+ i18n( "A file named \"%1\" already exists. "
+ "Are you sure you want to overwrite it?" ).arg( url.prettyURL() ),
+ i18n( "Overwrite File?" ),
+ i18n( "&Overwrite" ) ) )
+ return false;
+ overwrite = true;
+ }
+ return true;
+}
+
+void CertManager::slotCertificateExportResult( const GpgME::Error & err, const QByteArray & data ) {
+ disconnectJobFromStatusBarProgress( err );
+ if ( err ) {
+ showCertificateExportError( this, err );
+ return;
+ }
+
+ kdDebug() << "CertManager::slotCertificateExportResult(): got " << data.size() << " bytes" << endl;
+
+ const QString filter = QString("*.pem|") + i18n("ASCII Armored Certificate Bundles (*.pem)");
+ const KURL url = KFileDialog::getOpenURL( QString::null,
+ filter,
+ this,
+ i18n( "Save Certificate" ) );
+ if ( !url.isValid() )
+ return;
+
+ bool overwrite = false;
+ if ( !checkOverwrite( url, overwrite, this ) )
+ return;
+
+ KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ );
+ uploadJob->setWindow( this );
+ connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( slotUploadResult( KIO::Job* ) ) );
+}
+
+
+void CertManager::slotExportSecretKey() {
+ Kleo::KeySelectionDialog dlg( i18n("Secret Key Export"),
+ i18n("Select the secret key to export "
+ "(<b>Warning: The PKCS#12 format is insecure; "
+ "exporting secret keys is discouraged</b>):"),
+ std::vector<GpgME::Key>(),
+ Kleo::KeySelectionDialog::SecretKeys|Kleo::KeySelectionDialog::SMIMEKeys,
+ false /* no multiple selection */,
+ false /* no remember choice box */,
+ this, "secret key export key selection dialog" );
+ //dlg.setHideInvalidKeys( false );
+
+ if ( dlg.exec() != QDialog::Accepted )
+ return;
+
+ startSecretKeyExport( dlg.fingerprint() );
+}
+
+static void showSecretKeyExportError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n("<qt><p>An error occurred while trying to export "
+ "the secret key:</p>"
+ "<p><b>%1</b></p></qt>")
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+ KMessageBox::error( parent, msg, i18n("Secret-Key Export Failed") );
+}
+
+void CertManager::startSecretKeyExport( const QString & fingerprint ) {
+ if ( fingerprint.isEmpty() )
+ return;
+
+ // PENDING(marc): let user choose between binary and PEM format?
+
+ // Check if gpgsm supports --p12-charset
+ Kleo::CryptoConfig* config = Kleo::CryptoBackendFactory::instance()->config();
+ QString charset;
+ if ( config && config->entry( "gpgsm", "Configuration", "p12-charset" ) ) {
+ // This comes from gnupg's sources, agent/minip12.c
+ // In fact, any charset supported by iconv would work, but we don't link to iconv directly...
+ static const char *charsets[] = {
+ "utf8",
+ "iso-8859-1",
+ "iso-8859-15",
+ "iso-8859-2",
+ "iso-8859-3",
+ "iso-8859-4",
+ "iso-8859-5",
+ "iso-8859-6",
+ "iso-8859-7",
+ "iso-8859-8",
+ "iso-8859-9",
+ "koi8-r",
+ "ibm437",
+ "ibm850",
+ "euc-jp",
+ "big5",
+ NULL
+ };
+ QStringList charsetList;
+ for ( const char** c = charsets; *c; ++c ) {
+ charsetList.append( QString::fromLatin1( *c ) );
+ }
+
+ // TODO this selection could be done in a derived KeySelectionDialog which would add a combobox,
+ // it would be better integrated.
+ bool ok;
+ charset = KInputDialog::getItem( i18n("Exporting secret key..."),
+ i18n("Choose a charset for encoding the pkcs#12 passphrase (utf8 is recommended)"),
+ charsetList,
+ 0, false /*editable*/,
+ &ok, this );
+ if ( !ok )
+ return;
+ }
+
+ Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->smime()->secretKeyExportJob( false, charset );
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::Error&,const QByteArray&)),
+ SLOT(slotSecretKeyExportResult(const GpgME::Error&,const QByteArray&)) );
+
+ connectJobToStatusBarProgress( job, i18n("Exporting secret key...") );
+
+ const GpgME::Error err = job->start( fingerprint );
+ if ( err )
+ showSecretKeyExportError( this, err );
+ else
+ mProgressBar->setProgress( 0, 0 );
+}
+
+void CertManager::slotSecretKeyExportResult( const GpgME::Error & err, const QByteArray & data ) {
+ disconnectJobFromStatusBarProgress( err );
+ if ( err ) {
+ showSecretKeyExportError( this, err );
+ return;
+ }
+
+ kdDebug() << "CertManager::slotSecretKeyExportResult(): got " << data.size() << " bytes" << endl;
+ QString filter = QString("*.p12|") + i18n("PKCS#12 Key Bundle (*.p12)");
+ KURL url = KFileDialog::getOpenURL( QString::null,
+ filter,
+ this,
+ i18n( "Save Certificate" ) );
+ if ( !url.isValid() )
+ return;
+
+ bool overwrite = false;
+ if ( !checkOverwrite( url, overwrite, this ) )
+ return;
+
+ KIO::Job* uploadJob = KIOext::put( data, url, -1, overwrite, false /*resume*/ );
+ uploadJob->setWindow( this );
+ connect( uploadJob, SIGNAL( result( KIO::Job* ) ),
+ this, SLOT( slotUploadResult( KIO::Job* ) ) );
+}
+
+void CertManager::slotUploadResult( KIO::Job* job )
+{
+ if ( job->error() )
+ job->showErrorDialog();
+}
+
+void CertManager::slotDropped(const KURL::List& lst)
+{
+ mURLsToImport = lst;
+ if ( !lst.empty() )
+ importNextURLOrRedisplay();
+}
+
+void CertManager::importNextURLOrRedisplay()
+{
+ if ( !mURLsToImport.empty() ) {
+ // We can only import them one by one, otherwise the jobs would run into each other
+ KURL url = mURLsToImport.front();
+ mURLsToImport.pop_front();
+ slotImportCertFromFile( url );
+ } else {
+ if ( isRemote() )
+ return;
+ startKeyListing( false, true, mPreviouslySelectedFingerprints );
+ }
+}
+
+void CertManager::slotStartWatchGnuPG()
+{
+ KProcess certManagerProc;
+ certManagerProc << "kwatchgnupg";
+
+ if( !certManagerProc.start( KProcess::DontCare ) )
+ KMessageBox::error( this, i18n( "Could not start GnuPG LogViewer (kwatchgnupg). "
+ "Please check your installation!" ),
+ i18n( "Kleopatra Error" ) );
+}
+
+#include "certmanager.moc"
diff --git a/certmanager/certmanager.h b/certmanager/certmanager.h
new file mode 100644
index 000000000..915e079eb
--- /dev/null
+++ b/certmanager/certmanager.h
@@ -0,0 +1,217 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ certmanager.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef _CERTMANAGER_H_
+#define _CERTMANAGER_H_
+
+//#include <gpgme.h>
+
+#include <kmainwindow.h>
+#include <kdepimmacros.h>
+#include <kurl.h>
+#include <qcstring.h>
+#include <qptrlist.h>
+
+#include <set>
+#include <string>
+
+namespace Kleo {
+ class KeyListView;
+ class KeyListViewItem;
+ class ProgressBar;
+ class Job;
+}
+
+namespace KIO {
+ class Job;
+}
+class KProcess;
+class KToolBar;
+class KAction;
+
+class CRLView;
+class HierarchyAnalyser;
+
+class LineEditAction;
+class ComboAction;
+
+class KURL;
+class QFile;
+class QStringList;
+class QLabel;
+
+namespace GpgME {
+ class ImportResult;
+ class KeyListResult;
+ class Error;
+ class Key;
+}
+
+class KDE_EXPORT CertManager : public KMainWindow {
+ Q_OBJECT
+public:
+ CertManager( bool remote = false, const QString& query = QString::null,
+ const QString& import=QString::null,
+ QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~CertManager();
+
+ bool isRemote() const { return mRemote; }
+
+signals:
+ void stopOperations();
+ void enableOperations( bool );
+
+private slots:
+ void slotStartCertificateDownload( const QString & fingerprint, const QString& displayName );
+ void newCertificate();
+ void revokeCertificate();
+ void extendCertificate();
+ void slotDeleteCertificate();
+ void slotExportSecretKey();
+ void slotExportCertificate();
+ void slotUploadResult( KIO::Job* job );
+
+ void slotImportCertFromFile();
+ void slotImportCertFromFile( const KURL & filename );
+ void slotImportResult( KIO::Job* );
+
+ void slotCertificateImportResult( const GpgME::ImportResult & result );
+ void slotCertificateDownloadResult( const GpgME::Error & error, const QByteArray & keyData );
+ void slotKeyListResult( const GpgME::KeyListResult & result );
+ void slotDeleteResult( const GpgME::Error & error, const GpgME::Key & );
+ void slotSecretKeyExportResult( const GpgME::Error & error, const QByteArray & keyData );
+ void slotCertificateExportResult( const GpgME::Error & error, const QByteArray & keyData );
+ void slotClearCRLsResult();
+
+ void importCRLFromFile();
+ void importCRLFromLDAP();
+ void slotImportCRLJobFinished( KIO::Job * );
+
+ void slotDirmngrExited();
+ void slotStderr( KProcess*, char*, int );
+
+ void slotToggleRemote(int idx);
+ void slotToggleHierarchicalView( bool );
+
+ void slotViewCRLs();
+ void slotClearCRLs();
+
+ void slotViewDetails();
+ void slotViewDetails( Kleo::KeyListViewItem * item );
+ void slotSelectionChanged();
+ void slotDownloadCertificate();
+ void slotStartWatchGnuPG();
+
+ void slotEditKeybindings();
+ void slotShowConfigurationDialog();
+ void slotConfigureGpgME();
+ void slotContextMenu(Kleo::KeyListViewItem*, const QPoint& point);
+ void slotDropped(const KURL::List&);
+ /** Schedule a repaint for the listview items. E.g. when the
+ colour config has changed */
+ void slotRepaint();
+ /** Schedule a validating keylisting for the selected items (or
+ all items, if none is selected). */
+ void slotValidate() { startRedisplay( true ); }
+ /** Schedule a non-validating keylisting for the selected items
+ (or all items, if none are selected). */
+ void slotRedisplay() { startRedisplay( false ); }
+ /** Start a keylisting with the current value of the query text as
+ pattern. */
+ void slotSearch();
+
+ void slotExpandAll();
+ void slotCollapseAll();
+ void slotRefreshKeys();
+ void slotRefreshKeysResult( const GpgME::Error & );
+
+private:
+ void createStatusBar();
+ void createActions();
+ void updateStatusBarLabels();
+ void updateImportActions( bool enable );
+ void startKeyListing( bool, bool, const QStringList & );
+ void startKeyListing( bool, bool, const std::set<std::string> & );
+ void startCertificateImport( const QByteArray & keyData, const QString& certDisplayName );
+ void startImportCRL( const QString& fileName, bool isTempFile );
+ void startClearCRLs();
+ void startSecretKeyExport( const QString & fingerprint );
+ void startCertificateExport( const QStringList & fingerprints );
+ bool connectAndStartDirmngr( const char*, const char* );
+ void connectJobToStatusBarProgress( Kleo::Job * job, const QString & initialText );
+ void disconnectJobFromStatusBarProgress( const GpgME::Error & err );
+ void importNextURLOrRedisplay();
+ void startRedisplay( bool validating );
+ QString displayNameForJob( const Kleo::Job *job );
+ void readConfig( bool noQueryGiven );
+ void writeConfig();
+
+private:
+ Kleo::KeyListView * mKeyListView;
+ CRLView * mCrlView;
+ Kleo::ProgressBar * mProgressBar;
+ QLabel * mStatusLabel;
+
+ KProcess * mDirmngrProc;
+ QString mErrorbuffer;
+ QPtrList<Kleo::KeyListViewItem> mItemsToDelete;
+ KURL::List mURLsToImport;
+ typedef QMap<const Kleo::Job *, QString> JobsDisplayNameMap;
+ JobsDisplayNameMap mJobsDisplayNameMap;
+ HierarchyAnalyser * mHierarchyAnalyser;
+
+ LineEditAction * mLineEditAction;
+ ComboAction * mComboAction;
+ KAction * mFindAction;
+ KAction * mImportCertFromFileAction;
+ KAction * mImportCRLFromFileAction;
+ KAction * mExportCertificateAction;
+ KAction * mViewCertDetailsAction;
+ KAction * mDeleteCertificateAction;
+#ifdef NOT_IMPLEMENTED_ANYWAY
+ KAction * mRevokeCertificateAction;
+ KAction * mExtendCertificateAction;
+#endif
+ KAction * mExportSecretKeyAction;
+ KAction * mDownloadCertificateAction;
+ KAction * mValidateCertificateAction;
+
+ QString mImportCRLTempFile;
+ QString mCurrentQuery;
+ std::set<std::string> mPreviouslySelectedFingerprints;
+ bool mNextFindRemote : 1; // state of the combo, i.e. whether the next find action will be remote
+ bool mRemote : 1; // whether the currently displayed items are from a remote listing
+ bool mDirMngrFound : 1;
+ bool mHierarchicalView : 1; // whether to display the list view in hierarchical mode
+};
+
+#endif // _CERTMANAGER_H_
diff --git a/certmanager/conf/Makefile.am b/certmanager/conf/Makefile.am
new file mode 100644
index 000000000..f58c20c77
--- /dev/null
+++ b/certmanager/conf/Makefile.am
@@ -0,0 +1,26 @@
+AM_CPPFLAGS = -DLIBKLEOPATRA_NO_COMPAT -I$(srcdir)/../lib -I$(srcdir)/../lib/ui -I../lib/ui \
+ -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+METASOURCES = AUTO
+
+# the stuff that gets compiled into kleopatra
+noinst_LTLIBRARIES = libconf.la
+libconf_la_SOURCES = configuredialog.cpp
+
+kde_module_LTLIBRARIES = kcm_kleopatra.la
+
+kcm_kleopatra_la_SOURCES = dirservconfigpage.cpp \
+ appearanceconfigpage.cpp \
+ appearanceconfigwidgetbase.ui \
+ appearanceconfigwidget.cpp \
+ dnorderconfigpage.cpp
+
+kcm_kleopatra_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined
+kcm_kleopatra_la_LIBADD = ../lib/libkleopatra.la $(LIB_KDEUI)
+
+kde_services_DATA = \
+ kleopatra_config_dirserv.desktop \
+ kleopatra_config_appear.desktop \
+ kleopatra_config_dnorder.desktop
+
+dirservconfigpage.lo: ../lib/ui/directoryserviceswidgetbase.h
diff --git a/certmanager/conf/appearanceconfigpage.cpp b/certmanager/conf/appearanceconfigpage.cpp
new file mode 100644
index 000000000..5d2a434cc
--- /dev/null
+++ b/certmanager/conf/appearanceconfigpage.cpp
@@ -0,0 +1,87 @@
+/*
+ appearanceconfigpage.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "appearanceconfigpage.h"
+#include <qlayout.h>
+#include "appearanceconfigwidget.h"
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <kdepimmacros.h>
+
+AppearanceConfigurationPage::AppearanceConfigurationPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ QVBoxLayout* lay = new QVBoxLayout( this );
+ mWidget = new Kleo::AppearanceConfigWidget( this );
+ lay->addWidget( mWidget );
+ connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+
+void AppearanceConfigurationPage::load()
+{
+ mWidget->load();
+}
+
+void AppearanceConfigurationPage::save()
+{
+ mWidget->save();
+
+}
+
+void AppearanceConfigurationPage::defaults()
+{
+ mWidget->defaults();
+}
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kleopatra_config_appear( QWidget *parent, const char * )
+ {
+ AppearanceConfigurationPage *page =
+ new AppearanceConfigurationPage( parent, "kleopatra_config_appear" );
+ return page;
+ }
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void AppearanceConfigurationPage::slotChanged()
+{
+ emit changed(true);
+}
+
+#include "appearanceconfigpage.moc"
diff --git a/certmanager/conf/appearanceconfigpage.h b/certmanager/conf/appearanceconfigpage.h
new file mode 100644
index 000000000..c3acea007
--- /dev/null
+++ b/certmanager/conf/appearanceconfigpage.h
@@ -0,0 +1,60 @@
+/*
+ appearanceconfigpage.h
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef _APPEARANCE_CONFIGURE_PAGE_H_
+#define _APPEARANCE_CONFIGURE_PAGE_H_
+
+#include <kcmodule.h>
+
+namespace Kleo {
+ class AppearanceConfigWidget;
+}
+
+/**
+ * "Appearance" configuration page for kleopatra's configuration dialog
+ */
+class AppearanceConfigurationPage : public KCModule {
+ Q_OBJECT
+public:
+ AppearanceConfigurationPage( QWidget * parent=0, const char * name=0 );
+
+ virtual void load();
+ virtual void save();
+ virtual void defaults();
+
+private slots:
+ void slotChanged();
+
+private:
+ Kleo::AppearanceConfigWidget* mWidget;
+};
+
+#endif // _APPEARANCE_CONFIGURE_DIALOG_PRIVATE_H_
diff --git a/certmanager/conf/appearanceconfigwidget.cpp b/certmanager/conf/appearanceconfigwidget.cpp
new file mode 100644
index 000000000..a3d177c2a
--- /dev/null
+++ b/certmanager/conf/appearanceconfigwidget.cpp
@@ -0,0 +1,358 @@
+/*
+ appearanceconfigwidget.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "appearanceconfigwidget.h"
+
+#include <kleo/cryptobackendfactory.h>
+#include <kleo/keyfiltermanager.h>
+
+#include <klistview.h>
+#include <kconfig.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kfontdialog.h>
+#include <kcolordialog.h>
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qheader.h>
+#include <qcolor.h>
+#include <qfont.h>
+#include <qstring.h>
+#include <qpainter.h>
+#include <qregexp.h>
+#include <qcheckbox.h>
+
+#include <assert.h>
+
+using namespace Kleo;
+
+class CategoryListViewItem : public QListViewItem
+{
+public:
+ CategoryListViewItem( QListView* lv, QListViewItem* prev, const KConfigBase& config )
+ : QListViewItem( lv, prev ) {
+
+ setName( config.readEntry( "Name", i18n("<unnamed>") ) );
+ mForegroundColor = config.readColorEntry( "foreground-color" );
+ mBackgroundColor = config.readColorEntry( "background-color" );
+ mHasFont = config.hasKey( "font" );
+ if ( mHasFont ) {
+ setFont( config.readFontEntry( "font" ) ); // sets mItalic and mBold
+ }
+ else {
+ mItalic = config.readBoolEntry( "font-italic", false );
+ mBold = config.readBoolEntry( "font-bold", false );
+ }
+ mStrikeOut = config.readBoolEntry( "font-strikeout", false );
+ mIsExpired = config.readBoolEntry( "is-expired", false );
+ mDirty = false;
+ }
+
+ void save( KConfigBase& config ) {
+ config.writeEntry( "Name", text( 0 ) );
+ config.writeEntry( "foreground-color", mForegroundColor );
+ config.writeEntry( "background-color", mBackgroundColor );
+ if ( mHasFont )
+ config.writeEntry( "font", mFont );
+ else {
+ config.deleteEntry( "font" );
+ config.writeEntry( "font-italic", mItalic );
+ config.writeEntry( "font-bold", mBold );
+ }
+ config.writeEntry( "font-strikeout", mStrikeOut );
+ }
+
+ void setForegroundColor( const QColor& foreground ) { mForegroundColor = foreground; mDirty = true; }
+ void setBackgroundColor( const QColor& background ) { mBackgroundColor = background; mDirty = true; }
+ void setFont( const QFont& font ) {
+ mFont = font;
+ mHasFont = true;
+ mItalic = font.italic();
+ mBold = font.bold();
+ mDirty = true;
+ }
+
+ QColor foregroundColor() const { return mForegroundColor; }
+ QColor backgroundColor() const { return mBackgroundColor; }
+ QFont font() const { return mFont; }
+
+ void setDefaultAppearance() {
+ mForegroundColor = mIsExpired ? Qt::red : QColor();
+ mBackgroundColor = QColor();
+ mHasFont = false;
+ mFont = QFont();
+ mBold = false;
+ mItalic = false;
+ mStrikeOut = false;
+ mDirty = true;
+ }
+
+ bool isDirty() const { return mDirty; }
+ bool isItalic() const { return mItalic; }
+ bool isBold() const { return mBold; }
+ bool isStrikeout() const { return mStrikeOut; }
+ bool hasFont() const { return mHasFont; }
+
+ void toggleItalic() { mItalic = !mItalic; if ( mHasFont ) mFont.setItalic( mItalic ); mDirty = true; }
+ void toggleBold() { mBold = !mBold; if ( mHasFont ) mFont.setBold( mBold ); mDirty = true; }
+ void toggleStrikeout() { mStrikeOut = !mStrikeOut; mDirty = true; }
+
+private:
+ void setName( const QString& name ) {
+ setText( 0, name );
+ }
+
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+
+private:
+ QColor mForegroundColor, mBackgroundColor;
+ QFont mFont;
+ bool mHasFont;
+ bool mIsExpired; // used for default settings
+ bool mItalic;
+ bool mBold;
+ bool mStrikeOut;
+ bool mDirty;
+};
+
+void CategoryListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ QColorGroup _cg = cg;
+ QFont font = p->font();
+ if ( mHasFont )
+ font = mFont;
+ else {
+ if ( mItalic )
+ font.setItalic( true );
+ if ( mBold )
+ font.setBold( true );
+ }
+ if ( mStrikeOut )
+ font.setStrikeOut( true );
+ p->setFont( font );
+
+ if ( mForegroundColor.isValid() )
+ _cg.setColor( QColorGroup::Text, mForegroundColor );
+ if ( mBackgroundColor.isValid() )
+ _cg.setColor( QColorGroup::Base, mBackgroundColor );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+////
+
+Kleo::AppearanceConfigWidget::AppearanceConfigWidget (
+ QWidget* parent, const char* name, WFlags fl )
+ : AppearanceConfigWidgetBase( parent, name, fl )
+{
+ categoriesLV->setSorting( -1 );
+ load();
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+
+AppearanceConfigWidget::~AppearanceConfigWidget()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+void AppearanceConfigWidget::slotSelectionChanged( QListViewItem* item )
+{
+ bool sel = item != 0;
+ foregroundButton->setEnabled( sel );
+ backgroundButton->setEnabled( sel );
+ fontButton->setEnabled( sel );
+ italicCB->setEnabled( item );
+ boldCB->setEnabled( item );
+ strikeoutCB->setEnabled( item );
+ defaultLookPB->setEnabled( sel );
+ if ( item ) {
+ CategoryListViewItem* clvi = static_cast<CategoryListViewItem *>( item );
+ italicCB->setChecked( clvi->isItalic() );
+ boldCB->setChecked( clvi->isBold() );
+ strikeoutCB->setChecked( clvi->isStrikeout() );
+ } else {
+ italicCB->setChecked( false );
+ boldCB->setChecked( false );
+ strikeoutCB->setChecked( false );
+ }
+}
+
+/*
+ * set default appearance for selected category
+ */
+void AppearanceConfigWidget::slotDefaultClicked()
+{
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ if ( !item )
+ return;
+ item->setDefaultAppearance();
+ item->repaint();
+ slotSelectionChanged( item );
+ emit changed();
+}
+
+void AppearanceConfigWidget::load()
+{
+ categoriesLV->clear();
+ KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject();
+ if ( !config )
+ return;
+ QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) );
+ for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
+ KConfigGroup cfg( config, *it );
+ (void) new CategoryListViewItem( categoriesLV, categoriesLV->lastItem(), cfg );
+ }
+}
+
+void AppearanceConfigWidget::save()
+{
+ KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject();
+ if ( !config )
+ return;
+ // We know (assume) that the groups in the config object haven't changed,
+ // so we just iterate over them and over the listviewitems, and map one-to-one.
+ QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) );
+ if ( groups.isEmpty() ) {
+ // If we created the default categories ourselves just now, then we need to make up their list
+ QListViewItemIterator lvit( categoriesLV );
+ for ( ; lvit.current() ; ++lvit )
+ groups << lvit.current()->text( 0 );
+ }
+
+ QListViewItemIterator lvit( categoriesLV );
+ for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() && lvit.current(); ++it, ++lvit ) {
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(lvit.current() );
+ KConfigGroup cfg( config, *it );
+ item->save( cfg );
+ }
+ config->sync();
+ Kleo::KeyFilterManager::instance()->reload();
+}
+
+
+void AppearanceConfigWidget::slotForegroundClicked() {
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QColor fg = item->foregroundColor();
+ int result = KColorDialog::getColor( fg );
+ if ( result == KColorDialog::Accepted ) {
+ item->setForegroundColor( fg );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotBackgroundClicked() {
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QColor bg = item->backgroundColor();
+ int result = KColorDialog::getColor( bg );
+ if ( result == KColorDialog::Accepted ) {
+ item->setBackgroundColor( bg );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotFontClicked() {
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ QFont font = item->font();
+ int result = KFontDialog::getFont( font );
+ if ( result == KFontDialog::Accepted ) {
+ item->setFont( font );
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::defaults()
+{
+ // This simply means "default look for every category"
+ QListViewItemIterator lvit( categoriesLV );
+ for ( ; lvit.current() ; ++lvit ) {
+ CategoryListViewItem* item = static_cast<CategoryListViewItem *>( lvit.current() );
+ item->setDefaultAppearance();
+ item->repaint();
+ }
+ emit changed();
+}
+
+void AppearanceConfigWidget::slotItalicClicked()
+{
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleItalic();
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotBoldClicked()
+{
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleBold();
+ item->repaint();
+ emit changed();
+ }
+}
+
+void AppearanceConfigWidget::slotStrikeoutClicked()
+{
+ CategoryListViewItem* item = static_cast<CategoryListViewItem*>(categoriesLV->selectedItem() );
+ if ( item ) {
+ item->toggleStrikeout();
+ item->repaint();
+ emit changed();
+ }
+}
+
+#include "appearanceconfigwidget.moc"
diff --git a/certmanager/conf/appearanceconfigwidget.h b/certmanager/conf/appearanceconfigwidget.h
new file mode 100644
index 000000000..dc5c79766
--- /dev/null
+++ b/certmanager/conf/appearanceconfigwidget.h
@@ -0,0 +1,73 @@
+/*
+ appearanceconfigwidget.h
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifndef APPEARANCECONFIGWIDGET_H
+#define APPEARANCECONFIGWIDGET_H
+
+#include "appearanceconfigwidgetbase.h"
+#include <qstringlist.h>
+class KConfig;
+
+namespace Kleo {
+
+ class AppearanceConfigWidget : public AppearanceConfigWidgetBase {
+ Q_OBJECT
+
+ public:
+ AppearanceConfigWidget(
+ QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~AppearanceConfigWidget();
+
+ void load();
+ void save();
+
+ public slots:
+ void defaults();
+
+ signals:
+ void changed();
+
+ protected slots:
+ // reimplemented from the base class
+ virtual void slotDefaultClicked();
+ virtual void slotSelectionChanged( QListViewItem * );
+ virtual void slotForegroundClicked();
+ virtual void slotBackgroundClicked();
+ virtual void slotFontClicked();
+ virtual void slotItalicClicked();
+ virtual void slotBoldClicked();
+ virtual void slotStrikeoutClicked();
+ };
+}
+
+#endif // APPEARANCECONFIGWIDGET_H
diff --git a/certmanager/conf/appearanceconfigwidgetbase.ui b/certmanager/conf/appearanceconfigwidgetbase.ui
new file mode 100644
index 000000000..b432ac8c6
--- /dev/null
+++ b/certmanager/conf/appearanceconfigwidgetbase.ui
@@ -0,0 +1,215 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>AppearanceConfigWidgetBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>AppearanceConfigWidgetBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>616</width>
+ <height>352</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Color &amp; Font Configuration</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Key Categories</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>categoriesLV</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>foregroundButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Set &amp;Text Color...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>backgroundButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Set &amp;Background Color...</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>fontButton</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Set F&amp;ont...</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>italicCB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Italic</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>boldCB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Bold</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>strikeoutCB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Strikeout</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>100</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>defaultLookPB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Default Appearance</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ </hbox>
+</widget>
+<connections>
+ <connection>
+ <sender>foregroundButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotForegroundClicked()</slot>
+ </connection>
+ <connection>
+ <sender>backgroundButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotBackgroundClicked()</slot>
+ </connection>
+ <connection>
+ <sender>fontButton</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotFontClicked()</slot>
+ </connection>
+ <connection>
+ <sender>categoriesLV</sender>
+ <signal>selectionChanged(QListViewItem*)</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotSelectionChanged(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>defaultLookPB</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotDefaultClicked()</slot>
+ </connection>
+ <connection>
+ <sender>italicCB</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotItalicClicked()</slot>
+ </connection>
+ <connection>
+ <sender>boldCB</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotBoldClicked()</slot>
+ </connection>
+ <connection>
+ <sender>strikeoutCB</sender>
+ <signal>clicked()</signal>
+ <receiver>AppearanceConfigWidgetBase</receiver>
+ <slot>slotStrikeoutClicked()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>categoriesLV</tabstop>
+ <tabstop>foregroundButton</tabstop>
+ <tabstop>backgroundButton</tabstop>
+ <tabstop>fontButton</tabstop>
+ <tabstop>italicCB</tabstop>
+ <tabstop>boldCB</tabstop>
+ <tabstop>strikeoutCB</tabstop>
+ <tabstop>defaultLookPB</tabstop>
+</tabstops>
+<slots>
+ <slot access="protected">slotForegroundClicked()</slot>
+ <slot access="protected">slotBackgroundClicked()</slot>
+ <slot access="protected">slotFontClicked()</slot>
+ <slot access="protected">slotSelectionChanged( QListViewItem * )</slot>
+ <slot access="protected">slotDefaultClicked()</slot>
+ <slot access="protected">slotItalicClicked()</slot>
+ <slot access="protected">slotBoldClicked()</slot>
+ <slot access="protected">slotStrikeoutClicked()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/certmanager/conf/configuredialog.cpp b/certmanager/conf/configuredialog.cpp
new file mode 100644
index 000000000..87976f106
--- /dev/null
+++ b/certmanager/conf/configuredialog.cpp
@@ -0,0 +1,73 @@
+/*
+ configuredialog.cpp
+
+ This file is part of kleopatra
+ Copyright (C) 2000 Espen Sand, espen@kde.org
+ Copyright (C) 2001-2002 Marc Mutz <mutz@kde.org>
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "configuredialog.h"
+
+#include <kwin.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klocale.h>
+
+ConfigureDialog::ConfigureDialog( QWidget *parent, const char *name, bool modal )
+ : KCMultiDialog( KDialogBase::IconList, i18n( "Configure" ), parent, name, modal )
+{
+ KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
+ showButton( User1, true );
+
+ addModule( "kleopatra_config_dirserv", false );
+ addModule( "kleopatra_config_appear", false );
+ addModule( "kleopatra_config_dnorder", false );
+
+ // We store the size of the dialog on hide, because otherwise
+ // the KCMultiDialog starts with the size of the first kcm, not
+ // the largest one. This way at least after the first showing of
+ // the largest kcm the size is kept.
+ const KConfigGroup geometry( KGlobal::config(), "Geometry" );
+ const int width = geometry.readNumEntry( "ConfigureDialogWidth" );
+ const int height = geometry.readNumEntry( "ConfigureDialogHeight" );
+ if ( width != 0 && height != 0 ) {
+ setMinimumSize( width, height );
+ }
+
+}
+
+void ConfigureDialog::hideEvent( QHideEvent * ) {
+ KConfigGroup geometry( KGlobal::config(), "Geometry" );
+ geometry.writeEntry( "ConfigureDialogWidth", width() );
+ geometry.writeEntry( "ConfigureDialogHeight",height() );
+}
+
+ConfigureDialog::~ConfigureDialog() {
+}
+
+#include "configuredialog.moc"
diff --git a/certmanager/conf/configuredialog.h b/certmanager/conf/configuredialog.h
new file mode 100644
index 000000000..40b7e371b
--- /dev/null
+++ b/certmanager/conf/configuredialog.h
@@ -0,0 +1,52 @@
+/*
+ configuredialog.cpp
+
+ This file is part of kleopatra
+ Copyright (C) 2000 Espen Sand, espen@kde.org
+ Copyright (C) 2001-2002 Marc Mutz <mutz@kde.org>
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef _CONFIGURE_DIALOG_H_
+#define _CONFIGURE_DIALOG_H_
+
+#include <kcmultidialog.h>
+
+class ConfigureDialog : public KCMultiDialog
+{
+ Q_OBJECT
+
+public:
+ ConfigureDialog( QWidget *parent=0, const char *name=0, bool modal=true );
+ ~ConfigureDialog();
+
+protected:
+ void hideEvent( QHideEvent *i );
+
+};
+
+#endif
diff --git a/certmanager/conf/dirservconfigpage.cpp b/certmanager/conf/dirservconfigpage.cpp
new file mode 100644
index 000000000..7711ca2e2
--- /dev/null
+++ b/certmanager/conf/dirservconfigpage.cpp
@@ -0,0 +1,296 @@
+/*
+ dirservconfigpage.cpp
+
+ This file is part of kleopatra
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "dirservconfigpage.h"
+#include "directoryserviceswidget.h"
+
+#include <kleo/cryptobackendfactory.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kconfig.h>
+#include <knuminput.h>
+#include <kdialog.h>
+
+#include <qhbox.h>
+#include <qlabel.h>
+#include <qdatetimeedit.h>
+#include <qcheckbox.h>
+#include <qlayout.h>
+
+#include <kdepimmacros.h>
+
+#if 0 // disabled, since it is apparently confusing
+// For sync'ing kabldaprc
+class KABSynchronizer
+{
+public:
+ KABSynchronizer()
+ : mConfig( "kabldaprc" ) {
+ mConfig.setGroup( "LDAP" );
+ }
+
+ KURL::List readCurrentList() const {
+
+ KURL::List lst;
+ // stolen from kabc/ldapclient.cpp
+ const uint numHosts = mConfig.readUnsignedNumEntry( "NumSelectedHosts" );
+ for ( uint j = 0; j < numHosts; j++ ) {
+ const QString num = QString::number( j );
+
+ KURL url;
+ url.setProtocol( "ldap" );
+ url.setPath( "/" ); // workaround KURL parsing bug
+ const QString host = mConfig.readEntry( QString( "SelectedHost" ) + num ).stripWhiteSpace();
+ url.setHost( host );
+
+ const int port = mConfig.readUnsignedNumEntry( QString( "SelectedPort" ) + num );
+ if ( port != 0 )
+ url.setPort( port );
+
+ const QString base = mConfig.readEntry( QString( "SelectedBase" ) + num ).stripWhiteSpace();
+ url.setQuery( base );
+
+ const QString bindDN = mConfig.readEntry( QString( "SelectedBind" ) + num ).stripWhiteSpace();
+ url.setUser( bindDN );
+
+ const QString pwdBindDN = mConfig.readEntry( QString( "SelectedPwdBind" ) + num ).stripWhiteSpace();
+ url.setPass( pwdBindDN );
+ lst.append( url );
+ }
+ return lst;
+ }
+
+ void writeList( const KURL::List& lst ) {
+
+ mConfig.writeEntry( "NumSelectedHosts", lst.count() );
+
+ KURL::List::const_iterator it = lst.begin();
+ KURL::List::const_iterator end = lst.end();
+ unsigned j = 0;
+ for( ; it != end; ++it, ++j ) {
+ const QString num = QString::number( j );
+ KURL url = *it;
+
+ Q_ASSERT( url.protocol() == "ldap" );
+ mConfig.writeEntry( QString( "SelectedHost" ) + num, url.host() );
+ mConfig.writeEntry( QString( "SelectedPort" ) + num, url.port() );
+
+ // KURL automatically encoded the query (e.g. for spaces inside it),
+ // so decode it before writing it out
+ const QString base = KURL::decode_string( url.query().mid(1) );
+ mConfig.writeEntry( QString( "SelectedBase" ) + num, base );
+ mConfig.writeEntry( QString( "SelectedBind" ) + num, url.user() );
+ mConfig.writeEntry( QString( "SelectedPwdBind" ) + num, url.pass() );
+ }
+ mConfig.sync();
+ }
+
+private:
+ KConfig mConfig;
+};
+
+#endif
+
+static const char s_dirserv_componentName[] = "dirmngr";
+static const char s_dirserv_groupName[] = "LDAP";
+static const char s_dirserv_entryName[] = "LDAP Server";
+
+static const char s_timeout_componentName[] = "dirmngr";
+static const char s_timeout_groupName[] = "LDAP";
+static const char s_timeout_entryName[] = "ldaptimeout";
+
+static const char s_maxitems_componentName[] = "dirmngr";
+static const char s_maxitems_groupName[] = "LDAP";
+static const char s_maxitems_entryName[] = "max-replies";
+
+static const char s_addnewservers_componentName[] = "dirmngr";
+static const char s_addnewservers_groupName[] = "LDAP";
+static const char s_addnewservers_entryName[] = "add-servers";
+
+DirectoryServicesConfigurationPage::DirectoryServicesConfigurationPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ mConfig = Kleo::CryptoBackendFactory::instance()->config();
+ QVBoxLayout* lay = new QVBoxLayout( this, 0, KDialog::spacingHint() );
+ Kleo::CryptoConfigEntry* entry = configEntry( s_dirserv_componentName, s_dirserv_groupName, s_dirserv_entryName,
+ Kleo::CryptoConfigEntry::ArgType_LDAPURL, true );
+ mWidget = new Kleo::DirectoryServicesWidget( entry, this );
+ lay->addWidget( mWidget );
+ connect( mWidget, SIGNAL( changed() ), this, SLOT( slotChanged() ) );
+
+ // LDAP timeout
+ QHBox* box = new QHBox( this );
+ box->setSpacing( KDialog::spacingHint() );
+ lay->addWidget( box );
+ QLabel* label = new QLabel( i18n( "LDAP &timeout (minutes:seconds)" ), box );
+ mTimeout = new QTimeEdit( box );
+ mTimeout->setDisplay( QTimeEdit::Minutes | QTimeEdit::Seconds );
+ connect( mTimeout, SIGNAL( valueChanged( const QTime& ) ), this, SLOT( slotChanged() ) );
+ label->setBuddy( mTimeout );
+ QWidget* stretch = new QWidget( box );
+ box->setStretchFactor( stretch, 2 );
+
+ // Max number of items returned by queries
+ box = new QHBox( this );
+ box->setSpacing( KDialog::spacingHint() );
+ lay->addWidget( box );
+ mMaxItems = new KIntNumInput( box );
+ mMaxItems->setLabel( i18n( "&Maximum number of items returned by query" ), Qt::AlignLeft | Qt::AlignVCenter );
+ mMaxItems->setMinValue( 0 );
+ connect( mMaxItems, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) );
+ stretch = new QWidget( box );
+ box->setStretchFactor( stretch, 2 );
+
+#ifdef NOT_USEFUL_CURRENTLY
+ mAddNewServersCB = new QCheckBox( i18n( "Automatically add &new servers discovered in CRL distribution points" ), this );
+ connect( mAddNewServersCB, SIGNAL( clicked() ), this, SLOT( slotChanged() ) );
+ lay->addWidget( mAddNewServersCB );
+#endif
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+void DirectoryServicesConfigurationPage::load()
+{
+ mWidget->load();
+
+ mTimeoutConfigEntry = configEntry( s_timeout_componentName, s_timeout_groupName, s_timeout_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
+ if ( mTimeoutConfigEntry ) {
+ QTime time = QTime().addSecs( mTimeoutConfigEntry->uintValue() );
+ //kdDebug() << "timeout:" << mTimeoutConfigEntry->uintValue() << " -> " << time << endl;
+ mTimeout->setTime( time );
+ }
+
+ mMaxItemsConfigEntry = configEntry( s_maxitems_componentName, s_maxitems_groupName, s_maxitems_entryName, Kleo::CryptoConfigEntry::ArgType_UInt, false );
+ if ( mMaxItemsConfigEntry ) {
+ mMaxItems->blockSignals( true ); // KNumInput emits valueChanged from setValue!
+ mMaxItems->setValue( mMaxItemsConfigEntry->uintValue() );
+ mMaxItems->blockSignals( false );
+ }
+
+#ifdef NOT_USEFUL_CURRENTLY
+ mAddNewServersConfigEntry = configEntry( s_addnewservers_componentName, s_addnewservers_groupName, s_addnewservers_entryName, Kleo::CryptoConfigEntry::ArgType_None, false );
+ if ( mAddNewServersConfigEntry ) {
+ mAddNewServersCB->setChecked( mAddNewServersConfigEntry->boolValue() );
+ }
+#endif
+}
+
+void DirectoryServicesConfigurationPage::save()
+{
+ mWidget->save();
+
+ QTime time( mTimeout->time() );
+ unsigned int timeout = time.minute() * 60 + time.second();
+ if ( mTimeoutConfigEntry && mTimeoutConfigEntry->uintValue() != timeout )
+ mTimeoutConfigEntry->setUIntValue( timeout );
+ if ( mMaxItemsConfigEntry && mMaxItemsConfigEntry->uintValue() != (uint)mMaxItems->value() )
+ mMaxItemsConfigEntry->setUIntValue( mMaxItems->value() );
+#ifdef NOT_USEFUL_CURRENTLY
+ if ( mAddNewServersConfigEntry && mAddNewServersConfigEntry->boolValue() != mAddNewServersCB->isChecked() )
+ mAddNewServersConfigEntry->setBoolValue( mAddNewServersCB->isChecked() );
+#endif
+
+ mConfig->sync( true );
+
+#if 0
+ // Also write the LDAP URLs to kabldaprc so that they are used by kaddressbook
+ KABSynchronizer sync;
+ const KURL::List toAdd = mWidget->urlList();
+ KURL::List currentList = sync.readCurrentList();
+
+ KURL::List::const_iterator it = toAdd.begin();
+ KURL::List::const_iterator end = toAdd.end();
+ for( ; it != end; ++it ) {
+ // check if the URL is already in currentList
+ if ( currentList.find( *it ) == currentList.end() )
+ // if not, add it
+ currentList.append( *it );
+ }
+ sync.writeList( currentList );
+#endif
+}
+
+void DirectoryServicesConfigurationPage::defaults()
+{
+ mWidget->defaults();
+ if ( mTimeoutConfigEntry )
+ mTimeoutConfigEntry->resetToDefault();
+ if ( mMaxItemsConfigEntry )
+ mMaxItemsConfigEntry->resetToDefault();
+#ifdef NOT_USEFUL_CURRENTLY
+ if ( mAddNewServersConfigEntry )
+ mAddNewServersConfigEntry->resetToDefault();
+#endif
+ load();
+}
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_kleopatra_config_dirserv( QWidget *parent, const char * )
+ {
+ DirectoryServicesConfigurationPage *page =
+ new DirectoryServicesConfigurationPage( parent, "kleopatra_config_dirserv" );
+ return page;
+ }
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void DirectoryServicesConfigurationPage::slotChanged()
+{
+ emit changed(true);
+}
+
+
+// Find config entry for ldap servers. Implements runtime checks on the configuration option.
+Kleo::CryptoConfigEntry* DirectoryServicesConfigurationPage::configEntry( const char* componentName,
+ const char* groupName,
+ const char* entryName,
+ Kleo::CryptoConfigEntry::ArgType argType,
+ bool isList )
+{
+ Kleo::CryptoConfigEntry* entry = mConfig->entry( componentName, groupName, entryName );
+ if ( !entry ) {
+ KMessageBox::error( this, i18n( "Backend error: gpgconf does not seem to know the entry for %1/%2/%3" ).arg( componentName, groupName, entryName ) );
+ return 0;
+ }
+ if( entry->argType() != argType || entry->isList() != isList ) {
+ KMessageBox::error( this, i18n( "Backend error: gpgconf has wrong type for %1/%2/%3: %4 %5" ).arg( componentName, groupName, entryName ).arg( entry->argType() ).arg( entry->isList() ) );
+ return 0;
+ }
+ return entry;
+}
+
+#include "dirservconfigpage.moc"
diff --git a/certmanager/conf/dirservconfigpage.h b/certmanager/conf/dirservconfigpage.h
new file mode 100644
index 000000000..8c7c75439
--- /dev/null
+++ b/certmanager/conf/dirservconfigpage.h
@@ -0,0 +1,84 @@
+/*
+ dirservconfigpage.h
+
+ This file is part of kleopatra
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef DIRSERVCONFIGPAGE_H
+#define DIRSERVCONFIGPAGE_H
+
+#include <kcmodule.h>
+#include <kleo/cryptoconfig.h>
+#include <kdepimmacros.h>
+
+class QCheckBox;
+class QTimeEdit;
+class KIntNumInput;
+namespace Kleo {
+ class CryptoConfig;
+ class CryptoConfigEntry;
+ class DirectoryServicesWidget;
+}
+
+/**
+ * "Directory Services" configuration page for kleopatra's configuration dialog
+ * The user can configure LDAP servers in this page, to be used for listing/fetching
+ * remote certificates in kleopatra.
+ */
+class KDE_EXPORT DirectoryServicesConfigurationPage : public KCModule {
+ Q_OBJECT
+public:
+ DirectoryServicesConfigurationPage( QWidget * parent=0, const char * name=0 );
+
+ virtual void load();
+ virtual void save();
+ virtual void defaults();
+
+private slots:
+ void slotChanged();
+
+private:
+ Kleo::CryptoConfigEntry* configEntry( const char* componentName,
+ const char* groupName,
+ const char* entryName,
+ Kleo::CryptoConfigEntry::ArgType argType,
+ bool isList );
+
+ Kleo::DirectoryServicesWidget* mWidget;
+ QTimeEdit* mTimeout;
+ KIntNumInput* mMaxItems;
+ QCheckBox* mAddNewServersCB;
+
+ Kleo::CryptoConfigEntry* mTimeoutConfigEntry;
+ Kleo::CryptoConfigEntry* mMaxItemsConfigEntry;
+ Kleo::CryptoConfigEntry* mAddNewServersConfigEntry;
+
+ Kleo::CryptoConfig* mConfig;
+};
+
+#endif
diff --git a/certmanager/conf/dnorderconfigpage.cpp b/certmanager/conf/dnorderconfigpage.cpp
new file mode 100644
index 000000000..44b86b5b8
--- /dev/null
+++ b/certmanager/conf/dnorderconfigpage.cpp
@@ -0,0 +1,77 @@
+/*
+ dnorderconfigpage.cpp
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "dnorderconfigpage.h"
+
+#include <ui/dnattributeorderconfigwidget.h>
+#include <kleo/dn.h>
+
+#include <kdepimmacros.h>
+
+#include <qlayout.h>
+
+DNOrderConfigPage::DNOrderConfigPage( QWidget * parent, const char * name )
+ : KCModule( parent, name )
+{
+ QVBoxLayout * vlay = new QVBoxLayout( this );
+ mWidget = Kleo::DNAttributeMapper::instance()->configWidget( this, "mWidget" );
+ vlay->addWidget( mWidget );
+
+ connect( mWidget, SIGNAL(changed()), SLOT(slotChanged()) );
+
+#ifndef HAVE_UNBROKEN_KCMULTIDIALOG
+ load();
+#endif
+}
+
+
+void DNOrderConfigPage::load() {
+ mWidget->load();
+}
+
+void DNOrderConfigPage::save() {
+ mWidget->save();
+}
+
+void DNOrderConfigPage::defaults() {
+ mWidget->defaults();
+}
+
+// kdelibs-3.2 didn't have the changed signal in KCModule...
+void DNOrderConfigPage::slotChanged() {
+ emit changed(true);
+}
+
+extern "C" KDE_EXPORT KCModule * create_kleopatra_config_dnorder( QWidget * parent, const char * ) {
+ return new DNOrderConfigPage( parent, "kleopatra_config_dnorder" );
+}
+
+#include "dnorderconfigpage.moc"
diff --git a/certmanager/conf/dnorderconfigpage.h b/certmanager/conf/dnorderconfigpage.h
new file mode 100644
index 000000000..c874c7527
--- /dev/null
+++ b/certmanager/conf/dnorderconfigpage.h
@@ -0,0 +1,63 @@
+/*
+ dnorderconfigpage.h
+
+ This file is part of kleopatra, the KDE key manager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
+#define __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
+
+#include <kcmodule.h>
+
+namespace Kleo {
+ class DNAttributeOrderConfigWidget;
+}
+
+/**
+ * "DN Order" configuration page for kleopatra's configuration dialog
+ */
+class DNOrderConfigPage : public KCModule {
+ Q_OBJECT
+public:
+ DNOrderConfigPage( QWidget * parent=0, const char * name=0 );
+
+ /*! reimplementation */
+ void load();
+ /*! reimplementation */
+ void save();
+ /*! reimplementation */
+ void defaults();
+
+private slots:
+ void slotChanged();
+
+private:
+ Kleo::DNAttributeOrderConfigWidget * mWidget;
+};
+
+#endif // __KLEOPATRA_CONF_DNORDERCONFIGPAGE_H__
diff --git a/certmanager/conf/kleopatra_config_appear.desktop b/certmanager/conf/kleopatra_config_appear.desktop
new file mode 100644
index 000000000..8cbeaecf8
--- /dev/null
+++ b/certmanager/conf/kleopatra_config_appear.desktop
@@ -0,0 +1,181 @@
+[Desktop Entry]
+Icon=looknfeel
+Type=Service
+ServiceTypes=KCModule
+DocPath=kleopatra/configuration-appearance.html
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kleopatra
+X-KDE-FactoryName=kleopatra_config_appear
+X-KDE-HasReadOnlyMode=false
+X-KDE-ParentApp=kleopatra
+X-KDE-ParentComponents=kleopatra
+X-KDE-CfgDlgHierarchy=Kleopatra
+
+Name=Appearance
+Name[ar]=المظهر
+Name[be]=Знешні выглÑд
+Name[bg]=Външен вид
+Name[br]=Neuziadur
+Name[bs]=Izgled
+Name[ca]=Aparença
+Name[cs]=Vzhled
+Name[cy]=Golwg
+Name[da]=Udseende
+Name[de]=Erscheinungsbild
+Name[el]=Εμφάνιση
+Name[eo]=Prezentado
+Name[es]=Apariencia
+Name[et]=Välimus
+Name[eu]=Itxura
+Name[fa]=ظاهر
+Name[fi]=Ulkoasu
+Name[fr]=Apparence
+Name[fy]=Uterlik
+Name[ga]=Cuma
+Name[gl]=Apariencia
+Name[he]=מר××”
+Name[hr]=Izgled
+Name[hu]=Megjelenés
+Name[is]=Útlit
+Name[it]=Aspetto
+Name[ja]=外観
+Name[ka]=იერსáƒáƒ®áƒ”
+Name[kk]=Сыртқы көрініÑÑ–
+Name[km]=រូបរាង
+Name[ko]=모양
+Name[lt]=IÅ¡vaizda
+Name[mk]=Изглед
+Name[ms]=Rupa
+Name[nb]=Utseende
+Name[nds]=Utsehn
+Name[ne]=मोहडा
+Name[nl]=Uiterlijk
+Name[nn]=Utsjånad
+Name[pl]=WyglÄ…d
+Name[pt]=Aparência
+Name[pt_BR]=Aparência
+Name[ru]=Внешний вид
+Name[rw]=Imigaragarire
+Name[se]=Fárda
+Name[sk]=Vzhľad
+Name[sl]=Videz
+Name[sr]=Изглед
+Name[sr@Latn]=Izgled
+Name[sv]=Uppträdande
+Name[ta]=தோறà¯à®±à®®à¯
+Name[tg]=Ðамуди зоҳирӣ
+Name[tr]=Görünüm
+Name[uk]=ВиглÑд
+Name[uz]=Koʻrinishi
+Name[uz@cyrillic]=Кўриниши
+Name[zh_CN]=外观
+Comment=Colors & Fonts Configuration
+Comment[af]=Kleur en skrif tipe opstelling
+Comment[ar]=إعدادات الألوان Ùˆ المحارÙ
+Comment[be]=ÐаÑтаўленні колераў Ñ– шрыфтоў
+Comment[bg]=ÐаÑтройки на цветовете и шрифтовете
+Comment[bs]=Podešavanje boja i fontova
+Comment[ca]=Configuració de colors i lletres
+Comment[cs]=Nastavení barev a písem
+Comment[da]=Indstilling af farver & skrifttype
+Comment[de]=Farb- & Schrifteneinrichtung
+Comment[el]=ΡÏθμιση χÏωμάτων & γÏαμματοσειÏών
+Comment[en_GB]=Colours & Fonts Configuration
+Comment[eo]=Kolora kaj Tipara Agordo
+Comment[es]=Configuración de colores y tipografías
+Comment[et]=Värvide ja fontide seadistamine
+Comment[eu]=Kolore eta letra-tipoen konfigurazioa
+Comment[fa]=پیکربندی رنگها و قلمها
+Comment[fi]=Värien ja kirjasinten asetukset
+Comment[fr]=Configuration des polices et des couleurs
+Comment[fy]=Kleur- en lettertype-ynstellings
+Comment[ga]=Cumraíocht na nDathanna/gClófhoirne
+Comment[gl]=Configuración de Cores e Fontes
+Comment[he]=תצורת ×¦×‘×¢×™× ×•×’×•×¤× ×™×
+Comment[hu]=A színek és betűtípusok beállítása
+Comment[is]=Stilling lita & leturgerða
+Comment[it]=Configurazione tipi di carattere e colori
+Comment[ja]=色ã¨ãƒ•ã‚©ãƒ³ãƒˆã®è¨­å®š
+Comment[ka]=ფერთრდრშრიფტთრკáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ
+Comment[kk]=Ð¢Ò¯Ñ & Қаріп параметрлері
+Comment[km]=ការ​កំណážáŸ‹â€‹ážšáž…នាសម្ពáŸáž“្ធ​ពណ៌ & ពុម្ពអក្សរ
+Comment[ko]=색과 글꼴 설정
+Comment[lt]=Spalvų ir šriftų konfigūravimas
+Comment[mk]=Конфигурација на бои и фонтови
+Comment[ms]=Warna & Konfigurasi fon
+Comment[nb]=Oppsett av farger og skrifttyper
+Comment[nds]=Klören un Schriftoorden instellen
+Comment[ne]=रङ र फनà¥à¤Ÿ कनà¥à¤«à¤¿à¤—रेसन
+Comment[nl]=Kleur- en lettertype-instellingen
+Comment[nn]=Oppsett av fargar og skrifter
+Comment[pl]=Konfiguracja czcionek i kolorów
+Comment[pt]=Configuração das Cores e Tipos de Letra
+Comment[pt_BR]=Configuração de Cores & Fontes
+Comment[ru]=ÐаÑтройка цветов и шрифтов
+Comment[se]=Heivet ivnniid ja fonttaid
+Comment[sk]=Nastavenie písiem a farieb
+Comment[sl]=Nastavitev pisav in barv
+Comment[sr]=Подешавање боја и фонтова
+Comment[sr@Latn]=Podešavanje boja i fontova
+Comment[sv]=Inställning av färger och teckensnitt
+Comment[ta]=வணà¯à®£à®™à¯à®•à®³à¯& எழà¯à®¤à¯à®¤à¯à®°à¯à®•à¯à®•à®³à¯ கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯
+Comment[tg]=Танзимоти ранг ва ҳуруф
+Comment[tr]=Renkler ve Yazı Tipleri Yapılandırması
+Comment[uk]=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² Ñ– шрифтів
+Comment[zh_CN]=颜色和字体é…ç½®
+Comment[zh_TW]=設定é¡è‰²èˆ‡å­—åž‹
+Keywords=color,font, configuration
+Keywords[af]=kleur,skrif tipe,opstelling,color,font
+Keywords[ar]=لون,حرÙ, إعدادات,محرÙ,ألوان
+Keywords[be]=колер, шрыфт, канфігурацыÑ, color, font, configuration
+Keywords[bg]=цвÑÑ‚, шрифт, наÑтройване, наÑтройки color, font, configuration
+Keywords[br]=liv,nodrezh, kefluniadur
+Keywords[bs]=color,font, configuration,boja,boje,font,podešavanje
+Keywords[ca]=color,lletres, configuració
+Keywords[cs]=barva,písmo,nastavení
+Keywords[da]=farve,skrifttype,indstilling
+Keywords[de]=Farben,Schriftarten,Konfiguration,Einrichtung,Einstellungen
+Keywords[el]=χÏώμα,γÏαμματοσειÏά, ÏÏθμιση
+Keywords[en_GB]=colour,font, configuration
+Keywords[eo]=koloro,tiparo, agordo
+Keywords[es]=color, tipografía, configuración
+Keywords[et]=värv, font, seadistamine
+Keywords[eu]=kolore,letra-tipo, konfigurazioa
+Keywords[fa]=رنگ، قلم، پیکربندی
+Keywords[fi]=värit,kirjasimet,asetukset
+Keywords[fr]=couleur,police,configuration,paramètres,réglages,couleurs,polices
+Keywords[fy]=kleur,kleuren,font,lettertype,konfiguraasje,ynstellings,setup,opset
+Keywords[ga]=dath,cló,cumraíocht
+Keywords[gl]=cor,fonte, configuración
+Keywords[he]=color,font, configuration,צבע,צבעי×, גופני×, גופן, תצורה, הגדרה
+Keywords[hu]=szín,betűtípus,beállítások
+Keywords[is]=litir,letur, stillingar
+Keywords[it]=colori, font, caratteri, configurazione
+Keywords[ja]=色,フォント,設定
+Keywords[ka]=ფერები,შრიფტები, კáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ
+Keywords[km]=ពណ៌,ពុម្ពអក្សរ,ការ​កំណážáŸ‹â€‹ážšáž…នាសម្ពáŸáž“្ធ
+Keywords[ko]=색,글꼴,설정
+Keywords[lt]=color,font, configuration, spalvų, šriftų konfigūravimas
+Keywords[mk]=color,font,configuration,боја,фонт,конфигурација
+Keywords[ms]=warna,fon, konfigurasi
+Keywords[nb]=farge,skrifttype,oppsett
+Keywords[nds]=Klöör,Schriftoort,instellen
+Keywords[ne]=रङ, फनà¥à¤Ÿ, कनà¥à¤«à¤¿à¤—रेसन
+Keywords[nl]=kleur,kleuren,font,lettertype,configuratie,instellingen,setup
+Keywords[nn]=farge,skrift,oppsett
+Keywords[pl]=kolor,czcionki,kolory,konfiguracja
+Keywords[pt]=cor,tipo de letra, configuração
+Keywords[pt_BR]=cor,fonte,configurar,configurações
+Keywords[ru]=цвета,шрифты,наÑтройка
+Keywords[se]=ivdni,fonta,heivehus
+Keywords[sk]=farba,písmo,nastavenie
+Keywords[sl]=barva,barve,pisava,pisave,nastavi,nastavitve
+Keywords[sr]=боја,фонт,подешавања
+Keywords[sr@Latn]=boja,font,podešavanja
+Keywords[sv]=färger,teckensnitt, inställningar
+Keywords[ta]=Comment=வணà¯à®£à®®à¯,எழà¯à®¤à¯à®¤à¯à®°à¯, கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯
+Keywords[tg]=рангҳо,ҳуруфҳо,танзимот
+Keywords[tr]=renk,yazı tipi, yapılandırma
+Keywords[uk]=колір, шрифт, налаштуваннÑ
+Keywords[zh_CN]=color,font,configuration,颜色,字体,é…ç½®
diff --git a/certmanager/conf/kleopatra_config_dirserv.desktop b/certmanager/conf/kleopatra_config_dirserv.desktop
new file mode 100644
index 000000000..7a50a7c41
--- /dev/null
+++ b/certmanager/conf/kleopatra_config_dirserv.desktop
@@ -0,0 +1,169 @@
+[Desktop Entry]
+Icon=network
+Type=Service
+ServiceTypes=KCModule
+DocPath=kleopatra/configuration.html#configuration-directory-services
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kleopatra
+X-KDE-FactoryName=kleopatra_config_dirserv
+X-KDE-HasReadOnlyMode=false
+X-KDE-ParentApp=kleopatra
+X-KDE-ParentComponents=kleopatra
+X-KDE-CfgDlgHierarchy=Kleopatra
+
+Name=Directory Services
+Name[ar]=خدمات الدليل
+Name[bg]=Директорийни уÑлуги
+Name[bs]=ImeniÄki servisi
+Name[ca]=Serveis de directori
+Name[cs]=Adresářové služby
+Name[da]=Opslagstjeneste
+Name[de]=Verzeichnisdienste
+Name[el]=ΥπηÏεσίες καταλόγου
+Name[eo]=Dosierujaj Servoj
+Name[es]=Servicios de directorio
+Name[et]=Kataloogiteenused
+Name[eu]=Direktorio zerbitzuak
+Name[fa]=خدمات Ùهرست راهنما
+Name[fi]=Hakemistopalvelut
+Name[fr]=Services d'annuaire
+Name[fy]=Maptsjinsten
+Name[ga]=Seirbhísí Eolaire
+Name[gl]=Servicios de Directorio
+Name[he]=שירותי ספרייה
+Name[hu]=Címtárszolgáltatások
+Name[is]=Nafnaþjónustur
+Name[it]=Servizi Directory
+Name[ja]=ディレクトリサービス
+Name[ka]=სáƒáƒªáƒœáƒáƒ‘áƒáƒ áƒ მáƒáƒ›áƒ¡áƒáƒ®áƒ£áƒ áƒ”ბáƒ
+Name[kk]=Каталог қызметтері
+Name[km]=សáŸážœáž¶â€‹ážáž
+Name[ko]=디렉터리 서비스
+Name[lt]=Aplankų tarnybos
+Name[mk]=Именички ÑервиÑи
+Name[ms]=Servis Direktori
+Name[nb]=Katalogtjenere
+Name[nds]=Vertekendeensten
+Name[ne]=डाइरेकà¥à¤Ÿà¤°à¥€ कारà¥à¤¯
+Name[nl]=Mapdiensten
+Name[nn]=Katalogtenester
+Name[pa]=ਡਾਇਰੈਕਟਰੀ ਸੇਵਾਵਾਂ
+Name[pl]=Usługi katalogowe
+Name[pt]=Serviços de Directório
+Name[pt_BR]=Serviços de Diretório
+Name[ru]=Службы каталогов
+Name[se]=Ohcobálvalusat
+Name[sk]=Adresárové služby
+Name[sl]=Imeniške storitve
+Name[sr]=Ð¡ÐµÑ€Ð²Ð¸Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ˜ÑƒÐ¼Ð°
+Name[sr@Latn]=Servis direktorijuma
+Name[sv]=Katalogtjänster
+Name[ta]= அடைவ௠சேவைகளà¯
+Name[tg]=Кӯмакҳои каталог
+Name[tr]=Dizin Servisleri
+Name[uk]=Служби каталогів
+Name[zh_CN]=目录æœåŠ¡
+Name[zh_TW]=目錄æœå‹™
+Comment=Configuration of LDAP directory services
+Comment[af]=Opstelling van LDAP gids diens
+Comment[bg]=ÐаÑтройки на директорийните уÑлуги LDAP
+Comment[bs]=Podešavanje LDAP usluge imenika
+Comment[ca]=Configuració dels serveis de directori LDAP
+Comment[cs]=Nastavení adresářových služeb LDAP
+Comment[da]=Indstilling af LDAP opslagstjeneste
+Comment[de]=Einrichtung von LDAP-Verzeichnisdiensten
+Comment[el]=Ρυθμίσεις των υπηÏεσιών καταλόγου LDAP
+Comment[eo]=Agordo de LDAP dosierujaj servoj
+Comment[es]=Configuración de los servicios de directorio LDAP
+Comment[et]=LDAP kataloogiteenuste seadistused
+Comment[eu]=LDAP direktorio zerbitzuen konfigurazioa
+Comment[fa]=پیکربندی خدمات Ùهرست راهنمای LDAP
+Comment[fi]=Hakemistopalveluiden asetukset
+Comment[fr]=Configuration des services d'annuaire LDAP
+Comment[fy]=Konfiguraasje foar LDAP-tsjinsten
+Comment[gl]=Configuración dos servicios de directorio LDAP
+Comment[he]=תצורה של שירותי ספרייה עבור LDAP
+Comment[hu]=Az LDAP címtárszolgáltatások beállításai
+Comment[is]=Stillingar LDAP uppflettingaþjónustunnar
+Comment[it]=Configurazione servizi LDAP
+Comment[ja]=LDAP ディレクトリサービスã®è¨­å®š
+Comment[ka]=LDAP სáƒáƒªáƒœáƒáƒ‘áƒáƒ áƒ მáƒáƒ›áƒ¡áƒáƒ®áƒ£áƒ áƒ”ბის კáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ
+Comment[kk]=LDAP каталог қызметтер параметрлері
+Comment[km]=ការ​កំណážáŸ‹â€‹ážšáž…នាសម្ពáŸáž“្ធ​របស់​សáŸážœáž¶â€‹ážáž LDAP
+Comment[ko]=LDAP 디렉터리 서비스 설정
+Comment[lt]=LDAP aplankų tarnybų konfigūravimas
+Comment[mk]=Конфигурација на LDAP-именички ÑервиÑи
+Comment[ms]=Konfigurasi LDAP servis direktori
+Comment[nb]=Oppsett av LDAP katalogtjenester
+Comment[nds]=LDAP-Vertekendeensten instellen
+Comment[ne]=LDAP डाइरेकà¥à¤Ÿà¤°à¥€ कारà¥à¤¯à¤•à¥‹ कनà¥à¤«à¤¿à¤—रेसन
+Comment[nl]=Configuratie voor LDAP-diensten
+Comment[nn]=Oppsett av LDAP-katalogtenester
+Comment[pl]=Konfiguracja usług katalogowych LDAP
+Comment[pt]=Configuração dos serviços de directório LDAP
+Comment[pt_BR]=Configuração dos serviços de diretório LDAP
+Comment[ru]=ÐаÑтройка Ñлужб каталогов LDAP
+Comment[se]=Heivet LDAP-ohcobálvalusaid
+Comment[sk]=Nastavenie adresárových služieb LDAP
+Comment[sl]=Nastavitve imeniških storitev LDAP
+Comment[sr]= Подешавања LDAP ÑервиÑа директоријума
+Comment[sr@Latn]= Podešavanja LDAP servisa direktorijuma
+Comment[sv]=Inställning av LDAP-katalogtjänster
+Comment[ta]= LDAP அடைவ௠சேவைகளின௠கடà¯à®Ÿà®®à¯ˆà®ªà¯à®ªà¯
+Comment[tg]=Танзимоти кӯмакҳои каталоги LDAP
+Comment[tr]=LDAP dizin servislerinin yapılandırması
+Comment[uk]=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñлужб каталогів LDAP
+Comment[zh_CN]=LDAP 目录æœåŠ¡é…ç½®
+Comment[zh_TW]=設定 LDAP 目錄æœå‹™
+Keywords=ldap,directory,services
+Keywords[af]=ldap,directory,services,gids
+Keywords[be]=каталёг,ÑÑрвіÑÑ‹,ldap,directory,services
+Keywords[bg]=директорийни, уÑлуги, ldap, directory, services
+Keywords[br]=ldap,renkell,servijeroù
+Keywords[bs]=ldap,directory,services,imenik,servis,usluga,imeniÄki,imeniÄke,usluge
+Keywords[ca]=ldap,directori,serveis
+Keywords[cs]=LDAP,adresář,služby
+Keywords[da]=ldap,opslag,tjenester
+Keywords[de]=LDAP,Verzeichnis,Dienste,Verzeichnisdienst
+Keywords[el]=ldap,κατάλογος,υπηÏεσίες
+Keywords[eo]=ldap,dosierujo,servoj
+Keywords[es]=ldap,directorio,servicios
+Keywords[et]=ldap,kataloog,teenused
+Keywords[eu]=Idap, direktorio, zerbitzuak
+Keywords[fa]=ldapØŒ Ùهرست راهنما، خدمات
+Keywords[fi]=ldap,hakemisto,palvelut
+Keywords[fr]=ldap,annuaire,annuaires,service,services
+Keywords[fy]=ldap,directory,services,triemtafel,tsjinsten
+Keywords[ga]=ldap,eolaire,seirbhísí
+Keywords[gl]=ldap,directorio,servicios
+Keywords[he]=ldap,directory,services,ספרייה,שירותי×
+Keywords[hu]=ldap,címtár,szolgáltatások
+Keywords[is]=ldap,directory,services,nafnaþjónusta
+Keywords[it]=ldap, servizi, directory
+Keywords[ja]=ldap,ディレクトリ,サービス
+Keywords[ka]=ldap,ცნáƒáƒ‘áƒáƒ áƒ˜,მáƒáƒ›áƒ¡áƒáƒ®áƒ£áƒ áƒ”ბáƒ
+Keywords[km]=ldap,ážáž,សáŸážœáž¶
+Keywords[ko]=ldap,디렉터리,서비스
+Keywords[lt]=ldap,directory,services,aplankai,tarnybos
+Keywords[mk]=ldap,directory,services,именик,ÑервиÑи
+Keywords[ms]=ldap,direktori,servis
+Keywords[nb]=ldap,mappe,tjenester
+Keywords[nds]=LDAP,Verteken,Deensten
+Keywords[ne]=ldap,डाइरेकà¥à¤Ÿà¤°à¥€,कारà¥à¤¯
+Keywords[nn]=ldap,katalog,tenester
+Keywords[pl]=katalog,usługi katalogowe,usługi,LDAP
+Keywords[pt]=ldap,directório,serviços
+Keywords[pt_BR]=ldap,diretório,serviços
+Keywords[ru]=LDAP,Ñлужбы каталогов
+Keywords[se]=ldap,ohcu,bálvalusat
+Keywords[sk]=ldap,adresár,služby
+Keywords[sl]=ldap,imenik,storitve
+Keywords[sr]=ldap,директоријум,ÑервиÑи
+Keywords[sr@Latn]=ldap,direktorijum,servisi
+Keywords[sv]=ldap,katalog,tjänster
+Keywords[ta]=ldap, அடைவà¯, சேவைகளà¯
+Keywords[tg]=ldap,кӯмакҳои каталог
+Keywords[tr]=ldap,dizin,servisler
+Keywords[uk]=ldap,Ñлужби,каталогів
+Keywords[zh_CN]=ldap,directory,services,目录,æœåŠ¡
diff --git a/certmanager/conf/kleopatra_config_dnorder.desktop b/certmanager/conf/kleopatra_config_dnorder.desktop
new file mode 100644
index 000000000..dc46c3314
--- /dev/null
+++ b/certmanager/conf/kleopatra_config_dnorder.desktop
@@ -0,0 +1,164 @@
+[Desktop Entry]
+Icon=looknfeel
+Type=Service
+ServiceTypes=KCModule
+DocPath=kleopatra/configuration-dn-order.html
+
+X-KDE-ModuleType=Library
+X-KDE-Library=kleopatra
+X-KDE-FactoryName=kleopatra_config_dnorder
+X-KDE-HasReadOnlyMode=false
+X-KDE-ParentApp=kleopatra
+X-KDE-ParentComponents=kleopatra
+X-KDE-CfgDlgHierarchy=Kleopatra
+
+Name=DN-Attribute Order
+Name[bg]=Подредба
+Name[bs]=Redoslijed DN atributa
+Name[ca]=Ordre d'atributs DN
+Name[cs]=Pořadí DN atributů
+Name[da]=DN-Attributrækkefølge
+Name[de]=DN-Attribut-Ordnung
+Name[el]=ΣειÏά ιδιότητας DN
+Name[eo]=DN-Atributa Sinsekvo
+Name[es]=Orden de atributos DN
+Name[et]=DN-atribuutide järjekord
+Name[eu]=DN-atributu ordena
+Name[fa]=ترتیب خصیصۀ DN
+Name[fi]=DN-attribuuttien järjestys
+Name[fr]=Ordre des attributs DN
+Name[fy]=DN-Attribuutoarder
+Name[gl]=Orde de DN-Attribute
+Name[he]=סדר של מ×פייני DN
+Name[hu]=DN-attribútumsorrend
+Name[is]=DN eiginleikaröðun
+Name[it]=Attributi DN, ordine
+Name[ja]=DN 属性順ä½
+Name[ka]=DN áƒáƒ¢áƒ áƒ˜áƒ‘უტთრრიგი
+Name[kk]=DN-атрибуттер реті
+Name[km]=លំដាប់​គុណលក្ážážŽáŸˆ DN
+Name[ko]=DN 분배 순서
+Name[lt]=DN-Savybių tvarka
+Name[mk]=РедоÑлед на DN-атрибути
+Name[ms]=Tertib atribut DN
+Name[nb]=DN-Attributtrekkefølge
+Name[nds]=DN-Egenschappenreeg
+Name[ne]=डीà¤à¤¨ विशेषता आदेश
+Name[nl]=DN-Attribuutvolgorde
+Name[nn]=DN-attributtrekkjefølgje
+Name[pl]=Porządek atrybutów DN
+Name[pt]=Ordem de Atributos DN
+Name[pt_BR]=Ordem do Atributo DN
+Name[ru]=ПорÑдок атрибутов DN
+Name[se]=DN-attribuhttaortnet
+Name[sk]=Poradie atribútov DN
+Name[sl]=Vrstni red atributov DN
+Name[sr]=DN-Ðтрибут ред
+Name[sr@Latn]=DN-Atribut red
+Name[sv]=DN-egenskapsordning
+Name[ta]=DN-பணà¯à®ªà¯à®•à¯à®•à¯‚ற௠வரிசை
+Name[tg]=Тартиби мушаххаÑиÑти DN
+Name[tr]=DN-Öznitelik Sırası
+Name[uk]=ПорÑдок атрибутів DN
+Name[zh_CN]=DN 属性顺åº
+Name[zh_TW]=DN-屬性順åº
+Comment=Configure the order in which DN attributes are shown
+Comment[af]=Stel die volgorde op waarin DN eienskappe vertoon word
+Comment[bg]=ÐаÑтройки на подредбата на атрибутите на индекÑа (DN)
+Comment[bs]=Podesite redoslijed kojim će biti prikazani DN atributi
+Comment[ca]=Configura l'ordre en què es mostren els atributs DN
+Comment[cs]=Nastavení pořadí zobrazení DN atributů
+Comment[da]=Indstil rækkefølgen i hvilken DN-attributter vises
+Comment[de]=Einrichtung für die Anzeigereihenfolge der DN-Attribute
+Comment[el]=ΡÏθμιση της σειÏάς εμφάνισης των ιδιοτήτων DN
+Comment[eo]=Agordi la sinsekvon en kiu DN-atributoj aperas
+Comment[es]=Configura el orden en el que se muestran los atributos DN
+Comment[et]=DN-atribuutide näitamise järjekorra seadistamine
+Comment[eu]=Konfiguratu DN atributuak zein ordenetan erakutsiko diren
+Comment[fa]=پیکربندی ترتیبی که خصیصه‌های DN طبق آن نمایش داده می‌شوند
+Comment[fi]=Määrittele missä järjestyksessä DN-attribuutit näytetään
+Comment[fr]=Configurer l'ordre dans lequel les attributs DN sont affichés
+Comment[fy]=De folchoarder fan de DN-atributen ynstelle
+Comment[gl]=Configurar a orde en que se amosan os atributos DN
+Comment[he]=הגדרה של הסדר ×©×‘×”× ×ž×פייני DN מוצגי×
+Comment[hu]=A DN-attribútumok megjelenítési sorrendjének beállítása
+Comment[is]=Stilla röð DN eiginleikanna
+Comment[it]=Configura l'ordine in cui sono mostrati gli attributi DN
+Comment[ja]=DN 属性を表示ã™ã‚‹é †ä½ã‚’設定
+Comment[ka]=DN áƒáƒ¢áƒ áƒ˜áƒ‘უტთრჩვენების რიგის კáƒáƒœáƒ¤áƒ˜áƒ’ურáƒáƒªáƒ˜áƒ
+Comment[kk]=DN атрибуттерді көрÑету ретін баптау
+Comment[km]=កំណážáŸ‹â€‹ážšáž…នាសម្ពáŸáž“្ធ​លំដាប់ ដែល​ážáŸ’រូវ​បង្ហាញ​គុណលក្ážážŽáŸˆ DN
+Comment[lt]=Konfigūruoti DN savybių rodymo tvarką
+Comment[mk]=Конфигурирајте го редоÑледот по кој Ñе покажуваат DN-атрибутите
+Comment[ms]=Konfigur tertib yang atribut DN dipaparkan
+Comment[nb]=Still inn rekkefølgen DN-attributtene er sortert i
+Comment[nds]=De Reeg bi't Wiesen vun DN-Egenschappen fastleggen
+Comment[ne]=डीà¤à¤¨ विशेषता देखिने आदेश कनà¥à¤«à¤¿à¤—र गरà¥à¤¨à¥à¤¹à¥‹à¤¸à¥
+Comment[nl]=Stel de volgorde in van de DN-attributen
+Comment[nn]=Vel kva rekkjefølgje DN-attributtane er sorterte i
+Comment[pl]=Konfiguracja kolejności wyświetlania atrybutów DN
+Comment[pt]=Configuração da ordem em que os atributos DN são mostrados
+Comment[pt_BR]=Configura a ordem na qual os atributos DN são mostrados
+Comment[ru]=ÐаÑтройка порÑдка показываемых атрибутов DN
+Comment[se]=Vállje makkár ortnegis DN-attribuhttat sorterejuvvojit
+Comment[sk]=Nastavenie poradia, v ktorom sú zobrazené atribúty DN
+Comment[sl]=Nastavite vrstni red, v katerem so prikazani atributi DN
+Comment[sr]=Подешава ред којим Ñу приказани DN атрибути
+Comment[sr@Latn]=Podešava red kojim su prikazani DN atributi
+Comment[sv]=Anpassa ordningen som DN-egenskaper visas
+Comment[ta]= DN விவரஙà¯à®•à®³à¯ எநà¯à®¤ வரிசையில௠உளà¯à®³à®¤à¯‹ அபà¯à®ªà®Ÿà®¿à®¯à¯‡ அமை
+Comment[tg]=Танзимоти мушаххаÑиÑтҳои намоишшавандаи тартибии DN
+Comment[tr]=DN özniteliklerinin hangi sıralama ile gösterileceğini yapılandır
+Comment[uk]=ÐÐ°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ€Ñдку показу атрибутів DN
+Comment[zh_CN]=é…ç½® DN 属性显示的顺åº
+Comment[zh_TW]=設定 DN 屬性顯示順åº
+Keywords=DN,order,RDN,attribute
+Keywords[af]=DN,order,RDN,attribute,volgorde,eienskap
+Keywords[be]=парадак,атрыбут,DN,order,RDN,attribute
+Keywords[bg]=индекÑ, ред, подредба, атрибут DN, order, RDN, attribute
+Keywords[bs]=DN,order,RDN,attribute,redoslijed,atribut
+Keywords[ca]=DN,ordre,RDN,atribut
+Keywords[cs]=DN,pořadí,RDN,atribut
+Keywords[da]=DN,rækkefølge,RDN,attribut
+Keywords[de]=DN,Ordnung,RDN,Attribut
+Keywords[el]=DN,σειÏά,RDN,ιδιότητα
+Keywords[eo]=DN,sinsekvo,ordo,RDN,atributo
+Keywords[es]=DN,orden,RDN,atributo
+Keywords[et]=DN,järjekord,RDN,atribuut
+Keywords[eu]=DN, ordena, RDN, atributua
+Keywords[fa]=DN، ترتیب، RDN، خصیصه
+Keywords[fi]=DN,järjestys,RDN,attribuutti
+Keywords[fr]=DN,ordre,RDN,attribut
+Keywords[fy]=DN,Fochoarder,RDN,attribuut
+Keywords[ga]=DN,ord,RDN,aitreabúid
+Keywords[gl]=DN,orde,RDN,atributo
+Keywords[he]=DN,order,RDN,attribute, סדר, מ×פיין
+Keywords[hu]=DN,sorrend,RDN,attribútum
+Keywords[is]=DN,röð,order,RDN,attribute
+Keywords[it]=DN,ordine,RDN,attributi
+Keywords[ja]=DN,é †ä½,RDN,属性
+Keywords[ka]=DN,რიგი,RDN,áƒáƒ¢áƒ áƒ˜áƒ‘უტი
+Keywords[km]=DN,លំដាប់,RDN,គុណលក្ážážŽáŸˆ
+Keywords[lt]=DN,order,RDN,attribute,savybÄ—,tvarka
+Keywords[mk]=DN,order,RDN,attribute,редоÑлед,атрибут
+Keywords[ms]=DN,susunan,RDN,atribut
+Keywords[nb]=DN,orden,RDN,attributt
+Keywords[nds]=DN,Reeg,RDN,Egenschap
+Keywords[ne]=डीà¤à¤¨,कà¥à¤°à¤®,आरडीà¤à¤¨, विशेषता
+Keywords[nl]=DN,volgorde,RDN,attribuut
+Keywords[nn]=DN,rekkjefølgje,RDN,attributt
+Keywords[pl]=DN,kolejność,RDN,atrybuty
+Keywords[pt]=DN,ordem,RDN,atributo
+Keywords[pt_BR]=DN, ordem, RDN,atributo
+Keywords[ru]=DN,порÑдок,RDN,атрибут
+Keywords[se]=DN,ortnet,RDN,attribuhtta
+Keywords[sk]=DN,poradie,RDN,atribút
+Keywords[sl]=DN,vrstni red,RDN,atribut
+Keywords[sr]=DN,ред,RDN,атрибут
+Keywords[sr@Latn]=DN,red,RDN,atribut
+Keywords[sv]=DN,ordning,RDN,egenskap
+Keywords[ta]=DN,வரிசை,RDN,கà¯à®£à®®à¯
+Keywords[tg]=DN,тартибот,RDN,мушаххаÑот
+Keywords[tr]=DN,sıralama,RDN,öznitelik
+Keywords[uk]=DN,порÑдок,RDN,атрибут
+Keywords[zh_CN]=DN,order,RDN,attribute,顺åº,属性
diff --git a/certmanager/configure.in.in b/certmanager/configure.in.in
new file mode 100644
index 000000000..3b5b23cd4
--- /dev/null
+++ b/certmanager/configure.in.in
@@ -0,0 +1 @@
+AC_DEFINE_UNQUOTED(MAX_CMD_LENGTH, $lt_cv_sys_max_cmd_len, [Maximum length of command line arguments])
diff --git a/certmanager/crlview.cpp b/certmanager/crlview.cpp
new file mode 100644
index 000000000..6cf7ddeaa
--- /dev/null
+++ b/certmanager/crlview.cpp
@@ -0,0 +1,138 @@
+/*
+ crlview.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "crlview.h"
+
+#include <klocale.h>
+#include <kprocess.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+#include <kstdguiitem.h>
+#include <kglobalsettings.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qtextedit.h>
+#include <qfontmetrics.h>
+#include <qtimer.h>
+
+CRLView::CRLView( QWidget* parent, const char* name, bool modal )
+ : QDialog( parent, name, modal ), _process(0)
+{
+ QVBoxLayout* topLayout = new QVBoxLayout( this, 10, 4 );
+
+ topLayout->addWidget( new QLabel( i18n("CRL cache dump:"), this ) );
+
+ _textView = new QTextEdit( this );
+ _textView->setFont( KGlobalSettings::fixedFont() );
+ _textView->setTextFormat( QTextEdit::LogText );
+ topLayout->addWidget( _textView );
+
+ QHBoxLayout* hbLayout = new QHBoxLayout( topLayout );
+
+ _updateButton = new KPushButton( i18n("&Update"), this );
+ _closeButton = new KPushButton( KStdGuiItem::close(), this );
+
+ hbLayout->addWidget( _updateButton );
+ hbLayout->addStretch();
+ hbLayout->addWidget( _closeButton );
+
+ // connections:
+ connect( _updateButton, SIGNAL( clicked() ),
+ this, SLOT( slotUpdateView() ) );
+ connect( _closeButton, SIGNAL( clicked() ),
+ this, SLOT( close() ) );
+
+ resize( _textView->fontMetrics().width( 'M' ) * 80,
+ _textView->fontMetrics().lineSpacing() * 25 );
+
+ _timer = new QTimer( this );
+ connect( _timer, SIGNAL(timeout()), SLOT(slotAppendBuffer()) );
+}
+
+CRLView::~CRLView()
+{
+ delete _process; _process = 0;
+}
+
+void CRLView::closeEvent( QCloseEvent * e ) {
+ QDialog::closeEvent( e );
+ delete _process; _process = 0;
+}
+
+void CRLView::slotUpdateView()
+{
+ _updateButton->setEnabled( false );
+ _textView->clear();
+ _buffer = QString::null;
+ if( _process == 0 ) {
+ _process = new KProcess();
+ *_process << "gpgsm" << "--call-dirmngr" << "listcrls";
+ connect( _process, SIGNAL( receivedStdout( KProcess*, char*, int) ),
+ this, SLOT( slotReadStdout( KProcess*, char*, int ) ) );
+ connect( _process, SIGNAL( processExited( KProcess* ) ),
+ this, SLOT( slotProcessExited() ) );
+ }
+ if( _process->isRunning() ) _process->kill();
+ if( !_process->start( KProcess::NotifyOnExit, KProcess::Stdout ) ) {
+ KMessageBox::error( this, i18n( "Unable to start gpgsm process. Please check your installation." ), i18n( "Certificate Manager Error" ) );
+ slotProcessExited();
+ }
+ _timer->start( 1000 );
+}
+
+void CRLView::slotReadStdout( KProcess*, char* buf, int len)
+{
+ _buffer.append( QString::fromUtf8( buf, len ) );
+}
+
+void CRLView::slotAppendBuffer() {
+ _textView->append( _buffer );
+ _buffer = QString::null;
+}
+
+void CRLView::slotProcessExited()
+{
+ _timer->stop();
+ slotAppendBuffer();
+ _updateButton->setEnabled( true );
+
+ if( !_process->normalExit() ) {
+ KMessageBox::error( this, i18n( "The GpgSM process ended prematurely because of an unexpected error." ), i18n( "Certificate Manager Error" ) );
+ }
+}
+
+#include "crlview.moc"
diff --git a/certmanager/crlview.h b/certmanager/crlview.h
new file mode 100644
index 000000000..55828a90f
--- /dev/null
+++ b/certmanager/crlview.h
@@ -0,0 +1,69 @@
+/*
+ crlview.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CRLVIEW_H
+#define CRLVIEW_H
+
+#include <qdialog.h>
+#include <qstring.h>
+
+class QTextEdit;
+class QPushButton;
+class KProcess;
+class QTimer;
+
+class CRLView : public QDialog {
+ Q_OBJECT
+public:
+ CRLView( QWidget* parent = 0, const char* name = 0, bool modal = false );
+ ~CRLView();
+public slots:
+ void slotUpdateView();
+
+protected slots:
+ void slotReadStdout( KProcess*, char* buf, int len);
+ void slotProcessExited();
+ void slotAppendBuffer();
+
+protected:
+ void closeEvent( QCloseEvent * );
+
+private:
+ QTextEdit* _textView;
+ QPushButton* _updateButton;
+ QPushButton* _closeButton;
+ KProcess* _process;
+ QTimer* _timer;
+ QString _buffer;
+};
+
+#endif // CRLVIEW_H
diff --git a/certmanager/customactions.cpp b/certmanager/customactions.cpp
new file mode 100644
index 000000000..53e5dd2d8
--- /dev/null
+++ b/certmanager/customactions.cpp
@@ -0,0 +1,136 @@
+/*
+ customactions.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "customactions.h"
+
+#include <ktoolbar.h>
+#include <kapplication.h>
+
+#include <qlineedit.h>
+#include <qlabel.h>
+
+
+LabelAction::LabelAction( const QString & text, KActionCollection * parent,
+ const char* name )
+ : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name )
+{
+
+}
+
+int LabelAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar * bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ QLabel* label = new QLabel( text(), bar, "kde toolbar widget" );
+ bar->insertWidget( id_, label->width(), label, index );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+LineEditAction::LineEditAction( const QString & text, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name )
+ : KAction( text, QIconSet(), KShortcut(), 0, 0, parent, name ),
+ _le(0), _receiver(receiver), _member(member)
+{
+
+}
+
+int LineEditAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar *bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ // The toolbar trick doesn't seem to work for lineedits
+ //_le = new QLineEdit( bar, "kde toolbar widget" );
+ _le = new QLineEdit( bar );
+ bar->insertWidget( id_, _le->width(), _le, index );
+ bar->setStretchableWidget( _le );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ connect( _le, SIGNAL( returnPressed() ), _receiver, _member );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+void LineEditAction::clear() {
+ _le->clear();
+}
+
+void LineEditAction::focusAll() {
+ _le->selectAll();
+ _le->setFocus();
+}
+
+QString LineEditAction::text() const {
+ return _le->text();
+}
+
+void LineEditAction::setText( const QString & txt ) {
+ _le->setText(txt);
+}
+
+
+ComboAction::ComboAction( const QStringList & lst, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name,
+ int selectedID )
+ : KAction( QString::null, QIconSet(), KShortcut(), 0, 0, parent, name ),
+ _lst(lst), _receiver(receiver), _member(member), _selectedId( selectedID )
+{
+
+}
+
+int ComboAction::plug( QWidget * widget, int index ) {
+ if ( kapp && !kapp->authorizeKAction( name() ) )
+ return -1;
+ if ( widget->inherits( "KToolBar" ) ) {
+ KToolBar *bar = (KToolBar *)widget;
+ int id_ = getToolButtonID();
+ bar->insertCombo( _lst, id_, false, SIGNAL( highlighted(int) ), _receiver, _member );
+ bar->setCurrentComboItem( id_,_selectedId );
+ addContainer( bar, id_ );
+ connect( bar, SIGNAL( destroyed() ), this, SLOT( slotDestroyed() ) );
+ return containerCount() - 1;
+ }
+
+ return KAction::plug( widget, index );
+}
+
+#include "customactions.moc"
diff --git a/certmanager/customactions.h b/certmanager/customactions.h
new file mode 100644
index 000000000..44957487b
--- /dev/null
+++ b/certmanager/customactions.h
@@ -0,0 +1,86 @@
+/*
+ customactions.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __CUSTOMACTIONS_H__
+#define __CUSTOMACTIONS_H__
+
+#include <kaction.h>
+
+#include <qstringlist.h>
+
+class QLineEdit;
+
+class LabelAction : public KAction {
+ Q_OBJECT
+public:
+ LabelAction( const QString & text, KActionCollection * parent,
+ const char* name );
+
+ int plug( QWidget * widget, int index=-1 );
+};
+
+class LineEditAction : public KAction {
+ Q_OBJECT
+public:
+ LineEditAction( const QString & text, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name );
+
+ int plug( QWidget * widget, int index=-1 );
+ void clear();
+ void focusAll();
+ QString text() const;
+ void setText( const QString & txt );
+private:
+ QLineEdit* _le;
+ QObject * _receiver;
+ const char * _member;
+};
+
+class ComboAction : public KAction {
+ Q_OBJECT
+public:
+ ComboAction( const QStringList & lst, KActionCollection * parent,
+ QObject * receiver, const char * member, const char * name,
+ int selectedID );
+
+ int plug( QWidget * widget, int index=-1 );
+
+private:
+ QStringList _lst;
+ QObject * _receiver;
+ const char * _member;
+ int _selectedId;
+};
+
+
+
+#endif // __CUSTOMACTIONS_H__
diff --git a/certmanager/hierarchyanalyser.cpp b/certmanager/hierarchyanalyser.cpp
new file mode 100644
index 000000000..8e8c13803
--- /dev/null
+++ b/certmanager/hierarchyanalyser.cpp
@@ -0,0 +1,81 @@
+/*
+ hierarchyanalyser.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "hierarchyanalyser.h"
+
+#include <algorithm>
+#include <iterator>
+
+HierarchyAnalyser::HierarchyAnalyser( QObject * parent, const char * name )
+ : QObject( parent, name )
+{
+
+}
+
+HierarchyAnalyser::~HierarchyAnalyser() {
+
+}
+
+void HierarchyAnalyser::slotNextKey( const GpgME::Key & key ) {
+ if ( key.isNull() )
+ return;
+ if ( key.isRoot() || !key.chainID() || !*key.chainID() )
+ // root keys have themselves as issuer - we don't want them to
+ // have parents, though:
+ mSubjectsByIssuer[0].push_back( key );
+ else
+ mSubjectsByIssuer[key.chainID()].push_back( key );
+}
+
+const std::vector<GpgME::Key> & HierarchyAnalyser::subjectsForIssuer( const char * issuer_dn ) const {
+ static const std::vector<GpgME::Key> empty;
+ std::map< QCString, std::vector<GpgME::Key> >::const_iterator it =
+ mSubjectsByIssuer.find( issuer_dn );
+ return it == mSubjectsByIssuer.end() ? empty : it->second ;
+}
+
+std::vector<GpgME::Key> HierarchyAnalyser::subjectsForIssuerRecursive( const char * issuer_dn ) const {
+ std::vector<GpgME::Key> keys = subjectsForIssuer( issuer_dn );
+ for ( unsigned int i = 0 ; i < keys.size() ; ++i ) // can't use iterators here, since appending would invalidate them
+ if ( const char * fpr = keys[i].primaryFingerprint() ) {
+ const std::vector<GpgME::Key> & tmp = subjectsForIssuer( fpr );
+ std::copy( tmp.begin(), tmp.end(), std::back_inserter( keys ) );
+ }
+ return keys;
+}
+
+
+#include "hierarchyanalyser.moc"
diff --git a/certmanager/hierarchyanalyser.h b/certmanager/hierarchyanalyser.h
new file mode 100644
index 000000000..ccf07d4f3
--- /dev/null
+++ b/certmanager/hierarchyanalyser.h
@@ -0,0 +1,66 @@
+/* -*- mode: c++ -*-
+ hierarchyanalyser.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __HIERARCHYANALYSER_H__
+#define __HIERARCHYANALYSER_H__
+
+#include <gpgmepp/key.h>
+
+#include <qobject.h>
+#include <qcstring.h>
+
+#include <map>
+#include <vector>
+
+class HierarchyAnalyser : public QObject {
+ Q_OBJECT
+public:
+ HierarchyAnalyser( QObject * parent=0, const char * name=0 );
+ ~HierarchyAnalyser();
+
+ const std::vector<GpgME::Key> & rootItems() const {
+ return subjectsForIssuer( 0 );
+ }
+ const std::vector<GpgME::Key> & subjectsForIssuer( const char * issuer_fpr ) const;
+ std::vector<GpgME::Key> subjectsForIssuerRecursive( const char * issuer_fpr ) const;
+
+ void clear() { mSubjectsByIssuer.clear(); }
+
+public slots:
+ void slotNextKey( const GpgME::Key & key );
+
+private:
+ std::map< QCString, std::vector<GpgME::Key> > mSubjectsByIssuer;
+};
+
+
+#endif // __HIERARCHYANALYSER_H__
diff --git a/certmanager/kleopatra_import.desktop b/certmanager/kleopatra_import.desktop
new file mode 100644
index 000000000..382daf5ea
--- /dev/null
+++ b/certmanager/kleopatra_import.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Name=Kleopatra
+Name[is]=Kleópatra
+Name[mk]=Клеопатра
+Name[ne]=कà¥à¤²à¥‡à¤“पतà¥à¤°
+Name[ta]=கà¯à®³à®¿à®¯à¯‹à®ªà®Ÿà¯à®°à®¾
+Type=Application
+Exec=kleopatra --import-certificate %u
+#Icon=kleopatra
+NoDisplay=true
+MimeType=application/pkcs7-mime;application/x-x509-ca-cert;application/x-pkcs12;
+
+X-KDE-StartupNotify=true
diff --git a/certmanager/kleopatraui.rc b/certmanager/kleopatraui.rc
new file mode 100644
index 000000000..d07e08b85
--- /dev/null
+++ b/certmanager/kleopatraui.rc
@@ -0,0 +1,73 @@
+<!DOCTYPE kpartgui ><kpartgui name="kleopatra" version="19" >
+<MenuBar>
+ <Menu name="file">
+ <text>File</text>
+ <Action name="file_new_certificate"/>
+ <Separator/>
+ <Action name="file_export_certificate"/>
+ <Action name="file_export_secret_keys"/>
+ <Separator/>
+ <Action name="file_import_certificates"/>
+ <Action name="file_import_crls"/>
+ <Separator/>
+ <Action name="quit" />
+ </Menu>
+ <Menu name="view">
+ <text>View</text>
+ <Action name="view_stop_operations"/>
+ <Action name="view_certificate_details"/>
+ <Separator/>
+ <Action name="view_hierarchical"/>
+ <Separator/>
+ <Action name="view_expandall"/>
+ <Action name="view_collapseall"/>
+ </Menu>
+ <Menu name="certMenu">
+ <text>&amp;Certificates</text>
+ <Action name="certificates_validate"/>
+ <Action name="certificates_refresh_clr"/>
+<!--
+ <Action name="edit_revoke_certificate"/>
+ <Action name="edit_extend_certificate"/>
+-->
+ <Action name="edit_delete_certificate"/>
+ <Action name="download_certificate"/>
+ </Menu>
+ <Menu name="crlMenu">
+ <text>C&amp;RLs</text>
+ <Action name="crl_clear_crl_cache"/>
+ <Action name="crl_dump_crl_cache"/>
+ </Menu>
+ <Menu name="tools">
+ <text>&amp;Tools</text>
+ <Action name="tools_start_kwatchgnupg"/>
+ </Menu>
+ <Menu name="settings">
+ <Action name="configure_gpgme"/>
+ </Menu>
+</MenuBar>
+
+<ToolBar position="Top" iconText="IconOnly" noMerge="1" name="searchToolBar" >
+<text>Search Toolbar</text>
+ <Action name="label_action" />
+ <Action name="query_lineedit_action" />
+ <Action name="location_combo_action" />
+ <Action name="find" />
+</ToolBar>
+
+<Menu name="listview_popup">
+ <text>&amp;Certificates</text>
+ <Action name="certificates_validate"/>
+<!--
+ <Action name="edit_revoke_certificate"/>
+ <Action name="edit_extend_certificate"/>
+-->
+ <Action name="edit_delete_certificate"/>
+ <Action name="download_certificate"/>
+ <Separator/>
+ <Action name="file_export_certificate"/>
+ <Separator/>
+ <Action name="view_certificate_details"/>
+</Menu>
+
+</kpartgui>
diff --git a/certmanager/kwatchgnupg/Makefile.am b/certmanager/kwatchgnupg/Makefile.am
new file mode 100644
index 000000000..a727fa705
--- /dev/null
+++ b/certmanager/kwatchgnupg/Makefile.am
@@ -0,0 +1,30 @@
+KDE_CXXFLAGS = -DLIBKLEOPATRA_NO_COMPAT
+
+INCLUDES = -I$(top_srcdir)/certmanager/lib -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+bin_PROGRAMS = kwatchgnupg
+
+kwatchgnupg_SOURCES = \
+ kwatchgnupgmainwin.cpp \
+ kwatchgnupgconfig.cpp \
+ aboutdata.cpp \
+ tray.cpp \
+ main.cpp
+
+METASOURCES = AUTO
+
+kwatchgnupg_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+kwatchgnupg_LDADD = ../conf/libconf.la ../lib/libkleopatra.la $(LIB_KUTILS) $(LIB_KABC)
+
+rcdir = $(kde_datadir)/kwatchgnupg
+rc_DATA = kwatchgnupgui.rc
+
+
+pics_DATA = kwatchgnupg.png kwatchgnupg2.png
+
+picsdir = $(kde_datadir)/kwatchgnupg/pics
+
+EXTRA_DIST = $(pics_DATA)
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp *.h -o $(podir)/kwatchgnupg.pot
diff --git a/certmanager/kwatchgnupg/aboutdata.cpp b/certmanager/kwatchgnupg/aboutdata.cpp
new file mode 100644
index 000000000..4bde52190
--- /dev/null
+++ b/certmanager/kwatchgnupg/aboutdata.cpp
@@ -0,0 +1,73 @@
+/*
+ aboutdata.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2004 Klar�vdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "aboutdata.h"
+
+#include <klocale.h>
+
+static const char kwatchgnupg_version[] = "1.0";
+static const char description[] = I18N_NOOP("GnuPG log viewer");
+
+struct about_data {
+ const char * name;
+ const char * desc;
+ const char * email;
+ const char * web;
+};
+
+static const about_data authors[] = {
+ { "Steffen Hansen", I18N_NOOP("Original Author"), "hansen@kde.org", 0 },
+};
+
+#if 0
+// can't create zero size array - doesn't compile
+static const about_data credits[] = {
+ // PENDING(steffen) add stuff
+};
+#endif
+
+AboutData::AboutData()
+ : KAboutData( "kwatchgnupg", I18N_NOOP("KWatchGnuPG"),
+ kwatchgnupg_version, description, License_GPL,
+ "(c) 2004 Klar\xC3\xA4lvdalens Datakonsult AB\n" )
+{
+ using ::authors;
+ //using ::credits;
+ for ( unsigned int i = 0 ; i < sizeof authors / sizeof *authors ; ++i )
+ addAuthor( authors[i].name, authors[i].desc,
+ authors[i].email, authors[i].web );
+#if 0
+ for ( unsigned int i = 0 ; i < sizeof credits / sizeof *credits ; ++i )
+ addCredit( credits[i].name, credits[i].desc,
+ credits[i].email, credits[i].web );
+#endif
+}
diff --git a/certmanager/kwatchgnupg/aboutdata.h b/certmanager/kwatchgnupg/aboutdata.h
new file mode 100644
index 000000000..0e1f9f631
--- /dev/null
+++ b/certmanager/kwatchgnupg/aboutdata.h
@@ -0,0 +1,43 @@
+/*
+ aboutdata.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef ABOUTDATA_H
+#define ABOUTDATA_H
+
+#include <kaboutdata.h>
+
+class AboutData : public KAboutData {
+public:
+ AboutData();
+};
+
+#endif // ABOUTDATA_H
diff --git a/certmanager/kwatchgnupg/kwatchgnupg.png b/certmanager/kwatchgnupg/kwatchgnupg.png
new file mode 100644
index 000000000..fbc255cec
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupg.png
Binary files differ
diff --git a/certmanager/kwatchgnupg/kwatchgnupg2.png b/certmanager/kwatchgnupg/kwatchgnupg2.png
new file mode 100644
index 000000000..59efb5ddd
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupg2.png
Binary files differ
diff --git a/certmanager/kwatchgnupg/kwatchgnupgconfig.cpp b/certmanager/kwatchgnupg/kwatchgnupgconfig.cpp
new file mode 100644
index 000000000..b621e92b8
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupgconfig.cpp
@@ -0,0 +1,206 @@
+/*
+ kwatchgnupgconfig.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "kwatchgnupgconfig.h"
+
+#include <klocale.h>
+#include <kurlrequester.h>
+#include <kconfig.h>
+#include <kapplication.h>
+
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <qcheckbox.h>
+#include <qcombobox.h>
+#include <qdir.h>
+#include <qvgroupbox.h>
+
+static const char* log_levels[] = { "none", "basic", "advanced", "expert", "guru" };
+
+static int log_level_to_int( const QString& loglevel )
+{
+ if( loglevel == "none" ) {
+ return 0;
+ } else if( loglevel == "basic" ) {
+ return 1;
+ } else if( loglevel == "advanced" ) {
+ return 2;
+ } else if( loglevel == "expert" ) {
+ return 3;
+ } else if( loglevel == "guru" ) {
+ return 4;
+ } else {
+ // default
+ return 1;
+ }
+}
+
+KWatchGnuPGConfig::KWatchGnuPGConfig( QWidget* parent, const char* name )
+ : KDialogBase( Plain, i18n("Configure KWatchGnuPG"),
+ Ok|Cancel, Ok, parent, name )
+{
+ // tmp vars:
+ QWidget * w;
+ QGridLayout * glay;
+ QGroupBox * group;
+
+ QWidget * top = plainPage();
+
+ QVBoxLayout * vlay = new QVBoxLayout( top, 0, spacingHint() );
+
+ group = new QVGroupBox( i18n("WatchGnuPG"), top );
+ group->layout()->setSpacing( spacingHint() );
+
+ w = new QWidget( group );
+
+ glay = new QGridLayout( w, 3, 2, 0, spacingHint() );
+ glay->setColStretch( 1, 1 );
+
+ int row = -1;
+
+ ++row;
+ mExeED = new KURLRequester( w );
+ glay->addWidget( new QLabel( mExeED, i18n("&Executable:"), w ), row, 0 );
+ glay->addWidget( mExeED, row, 1 );
+ connect( mExeED, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()) );
+
+ ++row;
+ mSocketED = new KURLRequester( w );
+ glay->addWidget( new QLabel( mSocketED, i18n("&Socket:"), w ), row, 0 );
+ glay->addWidget( mSocketED, row, 1 );
+ connect( mSocketED, SIGNAL(textChanged(const QString&)), SLOT(slotChanged()) );
+
+ ++row;
+ mLogLevelCB = new QComboBox( false, w );
+ mLogLevelCB->insertItem( i18n("None") );
+ mLogLevelCB->insertItem( i18n("Basic") );
+ mLogLevelCB->insertItem( i18n("Advanced") );
+ mLogLevelCB->insertItem( i18n("Expert") );
+ mLogLevelCB->insertItem( i18n("Guru") );
+ glay->addWidget( new QLabel( mLogLevelCB, i18n("Default &log level:"), w ), row, 0 );
+ glay->addWidget( mLogLevelCB, row, 1 );
+ connect( mLogLevelCB, SIGNAL(activated(int)), SLOT(slotChanged()) );
+
+ vlay->addWidget( group );
+
+ /******************* Log Window group *******************/
+ group = new QVGroupBox( i18n("Log Window"), top );
+ group->layout()->setSpacing( spacingHint() );
+
+ w = new QWidget( group );
+
+ glay = new QGridLayout( w, 2, 3, 0, spacingHint() );
+ glay->setColStretch( 1, 1 );
+
+ row = -1;
+
+ ++row;
+ mLoglenSB = new QSpinBox( 0, 1000000, 100, w );
+ mLoglenSB->setSuffix( i18n("history size spinbox suffix"," lines") );
+ mLoglenSB->setSpecialValueText( i18n("unlimited") );
+ glay->addWidget( new QLabel( mLoglenSB, i18n("&History size:"), w ), row, 0 );
+ glay->addWidget( mLoglenSB, row, 1 );
+ QPushButton * button = new QPushButton( i18n("Set &Unlimited"), w );
+ glay->addWidget( button, row, 2 );
+
+ connect( mLoglenSB, SIGNAL(valueChanged(int)), SLOT(slotChanged()) );
+ connect( button, SIGNAL(clicked()), SLOT(slotSetHistorySizeUnlimited()) );
+
+ ++row;
+ mWordWrapCB = new QCheckBox( i18n("Enable &word wrapping"), w );
+ mWordWrapCB->hide(); // QTextEdit doesn't support word wrapping in LogText mode
+ glay->addMultiCellWidget( mWordWrapCB, row, row, 0, 2 );
+
+ connect( mWordWrapCB, SIGNAL(clicked()), SLOT(slotChanged()) );
+
+ vlay->addWidget( group );
+ vlay->addStretch( 1 );
+
+ connect( this, SIGNAL(applyClicked()), SLOT(slotSave()) );
+ connect( this, SIGNAL(okClicked()), SLOT(slotSave()) );
+}
+
+void KWatchGnuPGConfig::slotSetHistorySizeUnlimited() {
+ mLoglenSB->setValue( 0 );
+}
+
+void KWatchGnuPGConfig::loadConfig()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("WatchGnuPG");
+ mExeED->setURL( config->readEntry( "Executable", "watchgnupg" ) );
+ mSocketED->setURL( config->readEntry( "Socket", QDir::home().canonicalPath()
+ + "/.gnupg/log-socket") );
+ mLogLevelCB->setCurrentItem( log_level_to_int( config->readEntry( "LogLevel", "basic" ) ) );
+
+ config->setGroup("LogWindow");
+ mLoglenSB->setValue( config->readNumEntry( "MaxLogLen", 10000 ) );
+ mWordWrapCB->setChecked( config->readBoolEntry("WordWrap", false ) );
+
+ config->setGroup( QString::null );
+ enableButtonOK( false );
+ enableButtonApply( false );
+}
+
+void KWatchGnuPGConfig::saveConfig()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("WatchGnuPG");
+ config->writeEntry( "Executable", mExeED->url() );
+ config->writeEntry( "Socket", mSocketED->url() );
+ config->writeEntry( "LogLevel", log_levels[mLogLevelCB->currentItem()] );
+
+ config->setGroup("LogWindow");
+ config->writeEntry( "MaxLogLen", mLoglenSB->value() );
+ config->writeEntry( "WordWrap", mWordWrapCB->isChecked() );
+
+ config->setGroup( QString::null );
+ config->sync();
+ enableButtonOK( false );
+ enableButtonApply( false );
+}
+
+void KWatchGnuPGConfig::slotChanged()
+{
+ enableButtonOK( true );
+ enableButtonApply( true );
+}
+
+void KWatchGnuPGConfig::slotSave()
+{
+ saveConfig();
+ emit reconfigure();
+}
+
+#include "kwatchgnupgconfig.moc"
diff --git a/certmanager/kwatchgnupg/kwatchgnupgconfig.h b/certmanager/kwatchgnupg/kwatchgnupgconfig.h
new file mode 100644
index 000000000..4a93b463b
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupgconfig.h
@@ -0,0 +1,68 @@
+/*
+ kwatchgnupgconfig.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KWATCHGNUPGCONFIG_H
+#define KWATCHGNUPGCONFIG_H
+
+#include <kdialogbase.h>
+
+class QCheckBox;
+class QComboBox;
+class QSpinBox;
+class KURLRequester;
+
+class KWatchGnuPGConfig : public KDialogBase {
+ Q_OBJECT
+public:
+ KWatchGnuPGConfig( QWidget* parent, const char* name = 0 );
+
+ void loadConfig();
+ void saveConfig();
+
+signals:
+ void reconfigure();
+
+private slots:
+ void slotChanged();
+ void slotSave();
+ void slotSetHistorySizeUnlimited();
+
+private:
+ KURLRequester* mExeED;
+ KURLRequester* mSocketED;
+ QComboBox* mLogLevelCB;
+ QSpinBox* mLoglenSB;
+ QCheckBox* mWordWrapCB;
+};
+
+#endif /* KWATCHGNUPGCONFIG_H */
+
diff --git a/certmanager/kwatchgnupg/kwatchgnupgmainwin.cpp b/certmanager/kwatchgnupg/kwatchgnupgmainwin.cpp
new file mode 100644
index 000000000..19bda278b
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupgmainwin.cpp
@@ -0,0 +1,292 @@
+/*
+ kwatchgnupgmainwin.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "kwatchgnupgmainwin.h"
+#include "kwatchgnupgconfig.h"
+#include "tray.h"
+
+#include <kleo/cryptobackendfactory.h>
+#include <kleo/cryptoconfig.h>
+
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <kstdaction.h>
+#include <kprocio.h>
+#include <kconfig.h>
+#include <kfiledialog.h>
+#include <kedittoolbar.h>
+#include <kkeydialog.h>
+
+#include <qtextedit.h>
+#include <qdir.h>
+#include <qeventloop.h>
+#include <qtimer.h>
+#include <qtextcodec.h>
+
+#define WATCHGNUPGBINARY "watchgnupg"
+#define WATCHGNUPGSOCKET ( QDir::home().canonicalPath() + "/.gnupg/log-socket")
+
+KWatchGnuPGMainWindow::KWatchGnuPGMainWindow( QWidget* parent, const char* name )
+ : KMainWindow( parent, name, WType_TopLevel ), mConfig(0)
+{
+ createActions();
+ createGUI();
+
+ mCentralWidget = new QTextEdit( this, "central log view" );
+ mCentralWidget->setTextFormat( QTextEdit::LogText );
+ setCentralWidget( mCentralWidget );
+
+ mWatcher = new KProcIO( QTextCodec::codecForMib( 106 /*utf-8*/ ) );
+ connect( mWatcher, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotWatcherExited() ) );
+ connect( mWatcher, SIGNAL( readReady(KProcIO*) ),
+ this, SLOT( slotReadStdout() ) );
+
+ slotReadConfig();
+ mSysTray = new KWatchGnuPGTray( this );
+ mSysTray->show();
+ connect( mSysTray, SIGNAL( quitSelected() ),
+ this, SLOT( slotQuit() ) );
+ setAutoSaveSettings();
+}
+
+KWatchGnuPGMainWindow::~KWatchGnuPGMainWindow()
+{
+ delete mWatcher;
+}
+
+void KWatchGnuPGMainWindow::slotClear()
+{
+ mCentralWidget->clear();
+ mCentralWidget->append( tr("[%1] Log cleared").arg( QDateTime::currentDateTime().toString(Qt::ISODate) ) );
+}
+
+void KWatchGnuPGMainWindow::createActions()
+{
+ (void)new KAction( i18n("C&lear History"), "history_clear", CTRL+Key_L,
+ this, SLOT( slotClear() ),
+ actionCollection(), "clear_log" );
+ (void)KStdAction::saveAs( this, SLOT(slotSaveAs()), actionCollection() );
+ (void)KStdAction::close( this, SLOT(close()), actionCollection() );
+ (void)KStdAction::quit( this, SLOT(slotQuit()), actionCollection() );
+ (void)KStdAction::preferences( this, SLOT(slotConfigure()), actionCollection() );
+ ( void )KStdAction::keyBindings(this, SLOT(configureShortcuts()), actionCollection());
+ ( void )KStdAction::configureToolbars(this, SLOT(slotConfigureToolbars()), actionCollection());
+
+#if 0
+ (void)new KAction( i18n("Configure KWatchGnuPG..."), QString::fromLatin1("configure"),
+ 0, this, SLOT( slotConfigure() ),
+ actionCollection(), "configure" );
+#endif
+
+}
+
+void KWatchGnuPGMainWindow::configureShortcuts()
+{
+ KKeyDialog::configure( actionCollection(), this );
+}
+
+void KWatchGnuPGMainWindow::slotConfigureToolbars()
+{
+ KEditToolbar dlg( factory() );
+
+ dlg.exec();
+}
+
+void KWatchGnuPGMainWindow::startWatcher()
+{
+ disconnect( mWatcher, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotWatcherExited() ) );
+ if( mWatcher->isRunning() ) {
+ mWatcher->kill();
+ while( mWatcher->isRunning() ) {
+ kapp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput);
+ }
+ mCentralWidget->append(tr("[%1] Log stopped")
+ .arg( QDateTime::currentDateTime().toString(Qt::ISODate)));
+ }
+ mWatcher->clearArguments();
+ KConfig* config = kapp->config();
+ config->setGroup("WatchGnuPG");
+ *mWatcher << config->readEntry("Executable", WATCHGNUPGBINARY);
+ *mWatcher << "--force";
+ *mWatcher << config->readEntry("Socket", WATCHGNUPGSOCKET);
+ config->setGroup(QString::null);
+ if( !mWatcher->start() ) {
+ KMessageBox::sorry( this, i18n("The watchgnupg logging process could not be started.\nPlease install watchgnupg somewhere in your $PATH.\nThis log window is now completely useless." ) );
+ } else {
+ mCentralWidget->append( tr("[%1] Log started")
+ .arg( QDateTime::currentDateTime().toString(Qt::ISODate) ) );
+ }
+ connect( mWatcher, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotWatcherExited() ) );
+}
+
+void KWatchGnuPGMainWindow::setGnuPGConfig()
+{
+ QStringList logclients;
+ // Get config object
+ Kleo::CryptoConfig* cconfig = Kleo::CryptoBackendFactory::instance()->config();
+ if ( !cconfig )
+ return;
+ //Q_ASSERT( cconfig );
+ KConfig* config = kapp->config();
+ config->setGroup("WatchGnuPG");
+ QStringList comps = cconfig->componentList();
+ for( QStringList::const_iterator it = comps.begin(); it != comps.end(); ++it ) {
+ Kleo::CryptoConfigComponent* comp = cconfig->component( *it );
+ Q_ASSERT(comp);
+ // Look for log-file entry in Debug group
+ Kleo::CryptoConfigGroup* group = comp->group("Debug");
+ if( group ) {
+ Kleo::CryptoConfigEntry* entry = group->entry("log-file");
+ if( entry ) {
+ entry->setStringValue( QString("socket://")+
+ config->readEntry("Socket",
+ WATCHGNUPGSOCKET ));
+ logclients << QString("%1 (%2)").arg(*it).arg(comp->description());
+ }
+ entry = group->entry("debug-level");
+ if( entry ) {
+ entry->setStringValue( config->readEntry("LogLevel", "basic") );
+ }
+ }
+ }
+ cconfig->sync(true);
+ if( logclients.isEmpty() ) {
+ KMessageBox::sorry( 0, i18n("There are no components available that support logging." ) );
+ }
+}
+
+void KWatchGnuPGMainWindow::slotWatcherExited()
+{
+ if( KMessageBox::questionYesNo( this, i18n("The watchgnupg logging process died.\nDo you want to try to restart it?"), QString::null, i18n("Try Restart"), i18n("Do Not Try") ) == KMessageBox::Yes ) {
+ mCentralWidget->append( i18n("====== Restarting logging process =====") );
+ startWatcher();
+ } else {
+ KMessageBox::sorry( this, i18n("The watchgnupg logging process is not running.\nThis log window is now completely useless." ) );
+ }
+}
+
+void KWatchGnuPGMainWindow::slotReadStdout()
+{
+ if ( !mWatcher )
+ return;
+ QString str;
+ while( mWatcher->readln(str,false) > 0 ) {
+ mCentralWidget->append( str );
+ if( !isVisible() ) {
+ // Change tray icon to show something happened
+ // PENDING(steffen)
+ mSysTray->setAttention(true);
+ }
+ }
+ QTimer::singleShot( 0, this, SLOT(slotAckRead()) );
+}
+
+void KWatchGnuPGMainWindow::slotAckRead() {
+ if ( mWatcher )
+ mWatcher->ackRead();
+}
+
+void KWatchGnuPGMainWindow::show()
+{
+ mSysTray->setAttention(false);
+ KMainWindow::show();
+}
+
+void KWatchGnuPGMainWindow::slotSaveAs()
+{
+ QString filename = KFileDialog::getSaveFileName( QString::null, QString::null,
+ this, i18n("Save Log to File") );
+ if( filename.isEmpty() ) return;
+ QFile file(filename);
+ if( file.exists() ) {
+ if( KMessageBox::Yes !=
+ KMessageBox::warningYesNo( this, i18n("The file named \"%1\" already "
+ "exists. Are you sure you want "
+ "to overwrite it?").arg(filename),
+ i18n("Overwrite File"), i18n("Overwrite"), KStdGuiItem::cancel() ) ) {
+ return;
+ }
+ }
+ if( file.open( IO_WriteOnly ) ) {
+ QTextStream st(&file);
+ st << mCentralWidget->text();
+ file.close();
+ }
+}
+
+void KWatchGnuPGMainWindow::slotQuit()
+{
+ disconnect( mWatcher, SIGNAL( processExited(KProcess*) ),
+ this, SLOT( slotWatcherExited() ) );
+ mWatcher->kill();
+ kapp->quit();
+}
+
+void KWatchGnuPGMainWindow::slotConfigure()
+{
+ if( !mConfig ) {
+ mConfig = new KWatchGnuPGConfig( this, "config dialog" );
+ connect( mConfig, SIGNAL( reconfigure() ),
+ this, SLOT( slotReadConfig() ) );
+ }
+ mConfig->loadConfig();
+ mConfig->exec();
+}
+
+void KWatchGnuPGMainWindow::slotReadConfig()
+{
+ KConfig* config = kapp->config();
+ config->setGroup("LogWindow");
+ mCentralWidget->setWordWrap( config->readBoolEntry("WordWrap", false)
+ ?QTextEdit::WidgetWidth
+ :QTextEdit::NoWrap );
+ mCentralWidget->setMaxLogLines( config->readNumEntry( "MaxLogLen", 10000 ) );
+ setGnuPGConfig();
+ startWatcher();
+}
+
+bool KWatchGnuPGMainWindow::queryClose()
+{
+ if ( !kapp->sessionSaving() ) {
+ hide();
+ return false;
+ }
+ return KMainWindow::queryClose();
+}
+
+#include "kwatchgnupgmainwin.moc"
diff --git a/certmanager/kwatchgnupg/kwatchgnupgmainwin.h b/certmanager/kwatchgnupg/kwatchgnupgmainwin.h
new file mode 100644
index 000000000..2021a6579
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupgmainwin.h
@@ -0,0 +1,78 @@
+/*
+ main.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KWATCHGNUPGMAINWIN_H
+#define KWATCHGNUPGMAINWIN_H
+
+#include <kmainwindow.h>
+
+class KWatchGnuPGTray;
+class KWatchGnuPGConfig;
+class KProcIO;
+class QTextEdit;
+
+class KWatchGnuPGMainWindow : public KMainWindow {
+ Q_OBJECT
+public:
+ KWatchGnuPGMainWindow( QWidget* parent = 0, const char* name = 0 );
+ virtual ~KWatchGnuPGMainWindow();
+public slots:
+ void slotWatcherExited();
+ void slotReadStdout();
+ void slotAckRead();
+
+ void slotSaveAs();
+ void slotQuit();
+ void slotClear();
+
+ void slotConfigure();
+ void slotConfigureToolbars();
+ void configureShortcuts();
+ void slotReadConfig();
+
+ virtual void show();
+protected:
+ virtual bool queryClose();
+private:
+ void createActions();
+ void startWatcher();
+ void setGnuPGConfig();
+
+ KProcIO* mWatcher;
+
+ QTextEdit* mCentralWidget;
+ KWatchGnuPGTray* mSysTray;
+ KWatchGnuPGConfig* mConfig;
+};
+
+#endif /* KWATCHGNUPGMAINWIN_H */
+
diff --git a/certmanager/kwatchgnupg/kwatchgnupgui.rc b/certmanager/kwatchgnupg/kwatchgnupgui.rc
new file mode 100644
index 000000000..3e42a1410
--- /dev/null
+++ b/certmanager/kwatchgnupg/kwatchgnupgui.rc
@@ -0,0 +1,21 @@
+<!DOCTYPE kpartgui ><kpartgui name="kwatchgnupg" version="7">
+<MenuBar>
+ <Menu name="file" >
+ <text>&amp;File</text>
+ <Action name="clear_log"/>
+ <Action name="print"/>
+ <Separator/>
+ <Action name="close"/>
+ <Action name="quit"/>
+ </Menu>
+</MenuBar>
+<ToolBar noMerge="1" name="mainToolBar" >
+ <text>Main Toolbar</text>
+ <Action name="file_save_as"/>
+ <Separator/>
+ <Action name="clear_log"/>
+ <Separator/>
+ <Action name="options_configure"/>
+</ToolBar>
+
+</kpartgui>
diff --git a/certmanager/kwatchgnupg/main.cpp b/certmanager/kwatchgnupg/main.cpp
new file mode 100644
index 000000000..7c25a8da0
--- /dev/null
+++ b/certmanager/kwatchgnupg/main.cpp
@@ -0,0 +1,96 @@
+/*
+ main.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "aboutdata.h"
+#include "kwatchgnupgmainwin.h"
+
+#include <kuniqueapplication.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+class KWatchGnuPGApplication : public KUniqueApplication {
+public:
+ KWatchGnuPGApplication();
+ ~KWatchGnuPGApplication();
+ virtual int newInstance();
+private:
+ KWatchGnuPGMainWindow* mMainWin;
+};
+
+KWatchGnuPGApplication::KWatchGnuPGApplication()
+ : KUniqueApplication(), mMainWin(0)
+{
+}
+
+KWatchGnuPGApplication::~KWatchGnuPGApplication()
+{
+ delete mMainWin;
+}
+
+int KWatchGnuPGApplication::newInstance()
+{
+ if( !mMainWin ) {
+ mMainWin = new KWatchGnuPGMainWindow( 0, "kwatchgnupg mainwin" );
+ setMainWidget( mMainWin );
+ }
+ mMainWin->show();
+ return KUniqueApplication::newInstance();
+}
+
+int main( int argc, char** argv )
+{
+ AboutData aboutData;
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ static const KCmdLineOptions options[] = {
+ KCmdLineLastOption// End of options.
+ };
+ KCmdLineArgs::addCmdLineOptions( options );
+ KWatchGnuPGApplication::addCmdLineOptions();
+
+#if 0
+ if (!KWatchGnuPGApplication::start()) {
+ kdError() << "KWatchGnuPG is already running!" << endl;
+ return 0;
+ }
+#endif
+ KWatchGnuPGApplication app;
+ return app.exec();
+}
diff --git a/certmanager/kwatchgnupg/tray.cpp b/certmanager/kwatchgnupg/tray.cpp
new file mode 100644
index 000000000..62024b14a
--- /dev/null
+++ b/certmanager/kwatchgnupg/tray.cpp
@@ -0,0 +1,66 @@
+/*
+ main.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "tray.h"
+#include "kwatchgnupgmainwin.h"
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <qtooltip.h>
+
+KWatchGnuPGTray::KWatchGnuPGTray( KWatchGnuPGMainWindow* mainwin )
+ : KSystemTray( mainwin, "KWatchGnuPG Tray Window" )
+{
+ kdDebug() << "KWatchGnuPGTray::KWatchGnuPGTray" << endl;
+
+ KGlobal::iconLoader()->addAppDir( "kwatchgnupg" );
+
+ mNormalPix = loadIcon("kwatchgnupg");
+ mAttentionPix = loadIcon("kwatchgnupg2");
+
+ setPixmap( mNormalPix );
+ QToolTip::add( this, i18n("KWatchGnuPG Log Viewer") );
+}
+
+KWatchGnuPGTray::~KWatchGnuPGTray()
+{
+}
+
+void KWatchGnuPGTray::setAttention( bool att )
+{
+ if( att ) setPixmap( mAttentionPix );
+ else setPixmap( mNormalPix );
+}
+
+#include "tray.moc"
diff --git a/certmanager/kwatchgnupg/tray.h b/certmanager/kwatchgnupg/tray.h
new file mode 100644
index 000000000..7f220ecad
--- /dev/null
+++ b/certmanager/kwatchgnupg/tray.h
@@ -0,0 +1,55 @@
+/*
+ main.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef TRAY_H
+#define TRAY_H
+
+#include <ksystemtray.h>
+#include <qpixmap.h>
+
+class KWatchGnuPGMainWindow;
+
+class KWatchGnuPGTray : public KSystemTray {
+ Q_OBJECT
+public:
+ KWatchGnuPGTray( KWatchGnuPGMainWindow* mainwin );
+ virtual ~KWatchGnuPGTray();
+
+public slots:
+ void setAttention( bool att );
+private:
+ QPixmap mNormalPix;
+ QPixmap mAttentionPix;
+};
+
+#endif /* TRAY_H */
+
diff --git a/certmanager/lib/Makefile.am b/certmanager/lib/Makefile.am
new file mode 100644
index 000000000..ae101fd0e
--- /dev/null
+++ b/certmanager/lib/Makefile.am
@@ -0,0 +1,49 @@
+INCLUDES = -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+SUBDIRS = pics kleo backends ui . tests
+
+lib_LTLIBRARIES = libkleopatra.la
+
+libkleopatra_la_SOURCES = \
+ cryptplug.cpp \
+ cryptplugwrapper.cpp \
+ cryptplugwrapperlist.cpp \
+ cryptplugfactory.cpp
+
+libkleopatra_la_LIBADD = \
+ kleo/libkleopatra_core.la \
+ backends/qgpgme/libkleopatra_backend_qgpgme.la \
+ backends/chiasmus/libkleopatra_backend_chiasmus.la \
+ ui/libkleopatra_ui.la \
+ \
+ $(top_builddir)/libkdenetwork/qgpgme/libqgpgme.la \
+ $(LIB_KIO) $(LIB_KDEUI)
+
+# Disabled for kdepim-3.3, see also kleo/cryptobackendfactory.cpp
+# backends/kpgp/libkleopatra_backend_kpgp.la
+
+# --version-info CURRENT:REVISION:AGE
+# (Code changed: REVISION++)
+# (Interfaces added/removed/changed: CURRENT++, REVISION=0)
+# (Interfaces added: AGE++)
+# (Interfaces removed/changed: AGE=0)
+libkleopatra_la_LDFLAGS = $(all_libraries) -version-info 1:0:0 -no-undefined
+
+METASOURCES = AUTO
+
+# remove the .desktop suffix on install (which is needed for translation)
+install-data-local:
+ $(mkinstalldirs) $(DESTDIR)$(kde_confdir)
+ $(INSTALL_DATA) $(srcdir)/libkleopatrarc.desktop $(DESTDIR)$(kde_confdir)/libkleopatrarc
+
+uninstall-local:
+ rm -f $(DESTDIR)$(kde_confdir)/libkleopatrarc
+
+messages: #rc.cpp
+ $(EXTRACTRC) */*.ui > rc.cpp
+ $(XGETTEXT) *.cpp *.h \
+ kleo/*.cpp kleo/*.h \
+ ui/*.cpp ui/*.h \
+ backends/*/*.cpp backends/*/*.h -o $(podir)/libkleopatra.pot
+
+include $(top_srcdir)/admin/Doxyfile.am
diff --git a/certmanager/lib/backends/Makefile.am b/certmanager/lib/backends/Makefile.am
new file mode 100644
index 000000000..0219d7627
--- /dev/null
+++ b/certmanager/lib/backends/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = qgpgme chiasmus
diff --git a/certmanager/lib/backends/chiasmus/Makefile.am b/certmanager/lib/backends/chiasmus/Makefile.am
new file mode 100644
index 000000000..8a5d85bd4
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/Makefile.am
@@ -0,0 +1,16 @@
+INCLUDES = -I$(top_srcdir)/certmanager/lib -I$(top_srcdir)/libkdenetwork $(GPGME_CFLAGS) $(all_includes)
+
+KDE_CXXFLAGS = '-DGPG_ERR_SOURCE_DEFAULT=((gpg_err_source_t)176)'
+
+noinst_LTLIBRARIES = libkleopatra_backend_chiasmus.la
+
+libkleopatra_backend_chiasmus_la_SOURCES = \
+ config_data.c \
+ obtainkeysjob.cpp \
+ symcryptrunprocessbase.cpp \
+ chiasmusjob.cpp \
+ chiasmuslibrary.cpp \
+ chiasmusbackend.cpp
+
+
+METASOURCES = AUTO
diff --git a/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp b/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp
new file mode 100644
index 000000000..15a63de53
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmusbackend.cpp
@@ -0,0 +1,480 @@
+/*
+ chiasmusbackend.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "chiasmusbackend.h"
+
+#include "config_data.h"
+#include "obtainkeysjob.h"
+#include "chiasmusjob.h"
+
+#include "kleo/cryptoconfig.h"
+
+#include <klocale.h>
+#include <kconfig.h>
+#include <kshell.h>
+#include <kdebug.h>
+
+#include <qstringlist.h>
+#include <qvariant.h>
+#include <qfileinfo.h>
+
+#include <map>
+#include <memory>
+
+#include <cassert>
+
+namespace {
+
+ //
+ // The usual QVariant template helpers:
+ //
+
+ // to<> is a demarshaller. It's a class b/c you can't partially
+ // specialise function templates yet. However, to<> can be used as if
+ // it was a function: QString s = to<QString>( myVariant );
+ template <typename T> class to {};
+
+#define MAKE_TO( type, func ) \
+ template <> \
+ class to< type > { \
+ type m; \
+ public: \
+ to( const QVariant & v ) : m( v.func() ) {} \
+ operator type() const { return m; } \
+ }
+
+ MAKE_TO( int, toInt );
+ MAKE_TO( unsigned int, toUInt );
+
+ template <>
+ class to<KURL> {
+ KURL m;
+ public:
+ to( const QVariant & v ) {
+ m.setPath( v.toString() );
+ }
+ operator KURL() const { return m; }
+ };
+
+ template <typename T>
+ class to< QValueList<T> > {
+ QValueList<T> m;
+ public:
+ to( const QVariant & v ) {
+ const QValueList<QVariant> vl = v.toList();
+ for ( QValueList<QVariant>::const_iterator it = vl.begin(), end = vl.end() ; it != end ; ++it )
+ m.push_back( to<T>( *it ) );
+ }
+ operator QValueList<T> () const { return m; }
+ };
+
+ template <>
+ class to<KURL::List> {
+ KURL::List m;
+ public:
+ to( const QVariant & v ) {
+ // wow, KURL::List is broken... it lacks conversion from and to QVL<KURL>...
+ m += to< QValueList<KURL> >( v );
+ }
+ operator KURL::List() const { return m; }
+ };
+
+
+ // from<> is the demarshaller. See to<> for why this is a class...
+
+ template <typename T>
+ struct from_helper : public QVariant {
+ from_helper( const T & t ) : QVariant( t ) {}
+ };
+
+ template <typename T>
+ QVariant from( const T & t ) {
+ return from_helper<T>( t );
+ }
+
+ // some special types:
+ template <> struct from_helper<bool> : public QVariant {
+ from_helper( bool b ) : QVariant( b, int() ) {}
+ };
+ template <> struct from_helper<KURL> : public QVariant {
+ from_helper( const KURL & url ) : QVariant( url.path() ) {}
+ };
+ template <typename T> struct from_helper< QValueList<T> > : public QVariant {
+ from_helper( const QValueList<T> & l ) {
+ QValueList<QVariant> result;
+ for ( typename QValueList<T>::const_iterator it = l.begin(), end = l.end() ; it != end ; ++it )
+ result.push_back( from( *it ) );
+ QVariant::operator=( result );
+ }
+ };
+ template <> struct from_helper<KURL::List> : public from_helper< QValueList<KURL> > {
+ from_helper( const KURL::List & l ) : from_helper< QValueList<KURL> >( l ) {}
+ };
+
+ class ChiasmusConfigEntry : public Kleo::CryptoConfigEntry {
+ unsigned int mIdx;
+ QVariant mValue;
+ bool mDirty;
+ public:
+ ChiasmusConfigEntry( unsigned int i )
+ : Kleo::CryptoConfigEntry(),
+ mIdx( i ), mValue( defaultValue() ), mDirty( false )
+ {
+ assert( i < kleo_chiasmus_config_entries_dim );
+ }
+ QString name() const { return kleo_chiasmus_config_entries[mIdx].name; }
+ QString description() const { return i18n( kleo_chiasmus_config_entries[mIdx].description ); }
+ bool isOptional() const { return kleo_chiasmus_config_entries[mIdx].is_optional; }
+ bool isReadOnly() const { return false; }
+ bool isList() const { return kleo_chiasmus_config_entries[mIdx].is_list; }
+ bool isRuntime() const { return kleo_chiasmus_config_entries[mIdx].is_runtime; }
+ Level level() const { return static_cast<Level>( kleo_chiasmus_config_entries[mIdx].level ); }
+ ArgType argType() const { return static_cast<ArgType>( kleo_chiasmus_config_entries[mIdx].type ); }
+ bool isSet() const { return mValue != defaultValue(); }
+ bool boolValue() const { return mValue.toBool(); }
+ QString stringValue() const { return mValue.toString(); }
+ int intValue() const { return mValue.toInt(); }
+ unsigned int uintValue() const { return mValue.toUInt(); }
+ KURL urlValue() const {
+ if ( argType() != ArgType_Path && argType() != ArgType_DirPath ) return KURL( mValue.toString() );
+ KURL u; u.setPath( mValue.toString() ); return u;
+ }
+ unsigned int numberOfTimesSet() const { return 0; }
+ QStringList stringValueList() const { return mValue.toStringList(); }
+ QValueList<int> intValueList() const { return to< QValueList<int> >( mValue ); }
+ QValueList<unsigned int> uintValueList() const { return to< QValueList<unsigned int> >( mValue ); }
+ KURL::List urlValueList() const {
+ if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) return mValue.toStringList();
+ else return to<KURL::List>( mValue ); }
+ void resetToDefault() { mValue = defaultValue(); mDirty = false; }
+ void setBoolValue( bool value ) { setValue( QVariant( value, int() ) ); }
+ void setStringValue( const QString & value ) { setValue( value ); }
+ void setIntValue( int value ) { setValue( value ); }
+ void setUIntValue( unsigned int value ) { setValue( value ); }
+ void setURLValue( const KURL & value ) {
+ if ( argType() != ArgType_Path && argType()!= ArgType_DirPath ) setValue( value.url() );
+ else setValue( value.path() );
+ }
+ void setNumberOfTimesSet( unsigned int ) {}
+ void setStringValueList( const QStringList & value ) { setValue( value ); }
+ void setIntValueList( const QValueList<int> & l ) { setValue( from( l ) ); }
+ void setUIntValueList( const QValueList<unsigned int> & l ) { setValue( from( l ) ); }
+ void setURLValueList( const KURL::List & l ) { setValue( from( l ) ); }
+ bool isDirty() const { return mDirty; }
+
+ QVariant value() const { return mValue; }
+
+ void sync( KConfigBase * config ) {
+ if ( !mDirty )
+ return;
+ mDirty = false;
+ config->writeEntry( kleo_chiasmus_config_entries[mIdx].name, mValue );
+ }
+ void read( const KConfigBase * config ) {
+ mDirty = false;
+ mValue = config->readPropertyEntry( kleo_chiasmus_config_entries[mIdx].name, defaultValue() );
+ }
+ private:
+ QVariant defaultValue() const;
+ void setValue( const QVariant & value ) { mValue = value; mDirty = true; }
+ };
+
+ QVariant ChiasmusConfigEntry::defaultValue() const {
+ const kleo_chiasmus_config_data & data = kleo_chiasmus_config_entries[mIdx];
+ switch ( data.type ) {
+ default:
+ return QVariant();
+ case ArgType_None:
+ if ( isList() )
+ return QValueList<QVariant>() << QVariant( data.defaults.boolean.value, int() );
+ else
+ return QVariant( data.defaults.boolean.value, int() );
+ case ArgType_String:
+ if ( isList() )
+ return QStringList( QString::fromLatin1( data.defaults.string ) );
+ else
+ return QString::fromLatin1( data.defaults.string );
+ case ArgType_Int:
+ if ( isList() )
+ return QValueList<QVariant>() << data.defaults.integer;
+ else
+ return data.defaults.integer;
+ case ArgType_UInt:
+ if ( isList() )
+ return QValueList<QVariant>() << data.defaults.unsigned_integer;
+ else
+ return data.defaults.unsigned_integer;
+ case ArgType_Path:
+ case ArgType_DirPath:
+ if ( isList() )
+ return QValueList<QVariant>() << QString::fromLatin1( data.defaults.path );
+ else
+ return QString::fromLatin1( data.defaults.path );
+ case ArgType_URL:
+ case ArgType_LDAPURL:
+ if ( isList() )
+ return QValueList<QVariant>() << QString::fromLatin1( data.defaults.url );
+ else
+ return QString::fromLatin1( data.defaults.url );
+ }
+ }
+
+ class ChiasmusGeneralGroup : public Kleo::CryptoConfigGroup {
+ mutable std::map<QString,ChiasmusConfigEntry*> mCache;
+ mutable KConfig * mConfigObject;
+ public:
+ ChiasmusGeneralGroup() : Kleo::CryptoConfigGroup(), mConfigObject( 0 ) {}
+ ~ChiasmusGeneralGroup() { clear(); delete mConfigObject; }
+ QString name() const { return "General"; }
+ QString iconName() const { return "chiasmus_chi"; }
+ QString description() const { return i18n( "General" ); }
+ Kleo::CryptoConfigEntry::Level level() const { return Kleo::CryptoConfigEntry::Level_Basic; }
+ QStringList entryList() const {
+ QStringList result;
+ for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
+ result.push_back( kleo_chiasmus_config_entries[i].name );
+ return result;
+ }
+ Kleo::CryptoConfigEntry * entry( const QString & name ) const {
+ if ( ChiasmusConfigEntry * entry = mCache[name] )
+ return entry;
+ const KConfigGroup group( configObject(), "Chiasmus" );
+ for ( unsigned int i = 0 ; i < kleo_chiasmus_config_entries_dim ; ++i )
+ if ( name == kleo_chiasmus_config_entries[i].name ) {
+ ChiasmusConfigEntry * entry = new ChiasmusConfigEntry( i );
+ entry->read( &group );
+ return mCache[name] = entry;
+ }
+ return 0;
+ }
+
+ void sync() {
+ KConfigGroup group( configObject(), "Chiasmus" );
+ for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
+ it->second->sync( &group );
+ group.sync();
+ clear();
+ }
+ private:
+ KConfig * configObject() const {
+ if ( !mConfigObject )
+ // this is unsafe. We're a lib, used by concurrent apps.
+ mConfigObject = new KConfig( "chiasmusbackendrc" );
+ return mConfigObject;
+ }
+ void clear() {
+ for ( std::map<QString,ChiasmusConfigEntry*>::const_iterator it = mCache.begin(), end = mCache.end() ; it != end ; ++it )
+ delete it->second;
+ mCache.clear();
+ }
+ };
+
+ class ChiasmusComponent : public Kleo::CryptoConfigComponent {
+ mutable ChiasmusGeneralGroup * mGeneralGroup;
+ public:
+ ChiasmusComponent() : Kleo::CryptoConfigComponent(), mGeneralGroup( 0 ) {}
+ ~ChiasmusComponent() { delete mGeneralGroup; }
+
+ void sync() {
+ if ( mGeneralGroup )
+ mGeneralGroup->sync();
+ }
+
+ QString name() const { return "Chiasmus"; }
+ QString iconName() const { return "chiasmus_chi"; }
+ QString description() const { return i18n( "Chiasmus" ); }
+ QStringList groupList() const { return QStringList() << "General"; }
+ Kleo::CryptoConfigGroup * group( const QString & name ) const {
+ if ( name != "General" )
+ return 0;
+ if ( !mGeneralGroup )
+ mGeneralGroup = new ChiasmusGeneralGroup();
+ return mGeneralGroup;
+ }
+ };
+
+}
+
+class Kleo::ChiasmusBackend::CryptoConfig : public Kleo::CryptoConfig {
+ mutable ChiasmusComponent * mComponent;
+public:
+ CryptoConfig() : Kleo::CryptoConfig(), mComponent( 0 ) {}
+ ~CryptoConfig() { delete mComponent; }
+
+ QStringList componentList() const { return QStringList() << "Chiasmus" ; }
+ ChiasmusComponent * component( const QString & name ) const {
+ if ( name != "Chiasmus" )
+ return 0;
+ if ( !mComponent )
+ mComponent = new ChiasmusComponent();
+ return mComponent;
+ }
+ void sync( bool ) {
+ if ( mComponent )
+ mComponent->sync();
+ }
+ void clear() { delete mComponent; mComponent = 0; }
+};
+
+class Kleo::ChiasmusBackend::Protocol : public Kleo::CryptoBackend::Protocol {
+ Kleo::CryptoConfig * mCryptoConfig;
+public:
+ Protocol( Kleo::CryptoConfig * config )
+ : Kleo::CryptoBackend::Protocol(), mCryptoConfig( config )
+ {
+ assert( config );
+ }
+ ~Protocol() {}
+
+ QString name() const { return "Chiasmus"; }
+ QString displayName() const { return i18n( "Chiasmus command line tool" ); }
+ KeyListJob * keyListJob( bool, bool, bool ) const { return 0; }
+ EncryptJob * encryptJob( bool, bool ) const { return 0; }
+ DecryptJob * decryptJob() const { return 0; }
+ SignJob * signJob( bool, bool ) const { return 0; }
+ VerifyDetachedJob * verifyDetachedJob( bool ) const { return 0; }
+ VerifyOpaqueJob * verifyOpaqueJob( bool ) const { return 0; }
+ KeyGenerationJob * keyGenerationJob() const { return 0; }
+ ImportJob * importJob() const { return 0; }
+ ExportJob * publicKeyExportJob( bool ) const { return 0; }
+ ExportJob * secretKeyExportJob( bool, const QString& ) const { return 0; }
+ DownloadJob * downloadJob( bool ) const { return 0; }
+ DeleteJob * deleteJob() const { return 0; }
+ SignEncryptJob * signEncryptJob( bool, bool ) const { return 0; }
+ DecryptVerifyJob * decryptVerifyJob( bool ) const { return 0; }
+ RefreshKeysJob * refreshKeysJob() const { return 0; }
+
+ SpecialJob * specialJob( const char * type, const QMap<QString,QVariant> & args ) const {
+ if ( qstricmp( type, "x-obtain-keys" ) == 0 && args.size() == 0 )
+ return new ObtainKeysJob();
+ if ( qstricmp( type, "x-encrypt" ) == 0 && args.size() == 0 )
+ return new ChiasmusJob( ChiasmusJob::Encrypt );
+ if ( qstricmp( type, "x-decrypt" ) == 0 && args.size() == 0 )
+ return new ChiasmusJob( ChiasmusJob::Decrypt );
+ kdDebug(5150) << "ChiasmusBackend::Protocol: tried to instantiate unknown job type \""
+ << type << "\"" << endl;
+
+ return 0;
+ }
+};
+
+Kleo::ChiasmusBackend * Kleo::ChiasmusBackend::self = 0;
+
+Kleo::ChiasmusBackend::ChiasmusBackend()
+ : Kleo::CryptoBackend(),
+ mCryptoConfig( 0 ),
+ mProtocol( 0 )
+{
+ self = this;
+}
+
+Kleo::ChiasmusBackend::~ChiasmusBackend() {
+ self = 0;
+ delete mCryptoConfig;
+ delete mProtocol;
+}
+
+QString Kleo::ChiasmusBackend::name() const {
+ return "Chiasmus";
+}
+
+QString Kleo::ChiasmusBackend::displayName() const {
+ return i18n( "Chiasmus" );
+}
+
+Kleo::CryptoConfig * Kleo::ChiasmusBackend::config() const {
+ if ( !mCryptoConfig )
+ mCryptoConfig = new CryptoConfig();
+ return mCryptoConfig;
+}
+
+Kleo::CryptoBackend::Protocol * Kleo::ChiasmusBackend::protocol( const char * name ) const {
+ if ( qstricmp( name, "Chiasmus" ) != 0 )
+ return 0;
+ if ( !mProtocol )
+ if ( checkForChiasmus() )
+ mProtocol = new Protocol( config() );
+ return mProtocol;
+}
+
+bool Kleo::ChiasmusBackend::checkForOpenPGP( QString * reason ) const {
+ if ( reason )
+ *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "OpenPGP" );
+ return false;
+}
+
+bool Kleo::ChiasmusBackend::checkForSMIME( QString * reason ) const {
+ if ( reason )
+ *reason = i18n( "Unsupported protocol \"%1\"" ).arg( "SMIME" );
+ return false;
+}
+
+bool Kleo::ChiasmusBackend::checkForChiasmus( QString * reason ) const {
+
+ // kills the protocol instance when we return false:
+ std::auto_ptr<Protocol> tmp( mProtocol );
+ mProtocol = 0;
+
+ const CryptoConfigEntry * path = config()->entry( "Chiasmus", "General", "path" );
+ assert( path ); assert( path->argType() == CryptoConfigEntry::ArgType_Path );
+ const QString chiasmus = path->urlValue().path();
+ const QFileInfo fi( KShell::tildeExpand( chiasmus ) );
+ if ( !fi.isExecutable() ) {
+ if ( reason )
+ *reason = i18n( "File \"%1\" does not exist or is not executable." ).arg( chiasmus );
+ return false;
+ }
+
+ // FIXME: more checks?
+ mProtocol = tmp.release();
+ return true;
+}
+
+bool Kleo::ChiasmusBackend::checkForProtocol( const char * name, QString * reason ) const {
+ if ( qstricmp( name, "Chiasmus" ) == 0 )
+ return checkForChiasmus( reason );
+ if ( reason )
+ *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name );
+ return 0;
+}
+
+bool Kleo::ChiasmusBackend::supportsProtocol( const char * name ) const {
+ return qstricmp( name, "Chiasmus" ) == 0;
+}
+
+const char * Kleo::ChiasmusBackend::enumerateProtocols( int i ) const {
+ return i == 0 ? "Chiasmus" : 0 ;
+}
diff --git a/certmanager/lib/backends/chiasmus/chiasmusbackend.h b/certmanager/lib/backends/chiasmus/chiasmusbackend.h
new file mode 100644
index 000000000..6d51cad77
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmusbackend.h
@@ -0,0 +1,86 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ chiasmusbackend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_CHIASMUSBACKEND_H__
+#define __KLEO_CHIASMUSBACKEND_H__
+
+#include "kleo/cryptobackend.h"
+
+class CryptPlugWrapper;
+
+namespace Kleo {
+ class CryptoConfig;
+}
+class QString;
+
+namespace Kleo {
+
+ class ChiasmusBackend : public Kleo::CryptoBackend {
+ public:
+ ChiasmusBackend();
+ ~ChiasmusBackend();
+
+ static const ChiasmusBackend * instance() { return self; }
+
+ QString name() const;
+ QString displayName() const;
+
+ Kleo::CryptoConfig * config() const;
+
+ Kleo::CryptoBackend::Protocol * openpgp() const { return 0; }
+ Kleo::CryptoBackend::Protocol * smime() const { return 0; }
+ Kleo::CryptoBackend::Protocol * protocol( const char * name ) const;
+
+ bool checkForOpenPGP( QString * reason=0 ) const;
+ bool checkForSMIME( QString * reason=0 ) const;
+ bool checkForChiasmus( QString * reason=0 ) const;
+ bool checkForProtocol( const char * name, QString * reason=0 ) const;
+
+ bool supportsOpenPGP() const { return false; }
+ bool supportsSMIME() const { return false; }
+ bool supportsProtocol( const char * name ) const;
+
+ const char * enumerateProtocols( int i ) const;
+
+ private:
+ class CryptoConfig;
+ class Protocol;
+ mutable CryptoConfig * mCryptoConfig;
+ mutable Protocol * mProtocol;
+ static ChiasmusBackend * self;
+ };
+
+}
+
+
+#endif // __KLEO_CHIASMUSBACKEND_H__
diff --git a/certmanager/lib/backends/chiasmus/chiasmusjob.cpp b/certmanager/lib/backends/chiasmus/chiasmusjob.cpp
new file mode 100644
index 000000000..3ac7513df
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmusjob.cpp
@@ -0,0 +1,220 @@
+/*
+ chiasmusjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "chiasmusjob.h"
+#include "chiasmusbackend.h"
+#include "symcryptrunprocessbase.h"
+
+#include "kleo/cryptoconfig.h"
+#include "ui/passphrasedialog.h"
+
+#include <gpg-error.h>
+
+#include <kshell.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+
+#include <qtimer.h>
+#include <qfileinfo.h>
+#include <qvariant.h>
+
+#include <memory>
+
+#include <cassert>
+
+Kleo::ChiasmusJob::ChiasmusJob( Mode mode )
+ : Kleo::SpecialJob( 0, 0 ),
+ mSymCryptRun( 0 ),
+ mError( 0 ),
+ mCanceled( false ),
+ mTimeout( false ),
+ mMode( mode )
+{
+
+}
+
+Kleo::ChiasmusJob::~ChiasmusJob() {}
+
+GpgME::Error Kleo::ChiasmusJob::setup() {
+ if ( !checkPreconditions() )
+ return mError = gpg_error( GPG_ERR_INV_VALUE );
+
+ const Kleo::CryptoConfigEntry * class_
+ = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "symcryptrun-class" );
+ const Kleo::CryptoConfigEntry * chiasmus
+ = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "path" );
+ const Kleo::CryptoConfigEntry * timeoutEntry
+ = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "timeout" );
+ if ( !class_ || !chiasmus || !timeoutEntry )
+ return mError = gpg_error( GPG_ERR_INTERNAL );
+
+ mSymCryptRun = new SymCryptRunProcessBase( class_->stringValue(),
+ KShell::tildeExpand( chiasmus->urlValue().path() ),
+ mKey, mOptions,
+ mMode == Encrypt
+ ? SymCryptRunProcessBase::Encrypt
+ : SymCryptRunProcessBase::Decrypt,
+ this, "symcryptrun" );
+ QTimer::singleShot( timeoutEntry->uintValue() * 1000, this,
+ SLOT( slotTimeout() ) );
+ return 0;
+}
+
+namespace {
+ struct LaterDeleter {
+ QObject * _this;
+ LaterDeleter( QObject * o ) : _this( o ) {}
+ ~LaterDeleter() { if ( _this ) _this->deleteLater(); }
+ void disable() { _this = 0; }
+ };
+}
+
+GpgME::Error Kleo::ChiasmusJob::start() {
+
+ LaterDeleter d( this );
+
+ if ( const GpgME::Error err = setup() )
+ return mError = err;
+
+ connect( mSymCryptRun, SIGNAL(processExited(KProcess*)),
+ this, SLOT(slotProcessExited(KProcess*)) );
+
+ if ( !mSymCryptRun->launch( mInput ) )
+ return mError = gpg_error( GPG_ERR_ENOENT ); // what else?
+
+ d.disable();
+ return mError = 0;
+}
+
+GpgME::Error Kleo::ChiasmusJob::slotProcessExited( KProcess * proc ) {
+ if ( proc != mSymCryptRun )
+ mError = gpg_error( GPG_ERR_INTERNAL );
+ else if ( mCanceled )
+ mError = gpg_error( GPG_ERR_CANCELED );
+ else if ( mTimeout )
+ mError = gpg_error( GPG_ERR_TIMEOUT );
+ else if ( !proc->normalExit() )
+ mError = gpg_error( GPG_ERR_GENERAL );
+ else
+ switch ( proc->exitStatus() ) {
+ case 0: // success
+ mOutput = mSymCryptRun->output();
+ mError = 0;
+ break;
+ default:
+ case 1: // Some error occured
+ mStderr = mSymCryptRun->stdErr();
+ mError = gpg_error( GPG_ERR_GENERAL );
+ break;
+ case 2: // No valid passphrase was provided
+ mError = gpg_error( GPG_ERR_INV_PASSPHRASE );
+ break;
+ case 3: // Canceled
+ mError = gpg_error( GPG_ERR_CANCELED );
+ break;
+ }
+
+ const Kleo::CryptoConfigEntry * showOutput
+ = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "show-output" );
+ if ( showOutput && showOutput->boolValue() ) {
+ showChiasmusOutput();
+ }
+
+ emit done();
+ emit SpecialJob::result( mError, QVariant( mOutput ) );
+ return mError;
+}
+
+void Kleo::ChiasmusJob::showChiasmusOutput() {
+ kdDebug() << k_funcinfo << endl;
+ if ( mStderr.isEmpty() )
+ return;
+ KMessageBox::information( 0 /*how to get a parent widget?*/,
+ mStderr,
+ i18n( "Output from chiasmus" ) );
+}
+
+GpgME::Error Kleo::ChiasmusJob::exec() {
+ if ( const GpgME::Error err = setup() )
+ return mError = err;
+
+ if ( !mSymCryptRun->launch( mInput, KProcess::Block ) ) {
+ delete mSymCryptRun; mSymCryptRun = 0;
+ return mError = gpg_error( GPG_ERR_ENOENT ); // what else?
+ }
+
+ const GpgME::Error err = slotProcessExited( mSymCryptRun );
+ delete mSymCryptRun; mSymCryptRun = 0;
+ return err;
+}
+
+bool Kleo::ChiasmusJob::checkPreconditions() const {
+ return !mKey.isEmpty();
+}
+
+void Kleo::ChiasmusJob::slotCancel() {
+ if ( mSymCryptRun )
+ mSymCryptRun->kill();
+ mCanceled = true;
+}
+
+void Kleo::ChiasmusJob::slotTimeout() {
+ if ( !mSymCryptRun )
+ return;
+ mSymCryptRun->kill();
+ mTimeout = true;
+}
+
+
+void Kleo::ChiasmusJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( !mError )
+ return;
+ if ( mError.isCanceled() )
+ return;
+ const QString msg = ( mMode == Encrypt
+ ? i18n( "Encryption failed: %1" )
+ : i18n( "Decryption failed: %1" ) )
+ .arg( QString::fromLocal8Bit( mError.asString() ) );
+ if ( !mStderr.isEmpty() ) {
+ const QString details = i18n( "The following was received on stderr:\n%1" ).arg( mStderr );
+ KMessageBox::detailedError( parent, msg, details, caption );
+ } else {
+ KMessageBox::error( parent, msg, caption );
+ }
+}
+
+#include "chiasmusjob.moc"
diff --git a/certmanager/lib/backends/chiasmus/chiasmusjob.h b/certmanager/lib/backends/chiasmus/chiasmusjob.h
new file mode 100644
index 000000000..6393a0905
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmusjob.h
@@ -0,0 +1,116 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ chiasmusjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_CHIASMUSJOB_H__
+#define __KLEO_CHIASMUSJOB_H__
+
+#include "kleo/specialjob.h"
+
+#include <qstringlist.h>
+
+#include <gpgmepp/context.h>
+
+class KProcess;
+
+namespace Kleo {
+
+ class SymCryptRunProcessBase;
+
+ /**
+ @short SpecialJob for Chiasmus operations
+ */
+ class ChiasmusJob : public Kleo::SpecialJob {
+ Q_OBJECT
+ Q_ENUMS( Mode )
+ Q_PROPERTY( Mode mode READ mode )
+ Q_PROPERTY( QString key READ key WRITE setKey )
+ Q_PROPERTY( QString options READ options WRITE setOptions )
+ Q_PROPERTY( QByteArray input READ input WRITE setInput )
+ Q_PROPERTY( QByteArray result READ result )
+ public:
+ enum Mode {
+ Encrypt, Decrypt
+ };
+ ChiasmusJob( Mode op );
+ ~ChiasmusJob();
+
+ /*!\reimp SpecialJob */
+ GpgME::Error start();
+ /*!\reimp SpecialJob */
+ GpgME::Error exec();
+
+ /*!\reimp Kleo::Job */
+ void showErrorDialog( QWidget *, const QString & ) const;
+
+ Mode mode() const { return mMode; }
+
+ QString key() const { return mKey; }
+ void setKey( const QString & key ) { mKey = key; }
+
+ QString options() const { return mOptions; }
+ void setOptions( const QString & options ) { mOptions = options; }
+
+ QByteArray input() const { return mInput; }
+ void setInput( const QByteArray & input ) { mInput = input; }
+
+ //using SpecialJob::result;
+ QByteArray result() const { return mOutput; }
+
+ public slots:
+ void slotCancel();
+
+ private slots:
+ GpgME::Error slotProcessExited( KProcess * );
+ void slotTimeout();
+
+ private:
+ bool checkPreconditions() const;
+ GpgME::Error setup();
+ void showChiasmusOutput();
+
+ private:
+ SymCryptRunProcessBase * mSymCryptRun;
+ QString mKey;
+ QString mOptions;
+ QByteArray mInput, mOutput;
+ GpgME::Error mError;
+ QString mStderr;
+ bool mCanceled;
+ bool mTimeout;
+ const Mode mMode;
+ };
+
+}
+
+
+#endif // __KLEO_CHIASMUSJOB_H__
diff --git a/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp b/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp
new file mode 100644
index 000000000..2e3225492
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmuslibrary.cpp
@@ -0,0 +1,115 @@
+/*
+ chiasmuslibrary.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#include "chiasmuslibrary.h"
+
+#include "chiasmusbackend.h"
+
+#include "kleo/cryptoconfig.h"
+
+#include <klibloader.h>
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <qfile.h>
+
+#include <vector>
+#include <algorithm>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+Kleo::ChiasmusLibrary * Kleo::ChiasmusLibrary::self = 0;
+
+Kleo::ChiasmusLibrary::ChiasmusLibrary() : mXiaLibrary( 0 ) {
+ self = this;
+}
+
+Kleo::ChiasmusLibrary::~ChiasmusLibrary() {
+ //delete mXiaLibrary; // hmm, how to get rid of it, then?
+}
+
+Kleo::ChiasmusLibrary::main_func Kleo::ChiasmusLibrary::chiasmus( QString * reason ) const {
+ assert( ChiasmusBackend::instance() );
+ assert( ChiasmusBackend::instance()->config() );
+ const CryptoConfigEntry * lib = ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "lib" );
+ assert( lib );
+ const QString libfile = lib->urlValue().path();
+ if ( !mXiaLibrary )
+ mXiaLibrary = KLibLoader::self()->library( QFile::encodeName( libfile ) );
+ if ( !mXiaLibrary ) {
+ if ( reason )
+ *reason = i18n( "Failed to load %1: %2" )
+ .arg( libfile,KLibLoader::self()->lastErrorMessage() );
+ kdDebug(5150) << "ChiasmusLibrary: loading \"" << libfile
+ << "\" failed: " << KLibLoader::self()->lastErrorMessage() << endl;
+ return 0;
+ }
+ if ( !mXiaLibrary->hasSymbol( "Chiasmus" ) ) {
+ if ( reason )
+ *reason = i18n( "Failed to load %1: %2" )
+ .arg( libfile, i18n( "Library does not contain the symbol \"Chiasmus\"." ) );
+ kdDebug(5150) << "ChiasmusLibrary: loading \"" << libfile
+ << "\" failed: " << "Library does not contain the symbol \"Chiasmus\"." << endl;
+ return 0;
+ }
+ void * symbol = mXiaLibrary->symbol( "Chiasmus" );
+ assert( symbol );
+ return ( main_func )symbol;
+}
+
+namespace {
+ class ArgvProvider {
+ char ** mArgv;
+ int mArgc;
+ public:
+ ArgvProvider( const QValueVector<QCString> & args ) {
+ mArgv = new char * [args.size()];
+ for ( unsigned int i = 0 ; i < args.size() ; ++i )
+ mArgv[i] = strdup( args[i].data() );
+ }
+ ~ArgvProvider() {
+ std::for_each( mArgv, mArgv + mArgc, std::free );
+ delete[] mArgv;
+ }
+ char ** argv() const { return mArgv; }
+ };
+}
+
+int Kleo::ChiasmusLibrary::perform( const QValueVector<QCString> & args ) const {
+ if ( main_func func = chiasmus() )
+ return func( args.size(), ArgvProvider( args ).argv() );
+ else
+ return -1;
+}
diff --git a/certmanager/lib/backends/chiasmus/chiasmuslibrary.h b/certmanager/lib/backends/chiasmus/chiasmuslibrary.h
new file mode 100644
index 000000000..b04e162b4
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/chiasmuslibrary.h
@@ -0,0 +1,68 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ chiasmuslibrary.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_CHIASMUSLIBRARY_H__
+#define __KLEO_CHIASMUSLIBRARY_H__
+
+#include <qvaluevector.h>
+#include <qcstring.h>
+
+class KLibrary;
+
+namespace Kleo {
+
+ /**
+ @short small helper class to load xia.o through xia.so and make
+ the functionality available.
+ */
+ class ChiasmusLibrary {
+ ChiasmusLibrary();
+ ~ChiasmusLibrary();
+ public:
+ static const ChiasmusLibrary * instance();
+ static void deleteInstance();
+
+ int perform( const QValueVector<QCString> & args ) const;
+ private:
+ typedef int ( *main_func )( int, char** );
+ main_func chiasmus( QString * reason=0 ) const;
+
+ private:
+ static ChiasmusLibrary * self;
+ mutable KLibrary * mXiaLibrary;
+ };
+
+}
+
+
+#endif // __KLEO_CHIASMUSLIBRARY_H__
diff --git a/certmanager/lib/backends/chiasmus/config_data.c b/certmanager/lib/backends/chiasmus/config_data.c
new file mode 100644
index 000000000..bb3f33916
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/config_data.c
@@ -0,0 +1,95 @@
+/*
+ chiasmusbackend.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "config_data.h"
+
+#include "kleo/cryptoconfig.h" /* for the enum values */
+
+/*
+ This data structure uses C99 designated initializers. This is why
+ it's in a .c file, and not in a .cpp file. If your compiler doesn't
+ like this, just don't compile Chiasmus support, or live without the
+ wrapper option :) Sorry.
+*/
+
+#ifdef PATH
+# undef PATH
+#endif
+#ifdef HAVE_C99_INITIALIZERS
+# define PATH .path =
+#else
+# define PATH
+#endif
+
+#define I18N_NOOP(x) (x)
+
+const struct kleo_chiasmus_config_data kleo_chiasmus_config_entries[] = {
+ {
+ "path", I18N_NOOP( "Path to Chiasmus executable" ),
+ Level_Basic, ArgType_Path,
+ { PATH "/usr/local/bin/chiasmus" }, /* in the absence of C99, we assume path is first in the union here */
+ 0, 0, 1
+ },
+ {
+ "keydir", I18N_NOOP( "Key directory" ),
+ Level_Basic, ArgType_DirPath,
+ { PATH "~/.chiasmus/keys" },
+ 0, 0, 1 /* FIXME: should be a list */
+ },
+#ifdef HAVE_C99_INITIALIZERS
+ {
+ "show-output", I18N_NOOP( "Show output from chiasmus operations" ),
+ Level_Expert, ArgType_None,
+ { .boolean = { .value = 0, .numTimesSet = 0 } },
+ 0, 0, 1
+ },
+ {
+ "symcryptrun-class", I18N_NOOP( "SymCryptRun class to use" ),
+ Level_Expert, ArgType_String,
+ { .string = "confucius" },
+ 0, 0, 1
+ },
+ {
+ "timeout", I18N_NOOP( "Timeout in seconds for Chiasmus operations" ),
+ Level_Advanced, ArgType_UInt,
+ { .unsigned_integer = 60 },
+ 0, 0, 1
+ },
+#endif /* HAVE_C99_INITIALIZERS */
+};
+const unsigned int kleo_chiasmus_config_entries_dim
+ = sizeof kleo_chiasmus_config_entries / sizeof *kleo_chiasmus_config_entries ;
+
diff --git a/certmanager/lib/backends/chiasmus/config_data.h b/certmanager/lib/backends/chiasmus/config_data.h
new file mode 100644
index 000000000..c5c7b6c4e
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/config_data.h
@@ -0,0 +1,34 @@
+#ifndef __KLEO__CHIASMUS_CONFIG_DATA_H__
+#define __KLEO__CHIASMUS_CONFIG_DATA_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct kleo_chiasmus_config_data {
+ const char * name;
+ const char * description;
+ int level;
+ int type;
+ union {
+ const char * path; /* must be first, see config_data.c */
+ const char * string;
+ const char * url;
+ struct { unsigned int value : 1; unsigned int numTimesSet : 31; } boolean;
+ int integer;
+ unsigned int unsigned_integer;
+ } defaults;
+ unsigned int is_optional : 1;
+ unsigned int is_list : 1;
+ unsigned int is_runtime : 1;
+};
+
+extern const struct kleo_chiasmus_config_data kleo_chiasmus_config_entries[];
+extern const unsigned int kleo_chiasmus_config_entries_dim;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __KLEO__CHIASMUS_CONFIG_DATA_H__ */
+
diff --git a/certmanager/lib/backends/chiasmus/configure.in.in b/certmanager/lib/backends/chiasmus/configure.in.in
new file mode 100644
index 000000000..8cea56ad3
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/configure.in.in
@@ -0,0 +1,16 @@
+dnl
+dnl Check for C99 designated initializers:
+dnl
+AC_LANG_SAVE
+AC_LANG_C
+AC_MSG_CHECKING([for C99 designated initializers])
+AC_TRY_COMPILE([
+ union { int one; const char * two } foo = { .two = "Hello" };
+], [], [
+ AC_DEFINE(HAVE_C99_INITIALIZERS, 1, [Define to 1 if your C compiler support C99 designated initializers])
+ AC_MSG_RESULT([yes])
+], [
+ AC_MSG_RESULT([no])
+])
+
+AC_LANG_RESTORE
diff --git a/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp b/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp
new file mode 100644
index 000000000..a9de8d658
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/obtainkeysjob.cpp
@@ -0,0 +1,126 @@
+/*
+ obtainkeysjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "obtainkeysjob.h"
+
+#include "chiasmusbackend.h"
+
+#include "kleo/cryptoconfig.h"
+
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kshell.h>
+
+#include <qdir.h>
+#include <qstringlist.h>
+#include <qvariant.h>
+#include <qtimer.h>
+#include <qfileinfo.h>
+
+#include <gpg-error.h>
+
+#include <cassert>
+
+Kleo::ObtainKeysJob::ObtainKeysJob()
+ : SpecialJob( 0, 0 ),
+ mIndex( 0 ),
+ mCanceled( false )
+{
+ assert( ChiasmusBackend::instance() );
+ assert( ChiasmusBackend::instance()->config() );
+ const CryptoConfigEntry * keypaths =
+ ChiasmusBackend::instance()->config()->entry( "Chiasmus", "General", "keydir" );
+ assert( keypaths );
+ mKeyPaths = QStringList( keypaths->urlValue().path() );
+}
+
+Kleo::ObtainKeysJob::~ObtainKeysJob() {}
+
+GpgME::Error Kleo::ObtainKeysJob::start() {
+ QTimer::singleShot( 0, this, SLOT(slotPerform()) );
+ return mError = 0;
+}
+
+GpgME::Error Kleo::ObtainKeysJob::exec() {
+ slotPerform( false );
+ return mError;
+}
+
+void Kleo::ObtainKeysJob::slotCancel() {
+ mCanceled = true;
+}
+
+void Kleo::ObtainKeysJob::slotPerform() {
+ slotPerform( true );
+}
+
+void Kleo::ObtainKeysJob::slotPerform( bool async ) {
+ if ( mCanceled && !mError )
+ mError = gpg_error( GPG_ERR_CANCELED );
+ if ( mIndex >= mKeyPaths.size() || mError ) {
+ emit done();
+ emit SpecialJob::result( mError, QVariant( mResult ) );
+ return;
+ }
+
+ emit progress( i18n( "Scanning directory %1..." ).arg( mKeyPaths[mIndex] ),
+ mIndex, mKeyPaths.size() );
+
+ const QDir dir( KShell::tildeExpand( mKeyPaths[mIndex] ) );
+
+ if ( const QFileInfoList * xisFiles = dir.entryInfoList( "*.xis;*.XIS", QDir::Files ) )
+ for ( QFileInfoList::const_iterator it = xisFiles->begin(), end = xisFiles->end() ; it != end ; ++it )
+ if ( (*it)->isReadable() )
+ mResult.push_back( (*it)->absFilePath() );
+
+ ++mIndex;
+
+ if ( async )
+ QTimer::singleShot( 0, this, SLOT(slotPerform()) );
+ else
+ slotPerform( false );
+}
+
+void Kleo::ObtainKeysJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( !mError )
+ return;
+ if ( mError.isCanceled() )
+ return;
+ const QString msg = QString::fromUtf8( mError.asString() );
+ KMessageBox::error( parent, msg, caption );
+}
+
+#include "obtainkeysjob.moc"
diff --git a/certmanager/lib/backends/chiasmus/obtainkeysjob.h b/certmanager/lib/backends/chiasmus/obtainkeysjob.h
new file mode 100644
index 000000000..4b8392d46
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/obtainkeysjob.h
@@ -0,0 +1,101 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ obtainkeysjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_OBTAINKEYSJOB_H__
+#define __KLEO_OBTAINKEYSJOB_H__
+
+#include "kleo/specialjob.h"
+
+#include <qstringlist.h>
+
+#include <gpgmepp/context.h>
+
+namespace Kleo {
+
+ /**
+ @short SpecialJob for listing Chiasmus key files.
+
+ In the Chiasmus system, keys are mapped 1:1 to
+ files. Furthermore, we have to definition of the format of those
+ keys, so we cannot display more than the filename anyway. Due to
+ all of these limitations, we don't use KeyListJob here, but roll
+ our own interface.
+
+ The name of the function is x-obtain-keys. It takes no parameters.
+
+ To use, create an ObtainKeysJob instance like this:
+ <code>
+ Kleo::SpecialJob * job =
+ protocol->specialJob("x-obtain-keys", QMap<QString,QVariant>());
+ </code>
+
+ The resulting QVariant will contain a QStringList containing the
+ absolute filenames of the keys found in the configured key files.
+ */
+ class ObtainKeysJob : public Kleo::SpecialJob {
+ Q_OBJECT
+ Q_PROPERTY( QStringList result READ result )
+ public:
+ ObtainKeysJob();
+ ~ObtainKeysJob();
+
+ /*!\reimp SpecialJob */
+ GpgME::Error start();
+ /*!\reimp SpecialJob */
+ GpgME::Error exec();
+
+ /*!\reimp Kleo::Job */
+ void showErrorDialog( QWidget *, const QString & ) const;
+
+ //using SpecialJob::result;
+ QStringList result() const { return mResult; }
+
+ public slots:
+ void slotCancel();
+
+ private slots:
+ void slotPerform();
+ void slotPerform( bool async );
+
+ private:
+ GpgME::Error mError;
+ QStringList mKeyPaths;
+ unsigned int mIndex;
+ QStringList mResult;
+ bool mCanceled;
+ };
+
+}
+
+
+#endif // __KLEO_OBTAINKEYSJOB_H__
diff --git a/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp
new file mode 100644
index 000000000..1b8627252
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.cpp
@@ -0,0 +1,109 @@
+/*
+ symcryptrunbackend.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "symcryptrunprocessbase.h"
+
+#include <ktempfile.h>
+#include <kdebug.h>
+#include <kshell.h>
+
+#include <qtimer.h>
+#include <qfile.h>
+
+#include <cstring>
+
+Kleo::SymCryptRunProcessBase::SymCryptRunProcessBase( const QString & class_, const QString & program,
+ const QString & keyFile, const QString & options,
+ Operation mode,
+ QObject * parent, const char * name )
+ : KProcess( parent, name ),
+ mOperation( mode ), mOptions( options )
+{
+ *this << "symcryptrun"
+ << "--class" << class_
+ << "--program" << program
+ << "--keyfile" << keyFile
+ << ( mode == Encrypt ? "--encrypt" : "--decrypt" );
+}
+
+Kleo::SymCryptRunProcessBase::~SymCryptRunProcessBase() {}
+
+bool Kleo::SymCryptRunProcessBase::launch( const QByteArray & input, RunMode rm ) {
+ connect( this, SIGNAL(receivedStdout(KProcess*,char*,int)),
+ this, SLOT(slotReceivedStdout(KProcess*,char*,int)) );
+ connect( this, SIGNAL(receivedStderr(KProcess*,char*,int)),
+ this, SLOT(slotReceivedStderr(KProcess*,char*,int)) );
+ if ( rm == Block ) {
+ KTempFile tempfile;
+ tempfile.setAutoDelete( true );
+ if ( QFile * file = tempfile.file() )
+ file->writeBlock( input );
+ else
+ return false;
+ tempfile.close();
+ *this << "--input" << tempfile.name();
+ addOptions();
+ return KProcess::start( Block, All );
+ } else {
+ addOptions();
+ const bool ok = KProcess::start( rm, All );
+ if ( !ok )
+ return ok;
+ mInput = input.copy();
+ writeStdin( mInput.begin(), mInput.size() );
+ connect( this, SIGNAL(wroteStdin(KProcess*)), this, SLOT(closeStdin()) );
+ return true;
+ }
+}
+
+void Kleo::SymCryptRunProcessBase::addOptions() {
+ if ( !mOptions.isEmpty() )
+ {
+ const QStringList args = KShell::splitArgs( mOptions );
+ *this << "--" << args;
+ }
+}
+
+void Kleo::SymCryptRunProcessBase::slotReceivedStdout( KProcess * proc, char * buf, int len ) {
+ Q_ASSERT( proc == this );
+ const int oldsize = mOutput.size();
+ mOutput.resize( oldsize + len );
+ memcpy( mOutput.data() + oldsize, buf, len );
+}
+
+void Kleo::SymCryptRunProcessBase::slotReceivedStderr( KProcess * proc, char * buf, int len ) {
+ Q_ASSERT( proc == this );
+ if ( len > 0 )
+ mStderr += QString::fromLocal8Bit( buf, len );
+}
+
+#include "symcryptrunprocessbase.moc"
diff --git a/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h
new file mode 100644
index 000000000..d74db60cc
--- /dev/null
+++ b/certmanager/lib/backends/chiasmus/symcryptrunprocessbase.h
@@ -0,0 +1,81 @@
+/*
+ symcryptrunbackend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__
+#define __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__
+
+#include <kprocess.h>
+
+#include <qcstring.h>
+
+class QString;
+
+namespace Kleo {
+
+class SymCryptRunProcessBase : public KProcess {
+ Q_OBJECT
+public:
+ enum Operation {
+ Encrypt, Decrypt
+ };
+ SymCryptRunProcessBase( const QString & class_, const QString & program,
+ const QString & keyFile, const QString& options,
+ Operation op,
+ QObject * parent=0, const char * name=0 );
+ ~SymCryptRunProcessBase();
+
+ bool launch( const QByteArray & input, RunMode rm=NotifyOnExit );
+
+ const QByteArray & output() const { return mOutput; }
+ const QString & stdErr() const { return mStderr; }
+
+public slots:
+ /*! upgraded to slot */
+ void closeStdin() { KProcess::closeStdin(); }
+
+private slots:
+ void slotReceivedStdout( KProcess *, char *, int );
+ void slotReceivedStderr( KProcess *, char *, int );
+
+private:
+ void addOptions();
+
+ QByteArray mInput;
+ QByteArray mOutput;
+ QString mStderr;
+ const Operation mOperation;
+ QString mOptions;
+};
+
+}
+
+#endif // __KLEO_BACKEND_CHIASMUS__SYMCRYPTRUNPROCESSBASE_H__
diff --git a/certmanager/lib/backends/kpgp/Makefile.am b/certmanager/lib/backends/kpgp/Makefile.am
new file mode 100644
index 000000000..ad350f22c
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/Makefile.am
@@ -0,0 +1,12 @@
+INCLUDES = -I$(top_srcdir)/libkdenetwork \
+ -I$(top_srcdir)/certmanager/lib \
+ -I$(top_srcdir)/libkpgp \
+ $(GPGME_CFLAGS) $(all_includes)
+
+noinst_LTLIBRARIES = libkleopatra_backend_kpgp.la
+
+libkleopatra_backend_kpgp_la_SOURCES = \
+ kpgpbackendbase.cpp kpgpwrapper.cpp \
+ kpgpkeylistjob.cpp
+
+METASOURCES = AUTO
diff --git a/certmanager/lib/backends/kpgp/gpg1backend.h b/certmanager/lib/backends/kpgp/gpg1backend.h
new file mode 100644
index 000000000..f9413accf
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/gpg1backend.h
@@ -0,0 +1,52 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ gpg1backend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_GPG1BACKEND_H__
+#define __KLEO_GPG1BACKEND_H__
+
+#include "kpgpbackendbase.h"
+
+class QString;
+
+namespace Kleo {
+
+ class GPG1Backend : public KpgpBackendBase {
+ public:
+ QString name() const;
+ QString displayName() const;
+ };
+
+}
+
+
+#endif // __KLEO_GPG1BACKEND_H__
diff --git a/certmanager/lib/backends/kpgp/kpgpbackendbase.cpp b/certmanager/lib/backends/kpgp/kpgpbackendbase.cpp
new file mode 100644
index 000000000..2d4d17ab2
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpbackendbase.cpp
@@ -0,0 +1,111 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ kpgpbackendbase.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kpgpbackendbase.h"
+
+#include "pgp2backend.h"
+#include "pgp5backend.h"
+#include "pgp6backend.h"
+#include "gpg1backend.h"
+
+#include <klocale.h>
+
+#include <qstring.h>
+
+#include "kpgpwrapper.h"
+
+Kleo::KpgpBackendBase::KpgpBackendBase()
+ : Kleo::CryptoBackend(),
+ mOpenPGPProtocol( 0 )
+{
+}
+
+Kleo::KpgpBackendBase::~KpgpBackendBase()
+{
+ delete mOpenPGPProtocol; mOpenPGPProtocol = 0;
+}
+
+QString Kleo::GPG1Backend::name() const {
+ return GPG1_BACKEND_NAME;
+}
+
+QString Kleo::GPG1Backend::displayName() const {
+ return i18n("Kpgp/gpg");
+}
+
+QString Kleo::PGP2Backend::name() const {
+ return PGP2_BACKEND_NAME;
+}
+
+QString Kleo::PGP2Backend::displayName() const {
+ return i18n("Kpgp/pgp v2");
+}
+
+QString Kleo::PGP5Backend::name() const {
+ return PGP5_BACKEND_NAME;
+}
+
+QString Kleo::PGP5Backend::displayName() const {
+ return i18n("Kpgp/pgp v5");
+}
+
+QString Kleo::PGP6Backend::name() const {
+ return PGP6_BACKEND_NAME;
+}
+
+QString Kleo::PGP6Backend::displayName() const {
+ return i18n("Kpgp/pgp v6");
+}
+
+static const QString notSupported() {
+ return i18n("This backend does not support S/MIME");
+}
+
+bool Kleo::KpgpBackendBase::checkForOpenPGP( QString * /*reason*/ ) const {
+ return true;
+}
+
+bool Kleo::KpgpBackendBase::checkForSMIME( QString * reason ) const {
+ if ( reason ) *reason = notSupported();
+ return false;
+}
+
+Kleo::CryptoBackend::Protocol * Kleo::KpgpBackendBase::openpgp() const {
+ if ( !mOpenPGPProtocol )
+ if ( checkForOpenPGP() )
+ mOpenPGPProtocol = new KpgpWrapper( name() );
+ return mOpenPGPProtocol;
+}
diff --git a/certmanager/lib/backends/kpgp/kpgpbackendbase.h b/certmanager/lib/backends/kpgp/kpgpbackendbase.h
new file mode 100644
index 000000000..854e800c3
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpbackendbase.h
@@ -0,0 +1,73 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ kpgpbackendbase.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_KPGPBACKENDBASE_H__
+#define __KLEO_KPGPBACKENDBASE_H__
+
+#include "kleo/cryptobackend.h"
+
+#define GPG1_BACKEND_NAME "Kpgp/gpg1"
+#define PGP2_BACKEND_NAME "Kpgp/pgp2"
+#define PGP5_BACKEND_NAME "Kpgp/pgp5"
+#define PGP6_BACKEND_NAME "Kpgp/pgp6"
+
+namespace Kleo {
+ class CryptoConfig;
+}
+class QString;
+class KpgpWrapper;
+
+namespace Kleo {
+
+ class KpgpBackendBase : public Kleo::CryptoBackend {
+ public:
+ KpgpBackendBase();
+ ~KpgpBackendBase();
+
+ CryptoConfig * config() const { return 0; }
+ Protocol * openpgp() const;
+ Protocol * smime() const { return 0; }
+
+ bool supportsOpenPGP() const { return true; }
+ bool supportsSMIME() const { return false; }
+
+ bool checkForOpenPGP( QString * reason=0 ) const;
+ bool checkForSMIME( QString * reason=0 ) const;
+ private:
+ mutable KpgpWrapper * mOpenPGPProtocol;
+ };
+
+}
+
+
+#endif // __KLEO_KPGPBACKENDBASE_H__
diff --git a/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp b/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp
new file mode 100644
index 000000000..4c328adee
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpkeylistjob.cpp
@@ -0,0 +1,303 @@
+/*
+ kpgpkeylistjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kpgpkeylistjob.h"
+
+#include <kpgpbase.h>
+#include <kpgpkey.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/keylistresult.h>
+
+#include <gpgme.h>
+
+#include <qtimer.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+Kleo::KpgpKeyListJob::KpgpKeyListJob( Kpgp::Base * pgpBase )
+ : KeyListJob( 0, "Kleo::KpgpKeyListJob" ),
+ mPgpBase( pgpBase )
+{
+}
+
+Kleo::KpgpKeyListJob::~KpgpKeyListJob() {
+}
+
+// the following function is a verbatim copy from gpgme/key.c
+static char *
+set_user_id_part (char *tail, const char *buf, size_t len)
+{
+ while (len && (buf[len - 1] == ' ' || buf[len - 1] == '\t'))
+ len--;
+ for (; len; len--)
+ *tail++ = *buf++;
+ *tail++ = 0;
+ return tail;
+}
+
+// the following function is a verbatim copy from gpgme/key.c
+static void
+parse_user_id (char *src, char **name, char **email,
+ char **comment, char *tail)
+{
+ const char *start = NULL;
+ int in_name = 0;
+ int in_email = 0;
+ int in_comment = 0;
+
+ while (*src)
+ {
+ if (in_email)
+ {
+ if (*src == '<')
+ /* Not legal but anyway. */
+ in_email++;
+ else if (*src == '>')
+ {
+ if (!--in_email && !*email)
+ {
+ *email = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+ }
+ else if (in_comment)
+ {
+ if (*src == '(')
+ in_comment++;
+ else if (*src == ')')
+ {
+ if (!--in_comment && !*comment)
+ {
+ *comment = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+ }
+ else if (*src == '<')
+ {
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ in_name = 0;
+ }
+ in_email = 1;
+ start = src + 1;
+ }
+ else if (*src == '(')
+ {
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ in_name = 0;
+ }
+ in_comment = 1;
+ start = src + 1;
+ }
+ else if (!in_name && *src != ' ' && *src != '\t')
+ {
+ in_name = 1;
+ start = src;
+ }
+ src++;
+ }
+
+ if (in_name)
+ {
+ if (!*name)
+ {
+ *name = tail;
+ tail = set_user_id_part (tail, start, src - start);
+ }
+ }
+
+ /* Let unused parts point to an EOS. */
+ tail--;
+ if (!*name)
+ *name = tail;
+ if (!*email)
+ *email = tail;
+ if (!*comment)
+ *comment = tail;
+}
+
+gpgme_user_id_t KpgpUserID2GPGMEUserID( const Kpgp::UserID * kUserId )
+{
+ // inspired by _gpgme_key_append_name
+
+ const QCString text = kUserId->text().utf8();
+ const int src_len = text.length();
+
+ gpgme_user_id_t uid;
+ /* Allocate enough memory for the _gpgme_user_id struct, for the actual user
+ id (the text) and for the parsed version. */
+ uid = (gpgme_user_id_t) malloc( sizeof( *uid ) + 2 * src_len + 3 );
+ memset( uid, 0, sizeof *uid );
+ uid->revoked = kUserId->revoked();
+ uid->invalid = kUserId->invalid();
+ uid->validity = (gpgme_validity_t) kUserId->validity();
+
+ uid->uid = ((char *) uid) + sizeof (*uid);
+ char *dst = uid->uid;
+ memcpy( dst, text.data(), src_len + 1 );
+
+ dst += src_len + 1;
+ parse_user_id( uid->uid, &uid->name, &uid->email,
+ &uid->comment, dst );
+
+ return uid;
+}
+
+gpgme_subkey_t KpgpSubkey2GPGMESubKey( const Kpgp::Subkey * kSubkey )
+{
+ gpgme_subkey_t subkey;
+
+ const QCString fpr = kSubkey->fingerprint();
+ const unsigned int fpr_len = fpr.length();
+ const QCString keyId = kSubkey->longKeyID();
+
+ subkey = (gpgme_subkey_t) calloc( 1, sizeof( *subkey ) + fpr_len + 1 );
+ subkey->revoked = kSubkey->revoked();
+ subkey->expired = kSubkey->expired();
+ subkey->disabled = kSubkey->disabled();
+ subkey->invalid = kSubkey->invalid();
+ subkey->can_encrypt = kSubkey->canEncrypt();
+ subkey->can_sign = kSubkey->canSign();
+ subkey->can_certify = kSubkey->canCertify();
+ subkey->secret = kSubkey->secret();
+ subkey->pubkey_algo = (gpgme_pubkey_algo_t) kSubkey->keyAlgorithm();
+ subkey->length = kSubkey->keyLength();
+ subkey->keyid = subkey->_keyid;
+ memcpy( subkey->_keyid, keyId.data(), keyId.length() + 1 );
+ subkey->fpr = ((char *) subkey) + sizeof( *subkey );
+ memcpy( subkey->fpr, fpr.data(), fpr_len + 1 );
+ subkey->timestamp = kSubkey->creationDate();
+ subkey->expires = kSubkey->expirationDate();
+
+ return subkey;
+}
+
+gpgme_key_t KpgpKey2gpgme_key( const Kpgp::Key * kKey )
+{
+ gpgme_key_t key;
+
+ key = (gpgme_key_t) calloc( 1, sizeof( *key ) );
+ key->revoked = kKey->revoked();
+ key->expired = kKey->expired();
+ key->disabled = kKey->disabled();
+ key->invalid = kKey->invalid();
+ key->can_encrypt = kKey->canEncrypt();
+ key->can_sign = kKey->canSign();
+ key->can_certify = kKey->canCertify();
+ key->secret = kKey->secret();
+ key->protocol = GPGME_PROTOCOL_OpenPGP;
+ key->owner_trust = GPGME_VALIDITY_UNKNOWN; // FIXME?
+
+ Kpgp::UserIDList kUserIDs = kKey->userIDs();
+ for ( Kpgp::UserIDListIterator it( kUserIDs ); it.current(); ++it ) {
+ gpgme_user_id_t uid = KpgpUserID2GPGMEUserID( *it );
+ if ( !key->uids )
+ key->uids = uid;
+ if ( key->_last_uid )
+ key->_last_uid->next = uid;
+ key->_last_uid = uid;
+ }
+
+ Kpgp::SubkeyList kSubkeys = kKey->subkeys();
+ for ( Kpgp::SubkeyListIterator it( kSubkeys ); it.current(); ++it ) {
+ gpgme_subkey_t subkey = KpgpSubkey2GPGMESubKey( *it );
+ if (!key->subkeys)
+ key->subkeys = subkey;
+ if (key->_last_subkey)
+ key->_last_subkey->next = subkey;
+ key->_last_subkey = subkey;
+ }
+
+ return key;
+}
+
+GpgME::Error Kleo::KpgpKeyListJob::start( const QStringList & patterns,
+ bool secretOnly ) {
+ mPatterns = patterns;
+ mSecretOnly = secretOnly;
+ QTimer::singleShot( 0, this, SLOT( slotDoIt() ) );
+ return GpgME::Error( 0 );
+}
+
+void Kleo::KpgpKeyListJob::slotDoIt() {
+ std::vector<GpgME::Key> keys;
+ GpgME::KeyListResult res = exec( mPatterns, mSecretOnly, keys );
+ for ( std::vector<GpgME::Key>::const_iterator it = keys.begin();
+ it != keys.end(); ++it )
+ emit nextKey( *it );
+ emit done();
+ emit result( res );
+ deleteLater();
+}
+
+GpgME::KeyListResult Kleo::KpgpKeyListJob::exec( const QStringList & patterns,
+ bool secretOnly,
+ std::vector<GpgME::Key> & keys ) {
+ Kpgp::KeyList kKeys;
+ if ( secretOnly )
+ kKeys = mPgpBase->secretKeys( patterns );
+ else
+ kKeys = mPgpBase->publicKeys( patterns );
+
+ keys.clear();
+ for ( Kpgp::KeyListIterator it( kKeys ); it.current(); ++it ) {
+ keys.push_back( GpgME::Key( KpgpKey2gpgme_key(*it), true ) );
+ }
+
+ _gpgme_op_keylist_result res;
+ res.truncated = 0; // key list is not truncated
+ res._unused = 0;
+
+ return GpgME::KeyListResult( GpgME::Error( 0 ), res );
+}
+
+#include "kpgpkeylistjob.moc"
diff --git a/certmanager/lib/backends/kpgp/kpgpkeylistjob.h b/certmanager/lib/backends/kpgp/kpgpkeylistjob.h
new file mode 100644
index 000000000..779680c2d
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpkeylistjob.h
@@ -0,0 +1,79 @@
+/* -*- mode: C++ -*-
+ kpgpkeylistjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KPGPKEYLISTJOB_H__
+#define __KLEO_KPGPKEYLISTJOB_H__
+
+#include <kleo/keylistjob.h>
+
+#include <qstringlist.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kpgp {
+ class Base;
+}
+
+namespace Kleo {
+
+ class KpgpKeyListJob : public KeyListJob {
+ Q_OBJECT
+ public:
+ KpgpKeyListJob( Kpgp::Base * pgpBase );
+ ~KpgpKeyListJob();
+
+ /*! \reimp from KeyListJob */
+ GpgME::Error start( const QStringList & patterns, bool secretOnly );
+
+ /*! \reimp from KeyListJob */
+ GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly,
+ std::vector<GpgME::Key> & keys );
+
+ /*! \reimp from Job */
+ void slotCancel() { /*FIXME*/ }
+
+ private slots:
+ void slotDoIt();
+
+ private:
+ Kpgp::Base * mPgpBase;
+ QStringList mPatterns;
+ bool mSecretOnly;
+ };
+
+}
+
+#endif // __KLEO_KPGPKEYLISTJOB_H__
diff --git a/certmanager/lib/backends/kpgp/kpgpwrapper.cpp b/certmanager/lib/backends/kpgp/kpgpwrapper.cpp
new file mode 100644
index 000000000..20d885dd5
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpwrapper.cpp
@@ -0,0 +1,173 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ kpgpwrapper.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kpgpwrapper.h"
+
+#include "kpgpbackendbase.h"
+
+#include <kpgpbase.h>
+
+#include <backends/kpgp/kpgpkeylistjob.h>
+//#include <backends/kpgp/kpgpencryptjob.h>
+//#include <backends/kpgp/kpgpdecryptjob.h>
+//#include <backends/kpgp/kpgpsignjob.h>
+//#include <backends/kpgp/kpgpverifydetachedjob.h>
+//#include <backends/kpgp/kpgpverifyopaquejob.h>
+//#include <backends/kpgp/kpgpkeygenerationjob.h>
+//#include <backends/kpgp/kpgpimportjob.h>
+//#include <backends/kpgp/kpgpexportjob.h>
+//#include <backends/kpgp/kpgpsecretkeyexportjob.h>
+//#include <backends/kpgp/kpgpdownloadjob.h>
+//#include <backends/kpgp/kpgpdeletejob.h>
+//#include <backends/kpgp/kpgpsignencryptjob.h>
+//#include <backends/kpgp/kpgpdecryptverifyjob.h>
+//#include <backends/kpgp/kpgpcryptoconfig.h>
+
+KpgpWrapper::KpgpWrapper( const QString & name )
+ : mName( name ),
+ mPgpBase( 0 )
+{
+
+}
+
+KpgpWrapper::~KpgpWrapper()
+{
+
+}
+
+QString KpgpWrapper::name() const
+{
+ return mName;
+}
+
+QString KpgpWrapper::displayName() const
+{
+ return mName;
+}
+
+Kleo::KeyListJob * KpgpWrapper::keyListJob( bool /*remote*/,
+ bool /*includeSigs*/,
+ bool /*validate*/ ) const
+{
+ return new Kleo::KpgpKeyListJob( pgpBase() );
+}
+
+Kleo::EncryptJob * KpgpWrapper::encryptJob( bool /*armor*/,
+ bool /*textmode*/ ) const
+{
+ return 0;
+}
+
+Kleo::DecryptJob * KpgpWrapper::decryptJob() const
+{
+ return 0;
+}
+
+Kleo::SignJob * KpgpWrapper::signJob( bool /*armor*/, bool /*textMode*/ ) const
+{
+ return 0;
+}
+
+Kleo::VerifyDetachedJob * KpgpWrapper::verifyDetachedJob( bool /*textmode*/ ) const
+{
+ return 0;
+}
+
+Kleo::VerifyOpaqueJob * KpgpWrapper::verifyOpaqueJob( bool /*textmode*/ ) const
+{
+ return 0;
+}
+
+Kleo::KeyGenerationJob * KpgpWrapper::keyGenerationJob() const
+{
+ return 0;
+}
+
+Kleo::ImportJob * KpgpWrapper::importJob() const
+{
+ return 0;
+}
+
+Kleo::ExportJob * KpgpWrapper::publicKeyExportJob( bool /*armor*/ ) const
+{
+ return 0;
+}
+
+Kleo::ExportJob * KpgpWrapper::secretKeyExportJob( bool /*armor*/ ) const
+{
+ return 0;
+}
+
+Kleo::DownloadJob * KpgpWrapper::downloadJob( bool /*armor*/ ) const
+{
+ return 0;
+}
+
+Kleo::DeleteJob * KpgpWrapper::deleteJob() const
+{
+ return 0;
+}
+
+Kleo::SignEncryptJob * KpgpWrapper::signEncryptJob( bool /*armor*/,
+ bool /*textMode*/ ) const
+{
+ return 0;
+}
+
+Kleo::DecryptVerifyJob * KpgpWrapper::decryptVerifyJob( bool /*textmode*/ ) const
+{
+ return 0;
+}
+
+Kleo::RefreshKeysJob * KpgpWrapper::refreshKeysJob() const
+{
+ return 0;
+}
+
+Kpgp::Base * KpgpWrapper::pgpBase() const
+{
+ if ( !mPgpBase ) {
+ if ( name() == GPG1_BACKEND_NAME )
+ mPgpBase = new Kpgp::BaseG();
+ else if ( name() == PGP2_BACKEND_NAME )
+ mPgpBase = new Kpgp::Base2();
+ else if ( name() == PGP5_BACKEND_NAME )
+ mPgpBase = new Kpgp::Base5();
+ else if ( name() == PGP6_BACKEND_NAME )
+ mPgpBase = new Kpgp::Base6();
+ }
+ return mPgpBase;
+}
diff --git a/certmanager/lib/backends/kpgp/kpgpwrapper.h b/certmanager/lib/backends/kpgp/kpgpwrapper.h
new file mode 100644
index 000000000..182661ec4
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/kpgpwrapper.h
@@ -0,0 +1,97 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ kpgpwrapper.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Ingo Kloecker <kloecker@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KPGPWRAPPER_H__
+#define __KLEO_KPGPWRAPPER_H__
+
+#include <kleo/cryptobackend.h>
+
+#include <qstring.h>
+
+namespace Kleo {
+ class KeyListJob;
+ class EncryptJob;
+ class DecryptJob;
+ class SignJob;
+ class VerifyDetachedJob;
+ class VerifyOpaqueJob;
+ class KeyGenerationJob;
+ class ImportJob;
+ class ExportJob;
+ class DownloadJob;
+ class DeleteJob;
+ class SignEncryptJob;
+ class DecryptVerifyJob;
+ class CryptoConfig;
+ class RefreshKeysJob;
+}
+
+namespace Kpgp {
+ class Base;
+}
+
+class KpgpWrapper : public Kleo::CryptoBackend::Protocol {
+public:
+ KpgpWrapper( const QString & name );
+ ~KpgpWrapper();
+
+ QString name() const;
+
+ QString displayName() const;
+
+ Kleo::KeyListJob * keyListJob( bool remote=false, bool includeSigs=false,
+ bool validate=false ) const;
+ Kleo::EncryptJob * encryptJob( bool armor=false, bool textmode=false ) const;
+ Kleo::DecryptJob * decryptJob() const;
+ Kleo::SignJob * signJob( bool armor=false, bool textMode=false ) const;
+ Kleo::VerifyDetachedJob * verifyDetachedJob( bool textmode=false) const;
+ Kleo::VerifyOpaqueJob * verifyOpaqueJob( bool textmode=false ) const;
+ Kleo::KeyGenerationJob * keyGenerationJob() const;
+ Kleo::ImportJob * importJob() const;
+ Kleo::ExportJob * publicKeyExportJob( bool armor=false ) const;
+ Kleo::ExportJob * secretKeyExportJob( bool armor=false ) const;
+ Kleo::DownloadJob * downloadJob( bool armor=false ) const;
+ Kleo::DeleteJob * deleteJob() const;
+ Kleo::SignEncryptJob * signEncryptJob( bool armor=false,
+ bool textMode=false ) const;
+ Kleo::DecryptVerifyJob * decryptVerifyJob( bool textmode=false ) const;
+ Kleo::RefreshKeysJob * refreshKeysJob() const;
+
+private:
+ Kpgp::Base * pgpBase() const;
+
+private:
+ QString mName;
+ mutable Kpgp::Base * mPgpBase;
+};
+
+#endif // __KLEO_KPGPWRAPPER_H__
diff --git a/certmanager/lib/backends/kpgp/pgp2backend.h b/certmanager/lib/backends/kpgp/pgp2backend.h
new file mode 100644
index 000000000..fc053a20c
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/pgp2backend.h
@@ -0,0 +1,52 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ pgp2backend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_PGP2BACKEND_H__
+#define __KLEO_PGP2BACKEND_H__
+
+#include "kpgpbackendbase.h"
+
+class QString;
+
+namespace Kleo {
+
+ class PGP2Backend : public KpgpBackendBase {
+ public:
+ QString name() const;
+ QString displayName() const;
+ };
+
+}
+
+
+#endif // __KLEO_PGP2BACKEND_H__
diff --git a/certmanager/lib/backends/kpgp/pgp5backend.h b/certmanager/lib/backends/kpgp/pgp5backend.h
new file mode 100644
index 000000000..bf323b6fb
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/pgp5backend.h
@@ -0,0 +1,52 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ pgp5backend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_PGP5BACKEND_H__
+#define __KLEO_PGP5BACKEND_H__
+
+#include "kpgpbackendbase.h"
+
+class QString;
+
+namespace Kleo {
+
+ class PGP5Backend : public KpgpBackendBase {
+ public:
+ QString name() const;
+ QString displayName() const;
+ };
+
+}
+
+
+#endif // __KLEO_PGP5BACKEND_H__
diff --git a/certmanager/lib/backends/kpgp/pgp6backend.h b/certmanager/lib/backends/kpgp/pgp6backend.h
new file mode 100644
index 000000000..827cf239b
--- /dev/null
+++ b/certmanager/lib/backends/kpgp/pgp6backend.h
@@ -0,0 +1,52 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ pgp6backend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_PGP6BACKEND_H__
+#define __KLEO_PGP6BACKEND_H__
+
+#include "kpgpbackendbase.h"
+
+class QString;
+
+namespace Kleo {
+
+ class PGP6Backend : public KpgpBackendBase {
+ public:
+ QString name() const;
+ QString displayName() const;
+ };
+
+}
+
+
+#endif // __KLEO_PGP6BACKEND_H__
diff --git a/certmanager/lib/backends/qgpgme/Makefile.am b/certmanager/lib/backends/qgpgme/Makefile.am
new file mode 100644
index 000000000..a7336a029
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/Makefile.am
@@ -0,0 +1,34 @@
+#KDE_OPTIONS = nofinal
+
+INCLUDES = -I$(top_srcdir)/libkdenetwork \
+ -I$(top_srcdir)/certmanager/lib \
+ $(GPGME_CFLAGS) $(all_includes)
+
+noinst_LTLIBRARIES = libkleopatra_backend_qgpgme.la
+
+libkleopatra_backend_qgpgme_la_SOURCES = \
+ gnupgprocessbase.cpp \
+ qgpgmeprogresstokenmapper.cpp \
+ \
+ qgpgmebackend.cpp \
+ \
+ qgpgmejob.cpp \
+ \
+ qgpgmekeylistjob.cpp \
+ qgpgmekeygenerationjob.cpp \
+ qgpgmeimportjob.cpp \
+ qgpgmeexportjob.cpp \
+ qgpgmesecretkeyexportjob.cpp \
+ qgpgmedownloadjob.cpp \
+ qgpgmedeletejob.cpp \
+ qgpgmeencryptjob.cpp \
+ qgpgmedecryptjob.cpp \
+ qgpgmesignjob.cpp \
+ qgpgmeverifydetachedjob.cpp \
+ qgpgmeverifyopaquejob.cpp \
+ qgpgmesignencryptjob.cpp \
+ qgpgmedecryptverifyjob.cpp \
+ qgpgmecryptoconfig.cpp \
+ qgpgmerefreshkeysjob.cpp
+
+METASOURCES = AUTO
diff --git a/certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp b/certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp
new file mode 100644
index 000000000..2d3ca7409
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/gnupgprocessbase.cpp
@@ -0,0 +1,198 @@
+/*
+ gnupgprocessbase.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "gnupgprocessbase.h"
+
+#include <kdebug.h>
+#include <kurl.h>
+
+#include <qsocketnotifier.h>
+#include <qtextcodec.h>
+#include <qstringlist.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+struct Kleo::GnuPGProcessBase::Private {
+ Private() : useStatusFD( false ), statnot( 0 ) {
+ statusFD[0] = statusFD[1] = -1;
+ }
+
+ bool useStatusFD;
+ int statusFD[2];
+ QSocketNotifier * statnot;
+ QCString statusBuffer;
+};
+
+
+Kleo::GnuPGProcessBase::GnuPGProcessBase( QObject * parent, const char * name )
+ : KProcess( parent, name )
+{
+ d = new Private();
+}
+
+Kleo::GnuPGProcessBase::~GnuPGProcessBase() {
+ delete d; d = 0;
+}
+
+void Kleo::GnuPGProcessBase::setUseStatusFD( bool use ) {
+ assert( d );
+ d->useStatusFD = use;
+}
+
+bool Kleo::GnuPGProcessBase::start( RunMode runmode, Communication comm ) {
+ if ( d->useStatusFD ) {
+ // set up the status-fd. This should be in setupCommunication(),
+ // but then it's too late: we need the fd of the pipe to pass it
+ // as argument to the --status-fd option:
+ // PENDING(marc) find out why KProcess uses both pipe() and socketpair()...
+ if ( ::pipe( d->statusFD ) < 0 ) {
+ kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::start: pipe(2) failed: " << perror << endl;
+ return false;
+ }
+ ::fcntl( d->statusFD[0], F_SETFD, FD_CLOEXEC );
+ ::fcntl( d->statusFD[1], F_SETFD, FD_CLOEXEC );
+ if ( !arguments.empty() ) {
+ QValueList<QCString>::iterator it = arguments.begin();
+ ++it;
+ arguments.insert( it, "--status-fd" );
+ char buf[25];
+ sprintf( buf, "%d", d->statusFD[1] );
+ arguments.insert( it, buf );
+ arguments.insert( it, "--no-tty" );
+ //arguments.insert( it, "--enable-progress-filter" ); // gpgsm doesn't know this
+ }
+ }
+ return KProcess::start( runmode, comm );
+}
+
+int Kleo::GnuPGProcessBase::setupCommunication( Communication comm ) {
+ if ( int ok = KProcess::setupCommunication( comm ) )
+ return ok;
+ if ( d->useStatusFD ) {
+ // base class impl returned error, so close our fd's, too
+ ::close( d->statusFD[0] );
+ ::close( d->statusFD[1] );
+ d->statusFD[0] = d->statusFD[1] = -1;
+ }
+ return 0; // Error
+}
+
+int Kleo::GnuPGProcessBase::commSetupDoneP() {
+ if ( d->useStatusFD ) {
+ ::close( d->statusFD[1] ); // close the input end of the pipe, we're the reader
+ d->statnot = new QSocketNotifier( d->statusFD[0], QSocketNotifier::Read, this );
+ connect( d->statnot, SIGNAL(activated(int)), SLOT(slotChildStatus(int)) );
+ }
+ return KProcess::commSetupDoneP();
+}
+
+int Kleo::GnuPGProcessBase::commSetupDoneC() {
+ if ( d->useStatusFD )
+ ::fcntl( d->statusFD[1], F_SETFD, 0 );
+ return KProcess::commSetupDoneC();
+}
+
+void Kleo::GnuPGProcessBase::slotChildStatus( int fd ) {
+ if ( !childStatus(fd) )
+ closeStatus();
+}
+
+bool Kleo::GnuPGProcessBase::closeStatus() {
+ if ( !d->useStatusFD )
+ return false;
+ d->useStatusFD = false;
+ delete d->statnot; d->statnot = 0;
+ ::close( d->statusFD[0] ); d->statusFD[0] = -1;
+ return true;
+}
+
+int Kleo::GnuPGProcessBase::childStatus( int fd ) {
+ char buf[1024];
+ const int len = ::read( fd, buf, sizeof(buf)-1 );
+ if ( len > 0 ) {
+ buf[len] = 0;
+ d->statusBuffer += buf;
+ parseStatusOutput();
+ }
+ return len;
+}
+
+static QString fromHexEscapedUtf8( const QCString & str ) {
+ return KURL::decode_string( str.data(), 106 /* utf-8 */ );
+}
+
+void Kleo::GnuPGProcessBase::parseStatusOutput() {
+ static const char startToken[] = "[GNUPG:] ";
+ static const int startTokenLen = sizeof startToken / sizeof *startToken - 1;
+
+ int lineStart = 0;
+ for ( int lineEnd = d->statusBuffer.find( '\n' ) ; lineEnd >= 0 ; lineEnd = d->statusBuffer.find( '\n', lineStart = lineEnd+1 ) ) {
+ // get next line:
+ const QCString line = d->statusBuffer.mid( lineStart, lineEnd - lineStart ).stripWhiteSpace();
+ if ( line.isEmpty() )
+ continue;
+ // check status token
+ if ( line.left( startTokenLen ) != startToken ) {
+ kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line doesn't begin with \""
+ << startToken << "\"" << endl;
+ continue;
+ }
+ // remove status token:
+ const QCString command = line.mid( startTokenLen ).simplifyWhiteSpace() + ' ';
+ if ( command == " " ) {
+ kdDebug( 5150 ) << "Kleo::GnuPGProcessBase::childStatus: status-fd protocol error: line without content." << endl;
+ continue;
+ }
+ // split into base and args
+ QString cmd;
+ QStringList args;
+ int tagStart = 0;
+ for ( int tagEnd = command.find( ' ' ) ; tagEnd >= 0 ; tagEnd = command.find( ' ', tagStart = tagEnd+1 ) ) {
+ const QCString tag = command.mid( tagStart, tagEnd - tagStart );
+ if ( cmd.isNull() )
+ cmd = fromHexEscapedUtf8( tag );
+ else
+ args.push_back( fromHexEscapedUtf8( tag ) );
+ }
+ emit status( this, cmd, args );
+ }
+ d->statusBuffer = d->statusBuffer.mid( lineStart );
+}
+
+void Kleo::GnuPGProcessBase::virtual_hook( int id, void * data ) {
+ KProcess::virtual_hook( id, data );
+}
+
+#include "gnupgprocessbase.moc"
diff --git a/certmanager/lib/backends/qgpgme/gnupgprocessbase.h b/certmanager/lib/backends/qgpgme/gnupgprocessbase.h
new file mode 100644
index 000000000..73e31e295
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/gnupgprocessbase.h
@@ -0,0 +1,91 @@
+/*
+ gnupgprocessbase.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_GNUPGPROCESSBASE_H__
+#define __KLEO_GNUPGPROCESSBASE_H__
+
+#include <kprocess.h>
+
+namespace Kleo {
+
+ /**
+ * @short a base class for GPG and GPGSM processes.
+ *
+ * This KProcess subclass implements the status-fd handling common
+ * to GPG and GPGSM.
+ *
+ * @author Marc Mutz <mutz@kde.org>
+ */
+ class GnuPGProcessBase : public KProcess {
+ Q_OBJECT
+ public:
+ GnuPGProcessBase( QObject * parent=0, const char * name=0 );
+ ~GnuPGProcessBase();
+
+ void setUseStatusFD( bool use );
+
+ /*! reimplementation */
+ bool start( RunMode runmode, Communication comm );
+
+ bool closeStatus();
+
+ signals:
+ void status( Kleo::GnuPGProcessBase * proc, const QString & type, const QStringList & args );
+
+ protected:
+ /*! reimplementation */
+ int setupCommunication( Communication comm );
+ /*! reimplementation */
+ int commSetupDoneP();
+ /*! reimplementation */
+ int commSetupDoneC();
+
+ int childStatus( int fd );
+
+
+ private slots:
+ void slotChildStatus( int fd );
+
+ private:
+ void parseStatusOutput();
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ /*! reimplementation */
+ void virtual_hook( int id, void * data );
+ };
+
+}
+
+#endif // __KLEO_GNUPGPROCESSBASE_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp b/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp
new file mode 100644
index 000000000..8256522ae
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmebackend.cpp
@@ -0,0 +1,153 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ qgpgmebackend.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmebackend.h"
+
+#include "qgpgmecryptoconfig.h"
+#include "cryptplugwrapper.h"
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/engineinfo.h>
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <qfile.h>
+#include <qstring.h>
+
+Kleo::QGpgMEBackend::QGpgMEBackend()
+ : Kleo::CryptoBackend(),
+ mCryptoConfig( 0 ),
+ mOpenPGPProtocol( 0 ),
+ mSMIMEProtocol( 0 )
+{
+ GpgME::initializeLibrary();
+}
+
+Kleo::QGpgMEBackend::~QGpgMEBackend() {
+ delete mCryptoConfig; mCryptoConfig = 0;
+ delete mOpenPGPProtocol; mOpenPGPProtocol = 0;
+ delete mSMIMEProtocol; mSMIMEProtocol = 0;
+}
+
+QString Kleo::QGpgMEBackend::name() const {
+ return "gpgme";
+}
+
+QString Kleo::QGpgMEBackend::displayName() const {
+ return i18n( "GpgME" );
+}
+
+Kleo::CryptoConfig * Kleo::QGpgMEBackend::config() const {
+ if ( !mCryptoConfig ) {
+ static bool hasGpgConf = !KStandardDirs::findExe( "gpgconf" ).isEmpty();
+ if ( hasGpgConf )
+ mCryptoConfig = new QGpgMECryptoConfig();
+ }
+ return mCryptoConfig;
+}
+
+static bool check( GpgME::Context::Protocol proto, QString * reason ) {
+ if ( !GpgME::checkEngine( proto ) )
+ return true;
+ if ( !reason )
+ return false;
+ // error, check why:
+ const GpgME::EngineInfo ei = GpgME::engineInfo( proto );
+ if ( ei.isNull() )
+ *reason = i18n("GPGME was compiled without support for %1.").arg( proto == GpgME::Context::CMS ? "S/MIME" : "OpenPGP" );
+ else if ( ei.fileName() && !ei.version() )
+ *reason = i18n("Engine %1 is not installed properly.").arg( QFile::decodeName( ei.fileName() ) );
+ else if ( ei.fileName() && ei.version() && ei.requiredVersion() )
+ *reason = i18n("Engine %1 version %2 installed, "
+ "but at least version %3 is required.")
+ .arg( QFile::decodeName( ei.fileName() ), ei.version(), ei.requiredVersion() );
+ else
+ *reason = i18n("Unknown problem with engine for protocol %1.").arg( proto == GpgME::Context::CMS ? "S/MIME" : "OpenPGP" );
+ return false;
+}
+
+bool Kleo::QGpgMEBackend::checkForOpenPGP( QString * reason ) const {
+ return check( GpgME::Context::OpenPGP, reason );
+}
+
+bool Kleo::QGpgMEBackend::checkForSMIME( QString * reason ) const {
+ return check( GpgME::Context::CMS, reason );
+}
+
+bool Kleo::QGpgMEBackend::checkForProtocol( const char * name, QString * reason ) const {
+ if ( qstricmp( name, OpenPGP ) == 0 )
+ return check( GpgME::Context::OpenPGP, reason );
+ if ( qstricmp( name, SMIME ) == 0 )
+ return check( GpgME::Context::CMS, reason );
+ if ( reason )
+ *reason = i18n( "Unsupported protocol \"%1\"" ).arg( name );
+ return false;
+}
+
+Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::openpgp() const {
+ if ( !mOpenPGPProtocol )
+ if ( checkForOpenPGP() )
+ mOpenPGPProtocol = new CryptPlugWrapper( "gpg", "openpgp" );
+ return mOpenPGPProtocol;
+}
+
+Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::smime() const {
+ if ( !mSMIMEProtocol )
+ if ( checkForSMIME() )
+ mSMIMEProtocol = new CryptPlugWrapper( "gpgsm", "smime" );
+ return mSMIMEProtocol;
+}
+
+Kleo::CryptoBackend::Protocol * Kleo::QGpgMEBackend::protocol( const char * name ) const {
+ if ( qstricmp( name, OpenPGP ) == 0 )
+ return openpgp();
+ if ( qstricmp( name, SMIME ) == 0 )
+ return smime();
+ return 0;
+}
+
+bool Kleo::QGpgMEBackend::supportsProtocol( const char * name ) const {
+ return qstricmp( name, OpenPGP ) == 0 || qstricmp( name, SMIME ) == 0;
+}
+
+const char * Kleo::QGpgMEBackend::enumerateProtocols( int i ) const {
+ switch ( i ) {
+ case 0: return OpenPGP;
+ case 1: return SMIME;
+ default: return 0;
+ }
+}
diff --git a/certmanager/lib/backends/qgpgme/qgpgmebackend.h b/certmanager/lib/backends/qgpgme/qgpgmebackend.h
new file mode 100644
index 000000000..fae2dd68e
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmebackend.h
@@ -0,0 +1,82 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ qgpgmebackend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_QGPGMEBACKEND_H__
+#define __KLEO_QGPGMEBACKEND_H__
+
+#include "kleo/cryptobackend.h"
+
+class CryptPlugWrapper;
+
+namespace Kleo {
+ class CryptoConfig;
+}
+class QGpgMECryptoConfig;
+class QString;
+
+namespace Kleo {
+
+ class QGpgMEBackend : public Kleo::CryptoBackend {
+ public:
+ QGpgMEBackend();
+ ~QGpgMEBackend();
+
+ QString name() const;
+ QString displayName() const;
+
+ CryptoConfig * config() const;
+
+ Protocol * openpgp() const;
+ Protocol * smime() const;
+ Protocol * protocol( const char * name ) const;
+
+ bool checkForOpenPGP( QString * reason=0 ) const;
+ bool checkForSMIME( QString * reason=0 ) const;
+ bool checkForProtocol( const char * name, QString * reason ) const;
+
+ bool supportsOpenPGP() const { return true; }
+ bool supportsSMIME() const { return true; }
+ bool supportsProtocol( const char * name ) const;
+
+ const char * enumerateProtocols( int i ) const;
+
+ private:
+ mutable QGpgMECryptoConfig * mCryptoConfig;
+ mutable CryptPlugWrapper * mOpenPGPProtocol;
+ mutable CryptPlugWrapper * mSMIMEProtocol;
+ };
+
+}
+
+
+#endif // __KLEO_QGPGMEBACKEND_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp
new file mode 100644
index 000000000..86eab99b4
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.cpp
@@ -0,0 +1,837 @@
+/*
+ qgpgmecryptoconfig.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "qgpgmecryptoconfig.h"
+#include <kdebug.h>
+#include <kprocio.h>
+#include <errno.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+
+#include <assert.h>
+#include <ktempfile.h>
+#include <qfile.h>
+#include <stdlib.h>
+#include <qtextcodec.h>
+
+// Just for the Q_ASSERT in the dtor. Not thread-safe, but who would
+// have 2 threads talking to gpgconf anyway? :)
+static bool s_duringClear = false;
+
+static const int GPGCONF_FLAG_GROUP = 1;
+static const int GPGCONF_FLAG_OPTIONAL = 2;
+static const int GPGCONF_FLAG_LIST = 4;
+static const int GPGCONF_FLAG_RUNTIME = 8;
+static const int GPGCONF_FLAG_DEFAULT = 16; // fixed default value available
+static const int GPGCONF_FLAG_DEFAULT_DESC = 32; // runtime default value available
+static const int GPGCONF_FLAG_NOARG_DESC = 64; // option with optional arg; special meaning if no arg set
+static const int GPGCONF_FLAG_NO_CHANGE = 128; // readonly
+// Change size of mFlags bitfield if adding new values here
+
+QGpgMECryptoConfig::QGpgMECryptoConfig()
+ : mComponents( 7 ), mParsed( false )
+{
+ mComponents.setAutoDelete( true );
+}
+
+QGpgMECryptoConfig::~QGpgMECryptoConfig()
+{
+}
+
+void QGpgMECryptoConfig::runGpgConf( bool showErrors )
+{
+ // Run gpgconf --list-components to make the list of components
+
+ KProcIO proc( QTextCodec::codecForName( "utf8" ) );
+ proc << "gpgconf"; // must be in the PATH
+ proc << "--list-components";
+
+ QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ),
+ this, SLOT( slotCollectStdOut(KProcIO*) ) );
+
+ // run the process:
+ int rc = 0;
+ if ( !proc.start( KProcess::Block ) )
+ rc = -1;
+ else
+ rc = ( proc.normalExit() ) ? proc.exitStatus() : -2 ;
+
+ // handle errors, if any (and if requested)
+ if ( showErrors && rc != 0 ) {
+ QString wmsg = i18n("<qt>Failed to execute gpgconf:<br>%1</qt>");
+ if ( rc == -1 )
+ wmsg = wmsg.arg( i18n( "program not found" ) );
+ else if ( rc == -2 )
+ wmsg = wmsg.arg( i18n( "program cannot be executed" ) );
+ else
+ wmsg = wmsg.arg( strerror(rc) );
+ kdWarning(5150) << wmsg << endl; // to see it from test_cryptoconfig.cpp
+ KMessageBox::error(0, wmsg);
+ }
+ mParsed = true;
+}
+
+void QGpgMECryptoConfig::slotCollectStdOut( KProcIO* proc )
+{
+ QString line;
+ int result;
+ while( ( result = proc->readln(line) ) != -1 ) {
+ //kdDebug(5150) << "GOT LINE:" << line << endl;
+ // Format: NAME:DESCRIPTION
+ QStringList lst = QStringList::split( ':', line, true );
+ if ( lst.count() >= 2 ) {
+ mComponents.insert( lst[0], new QGpgMECryptoConfigComponent( this, lst[0], lst[1] ) );
+ } else {
+ kdWarning(5150) << "Parse error on gpgconf --list-components output: " << line << endl;
+ }
+ }
+}
+
+QStringList QGpgMECryptoConfig::componentList() const
+{
+ if ( !mParsed )
+ const_cast<QGpgMECryptoConfig*>( this )->runGpgConf( true );
+ QDictIterator<QGpgMECryptoConfigComponent> it( mComponents );
+ QStringList names;
+ for( ; it.current(); ++it )
+ names.push_back( it.currentKey() );
+ return names;
+}
+
+Kleo::CryptoConfigComponent* QGpgMECryptoConfig::component( const QString& name ) const
+{
+ if ( !mParsed )
+ const_cast<QGpgMECryptoConfig*>( this )->runGpgConf( false );
+ return mComponents.find( name );
+}
+
+void QGpgMECryptoConfig::sync( bool runtime )
+{
+ QDictIterator<QGpgMECryptoConfigComponent> it( mComponents );
+ for( ; it.current(); ++it )
+ it.current()->sync( runtime );
+}
+
+void QGpgMECryptoConfig::clear()
+{
+ s_duringClear = true;
+ mComponents.clear();
+ s_duringClear = false;
+ mParsed = false; // next call to componentList/component will need to run gpgconf again
+}
+
+////
+
+QGpgMECryptoConfigComponent::QGpgMECryptoConfigComponent( QGpgMECryptoConfig*, const QString& name, const QString& description )
+ : mGroups( 7 ), mName( name ), mDescription( description )
+{
+ mGroups.setAutoDelete( true );
+ runGpgConf();
+}
+
+QGpgMECryptoConfigComponent::~QGpgMECryptoConfigComponent()
+{
+}
+
+void QGpgMECryptoConfigComponent::runGpgConf()
+{
+ // Run gpgconf --list-options <component>, and create all groups and entries for that component
+
+ KProcIO proc( QTextCodec::codecForName( "utf8" ) );
+ proc << "gpgconf"; // must be in the PATH
+ proc << "--list-options";
+ proc << mName;
+
+ //kdDebug(5150) << "Running gpgconf --list-options " << mName << endl;
+
+ QObject::connect( &proc, SIGNAL( readReady(KProcIO*) ),
+ this, SLOT( slotCollectStdOut(KProcIO*) ) );
+ mCurrentGroup = 0;
+
+ // run the process:
+ int rc = 0;
+ if ( !proc.start( KProcess::Block ) )
+ rc = -1;
+ else
+ rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
+
+ if( rc != 0 ) // can happen when using the wrong version of gpg...
+ kdWarning(5150) << "Running 'gpgconf --list-options " << mName << "' failed. " << strerror( rc ) << ", but try that command to see the real output" << endl;
+ else {
+ if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() ) // only add non-empty groups
+ mGroups.insert( mCurrentGroupName, mCurrentGroup );
+ }
+}
+
+void QGpgMECryptoConfigComponent::slotCollectStdOut( KProcIO* proc )
+{
+ QString line;
+ int result;
+ while( ( result = proc->readln(line) ) != -1 ) {
+ //kdDebug(5150) << "GOT LINE:" << line << endl;
+ // Format: NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE
+ const QStringList lst = QStringList::split( ':', line, true );
+ if ( lst.count() >= 10 ) {
+ const int flags = lst[1].toInt();
+ const int level = lst[2].toInt();
+ if ( level > 2 ) // invisible or internal -> skip it;
+ continue;
+ if ( flags & GPGCONF_FLAG_GROUP ) {
+ if ( mCurrentGroup && !mCurrentGroup->mEntries.isEmpty() ) // only add non-empty groups
+ mGroups.insert( mCurrentGroupName, mCurrentGroup );
+ //else
+ // kdDebug(5150) << "Discarding empty group " << mCurrentGroupName << endl;
+ mCurrentGroup = new QGpgMECryptoConfigGroup( lst[0], lst[3], level );
+ mCurrentGroupName = lst[0];
+ } else {
+ // normal entry
+ if ( !mCurrentGroup ) { // first toplevel entry -> create toplevel group
+ mCurrentGroup = new QGpgMECryptoConfigGroup( "<nogroup>", QString::null, 0 );
+ mCurrentGroupName = "<nogroup>";
+ }
+ mCurrentGroup->mEntries.insert( lst[0], new QGpgMECryptoConfigEntry( lst ) );
+ }
+ } else {
+ // This happens on lines like
+ // dirmngr[31465]: error opening `/home/dfaure/.gnupg/dirmngr_ldapservers.conf': No such file or directory
+ // so let's not bother the user with it.
+ //kdWarning(5150) << "Parse error on gpgconf --list-options output: " << line << endl;
+ }
+ }
+}
+
+QStringList QGpgMECryptoConfigComponent::groupList() const
+{
+ QDictIterator<QGpgMECryptoConfigGroup> it( mGroups );
+ QStringList names;
+ for( ; it.current(); ++it )
+ names.push_back( it.currentKey() );
+ return names;
+}
+
+Kleo::CryptoConfigGroup* QGpgMECryptoConfigComponent::group(const QString& name ) const
+{
+ return mGroups.find( name );
+}
+
+void QGpgMECryptoConfigComponent::sync( bool runtime )
+{
+ KTempFile tmpFile;
+ tmpFile.setAutoDelete( true );
+
+ QValueList<QGpgMECryptoConfigEntry *> dirtyEntries;
+
+ // Collect all dirty entries
+ QDictIterator<QGpgMECryptoConfigGroup> groupit( mGroups );
+ for( ; groupit.current(); ++groupit ) {
+ QDictIterator<QGpgMECryptoConfigEntry> it( groupit.current()->mEntries );
+ for( ; it.current(); ++it ) {
+ if ( it.current()->isDirty() ) {
+ // OK, we can set it.currentKey() to it.current()->outputString()
+ QString line = it.currentKey();
+ if ( it.current()->isSet() ) { // set option
+ line += ":0:";
+ line += it.current()->outputString();
+ } else { // unset option
+ line += ":16:";
+ }
+ line += '\n';
+ QCString line8bit = line.utf8(); // encode with utf8, and KProcIO uses utf8 when reading.
+ tmpFile.file()->writeBlock( line8bit.data(), line8bit.size()-1 /*no 0*/ );
+ dirtyEntries.append( it.current() );
+ }
+ }
+ }
+ tmpFile.close();
+ if ( dirtyEntries.isEmpty() )
+ return;
+
+ // Call gpgconf --change-options <component>
+ QString commandLine = "gpgconf";
+ if ( runtime )
+ commandLine += " --runtime";
+ commandLine += " --change-options ";
+ commandLine += KProcess::quote( mName );
+ commandLine += " < ";
+ commandLine += KProcess::quote( tmpFile.name() );
+
+ //kdDebug(5150) << commandLine << endl;
+ //system( QCString( "cat " ) + tmpFile.name().latin1() ); // DEBUG
+
+ KProcess proc;
+ proc.setUseShell( true );
+ proc << commandLine;
+
+ // run the process:
+ int rc = 0;
+ if ( !proc.start( KProcess::Block ) )
+ rc = -1;
+ else
+ rc = ( proc.normalExit() ) ? proc.exitStatus() : -1 ;
+
+ if ( rc == -1 )
+ {
+ QString wmsg = i18n( "Could not start gpgconf\nCheck that gpgconf is in the PATH and that it can be started" );
+ kdWarning(5150) << wmsg << endl;
+ KMessageBox::error(0, wmsg);
+ }
+ else if( rc != 0 ) // Happens due to bugs in gpgconf (e.g. issues 104/115)
+ {
+ QString wmsg = i18n( "Error from gpgconf while saving configuration: %1" ).arg( QString::fromLocal8Bit( strerror( rc ) ) );
+ kdWarning(5150) << k_funcinfo << ":" << strerror( rc ) << endl;
+ KMessageBox::error(0, wmsg);
+ }
+ else
+ {
+ QValueList<QGpgMECryptoConfigEntry *>::Iterator it = dirtyEntries.begin();
+ for( ; it != dirtyEntries.end(); ++it ) {
+ (*it)->setDirty( false );
+ }
+ }
+}
+
+////
+
+QGpgMECryptoConfigGroup::QGpgMECryptoConfigGroup( const QString & name, const QString& description, int level )
+ : mEntries( 29 ),
+ mName( name ),
+ mDescription( description ),
+ mLevel( static_cast<Kleo::CryptoConfigEntry::Level>( level ) )
+{
+ mEntries.setAutoDelete( true );
+}
+
+QStringList QGpgMECryptoConfigGroup::entryList() const
+{
+ QDictIterator<QGpgMECryptoConfigEntry> it( mEntries );
+ QStringList names;
+ for( ; it.current(); ++it )
+ names.push_back( it.currentKey() );
+ return names;
+}
+
+Kleo::CryptoConfigEntry* QGpgMECryptoConfigGroup::entry( const QString& name ) const
+{
+ return mEntries.find( name );
+}
+
+////
+
+static QString gpgconf_unescape( const QString& str )
+{
+ // Looks like it's the same rules as KURL.
+ return KURL::decode_string( str, 106 );
+}
+
+static QString gpgconf_escape( const QString& str )
+{
+ // Escape special chars (including ':' and '%')
+ QString enc = KURL::encode_string( str, 106 ); // and convert to utf8 first (to get %12%34 for one special char)
+ // Also encode commas, for lists.
+ enc.replace( ',', "%2c" );
+ return enc;
+}
+
+static QString urlpart_encode( const QString& str )
+{
+ QString enc( str );
+ enc.replace( '%', "%25" ); // first!
+ enc.replace( ':', "%3a" );
+ //kdDebug() << " urlpart_encode: " << str << " -> " << enc << endl;
+ return enc;
+}
+
+static QString urlpart_decode( const QString& str )
+{
+ return KURL::decode_string( str );
+}
+
+// gpgconf arg type number -> CryptoConfigEntry arg type enum mapping
+static Kleo::CryptoConfigEntry::ArgType knownArgType( int argType, bool& ok ) {
+ ok = true;
+ switch( argType ) {
+ case 0: // none
+ return Kleo::CryptoConfigEntry::ArgType_None;
+ case 1: // string
+ return Kleo::CryptoConfigEntry::ArgType_String;
+ case 2: // int32
+ return Kleo::CryptoConfigEntry::ArgType_Int;
+ case 3: // uint32
+ return Kleo::CryptoConfigEntry::ArgType_UInt;
+ case 32: // pathname
+ return Kleo::CryptoConfigEntry::ArgType_Path;
+ case 33: // ldap server
+ return Kleo::CryptoConfigEntry::ArgType_LDAPURL;
+ default:
+ ok = false;
+ return Kleo::CryptoConfigEntry::ArgType_None;
+ }
+}
+
+QGpgMECryptoConfigEntry::QGpgMECryptoConfigEntry( const QStringList& parsedLine )
+{
+ // Format: NAME:FLAGS:LEVEL:DESCRIPTION:TYPE:ALT-TYPE:ARGNAME:DEFAULT:ARGDEF:VALUE
+ assert( parsedLine.count() >= 10 ); // called checked for it already
+ QStringList::const_iterator it = parsedLine.begin();
+ mName = *it++;
+ mFlags = (*it++).toInt();
+ mLevel = (*it++).toInt();
+ mDescription = *it++;
+ bool ok;
+ // we keep the real (int) arg type, since it influences the parsing (e.g. for ldap urls)
+ mRealArgType = (*it++).toInt();
+ mArgType = knownArgType( mRealArgType, ok );
+ if ( !ok && !(*it).isEmpty() ) {
+ // use ALT-TYPE
+ mRealArgType = (*it).toInt();
+ mArgType = knownArgType( mRealArgType, ok );
+ }
+ if ( !ok )
+ kdWarning(5150) << "Unsupported datatype: " << parsedLine[4] << " : " << *it << " for " << parsedLine[0] << endl;
+ ++it; // done with alt-type
+ ++it; // skip argname (not useful in GUIs)
+
+ mSet = false;
+ QString value;
+ if ( mFlags & GPGCONF_FLAG_DEFAULT ) {
+ value = *it; // get default value
+ mDefaultValue = stringToValue( value, true );
+ }
+ ++it; // done with DEFAULT
+ ++it; // ### skip ARGDEF for now. It's only for options with an "optional arg"
+ //kdDebug(5150) << "Entry " << parsedLine[0] << " val=" << *it << endl;
+
+ if ( !(*it).isEmpty() ) { // a real value was set
+ mSet = true;
+ value = *it;
+ mValue = stringToValue( value, true );
+ }
+ else {
+ mValue = mDefaultValue;
+ }
+
+ mDirty = false;
+}
+
+QVariant QGpgMECryptoConfigEntry::stringToValue( const QString& str, bool unescape ) const
+{
+ bool isString = isStringType();
+
+ if ( isList() ) {
+ QValueList<QVariant> lst;
+ QStringList items = QStringList::split( ',', str );
+ for( QStringList::const_iterator valit = items.begin(); valit != items.end(); ++valit ) {
+ QString val = *valit;
+ if ( isString ) {
+ if ( val.isEmpty() ) {
+ lst << QString::null;
+ continue;
+ }
+ else if ( unescape ) {
+ if( val[0] != '"' ) // see README.gpgconf
+ kdWarning(5150) << "String value should start with '\"' : " << val << endl;
+ val = val.mid( 1 );
+ }
+ }
+ lst << QVariant( unescape ? gpgconf_unescape( val ) : val );
+ }
+ return lst;
+ } else { // not a list
+ QString val( str );
+ if ( isString ) {
+ if ( val.isEmpty() )
+ return QVariant( QString::null ); // not set [ok with lists too?]
+ else if ( unescape ) {
+ Q_ASSERT( val[0] == '"' ); // see README.gpgconf
+ val = val.mid( 1 );
+ }
+ }
+ return QVariant( unescape ? gpgconf_unescape( val ) : val );
+ }
+}
+
+QGpgMECryptoConfigEntry::~QGpgMECryptoConfigEntry()
+{
+#ifndef NDEBUG
+ if ( !s_duringClear && mDirty )
+ kdWarning(5150) << "Deleting a QGpgMECryptoConfigEntry that was modified (" << mDescription << ")\n"
+ << "You forgot to call sync() (to commit) or clear() (to discard)" << endl;
+#endif
+}
+
+bool QGpgMECryptoConfigEntry::isOptional() const
+{
+ return mFlags & GPGCONF_FLAG_OPTIONAL;
+}
+
+bool QGpgMECryptoConfigEntry::isReadOnly() const
+{
+ return mFlags & GPGCONF_FLAG_NO_CHANGE;
+}
+
+bool QGpgMECryptoConfigEntry::isList() const
+{
+ return mFlags & GPGCONF_FLAG_LIST;
+}
+
+bool QGpgMECryptoConfigEntry::isRuntime() const
+{
+ return mFlags & GPGCONF_FLAG_RUNTIME;
+}
+
+bool QGpgMECryptoConfigEntry::isSet() const
+{
+ return mSet;
+}
+
+bool QGpgMECryptoConfigEntry::boolValue() const
+{
+ Q_ASSERT( mArgType == ArgType_None );
+ Q_ASSERT( !isList() );
+ return mValue.toBool();
+}
+
+QString QGpgMECryptoConfigEntry::stringValue() const
+{
+ return toString( false );
+}
+
+int QGpgMECryptoConfigEntry::intValue() const
+{
+ Q_ASSERT( mArgType == ArgType_Int );
+ Q_ASSERT( !isList() );
+ return mValue.toInt();
+}
+
+unsigned int QGpgMECryptoConfigEntry::uintValue() const
+{
+ Q_ASSERT( mArgType == ArgType_UInt );
+ Q_ASSERT( !isList() );
+ return mValue.toUInt();
+}
+
+static KURL parseURL( int mRealArgType, const QString& str )
+{
+ if ( mRealArgType == 33 ) { // LDAP server
+ // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
+ QStringList items = QStringList::split( ':', str, true );
+ if ( items.count() == 5 ) {
+ QStringList::const_iterator it = items.begin();
+ KURL url;
+ url.setProtocol( "ldap" );
+ url.setHost( urlpart_decode( *it++ ) );
+ url.setPort( (*it++).toInt() );
+ url.setPath( "/" ); // workaround KURL parsing bug
+ url.setUser( urlpart_decode( *it++ ) );
+ url.setPass( urlpart_decode( *it++ ) );
+ url.setQuery( urlpart_decode( *it ) );
+ return url;
+ } else
+ kdWarning(5150) << "parseURL: malformed LDAP server: " << str << endl;
+ }
+ // other URLs : assume wellformed URL syntax.
+ return KURL( str );
+}
+
+// The opposite of parseURL
+static QString splitURL( int mRealArgType, const KURL& url )
+{
+ if ( mRealArgType == 33 ) { // LDAP server
+ // The format is HOSTNAME:PORT:USERNAME:PASSWORD:BASE_DN
+ Q_ASSERT( url.protocol() == "ldap" );
+ return urlpart_encode( url.host() ) + ":" +
+ QString::number( url.port() ) + ":" +
+ urlpart_encode( url.user() ) + ":" +
+ urlpart_encode( url.pass() ) + ":" +
+ // KURL automatically encoded the query (e.g. for spaces inside it),
+ // so decode it before writing it out to gpgconf (issue119)
+ urlpart_encode( KURL::decode_string( url.query().mid(1) ) );
+ }
+ return url.path();
+}
+
+KURL QGpgMECryptoConfigEntry::urlValue() const
+{
+ Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
+ Q_ASSERT( !isList() );
+ QString str = mValue.toString();
+ if ( mArgType == ArgType_Path )
+ {
+ KURL url;
+ url.setPath( str );
+ return url;
+ }
+ return parseURL( mRealArgType, str );
+}
+
+unsigned int QGpgMECryptoConfigEntry::numberOfTimesSet() const
+{
+ Q_ASSERT( mArgType == ArgType_None );
+ Q_ASSERT( isList() );
+ return mValue.toUInt();
+}
+
+QStringList QGpgMECryptoConfigEntry::stringValueList() const
+{
+ Q_ASSERT( isStringType() );
+ Q_ASSERT( isList() );
+ return mValue.toStringList();
+}
+
+QValueList<int> QGpgMECryptoConfigEntry::intValueList() const
+{
+ Q_ASSERT( mArgType == ArgType_Int );
+ Q_ASSERT( isList() );
+ QValueList<int> ret;
+ QValueList<QVariant> lst = mValue.toList();
+ for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ ret.append( (*it).toInt() );
+ }
+ return ret;
+}
+
+QValueList<unsigned int> QGpgMECryptoConfigEntry::uintValueList() const
+{
+ Q_ASSERT( mArgType == ArgType_UInt );
+ Q_ASSERT( isList() );
+ QValueList<unsigned int> ret;
+ QValueList<QVariant> lst = mValue.toList();
+ for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ ret.append( (*it).toUInt() );
+ }
+ return ret;
+}
+
+KURL::List QGpgMECryptoConfigEntry::urlValueList() const
+{
+ Q_ASSERT( mArgType == ArgType_Path || mArgType == ArgType_URL || mArgType == ArgType_LDAPURL );
+ Q_ASSERT( isList() );
+ QStringList lst = mValue.toStringList();
+
+ KURL::List ret;
+ for( QStringList::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ if ( mArgType == ArgType_Path ) {
+ KURL url;
+ url.setPath( *it );
+ ret << url;
+ } else {
+ ret << parseURL( mRealArgType, *it );
+ }
+ }
+ return ret;
+}
+
+void QGpgMECryptoConfigEntry::resetToDefault()
+{
+ mSet = false;
+ mDirty = true;
+ if ( mFlags & GPGCONF_FLAG_DEFAULT )
+ mValue = mDefaultValue;
+ else if ( mArgType == ArgType_None )
+ mValue = false;
+}
+
+void QGpgMECryptoConfigEntry::setBoolValue( bool b )
+{
+ Q_ASSERT( mArgType == ArgType_None );
+ Q_ASSERT( !isList() );
+ // A "no arg" option is either set or not set.
+ // Being set means mSet==true + mValue==true, being unset means resetToDefault(), i.e. both false
+ mValue = b;
+ mSet = b;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setStringValue( const QString& str )
+{
+ mValue = stringToValue( str, false );
+ // When setting a string to empty (and there's no default), we need to act like resetToDefault
+ // Otherwise we try e.g. "ocsp-responder:0:" and gpgconf answers:
+ // "gpgconf: argument required for option ocsp-responder"
+ if ( str.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setIntValue( int i )
+{
+ Q_ASSERT( mArgType == ArgType_Int );
+ Q_ASSERT( !isList() );
+ mValue = i;
+ mSet = true;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setUIntValue( unsigned int i )
+{
+ mValue = i;
+ mSet = true;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setURLValue( const KURL& url )
+{
+ QString str = splitURL( mRealArgType, url );
+ if ( str.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mValue = str;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setNumberOfTimesSet( unsigned int i )
+{
+ Q_ASSERT( mArgType == ArgType_None );
+ Q_ASSERT( isList() );
+ setUIntValue( i );
+}
+
+void QGpgMECryptoConfigEntry::setStringValueList( const QStringList& lst )
+{
+ mValue = lst;
+ if ( lst.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setIntValueList( const QValueList<int>& lst )
+{
+ QValueList<QVariant> ret;
+ for( QValueList<int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ ret << QVariant( *it );
+ }
+ mValue = ret;
+ if ( ret.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setUIntValueList( const QValueList<unsigned int>& lst )
+{
+ QValueList<QVariant> ret;
+ for( QValueList<unsigned int>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ ret << QVariant( *it );
+ }
+ if ( ret.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mValue = ret;
+ mDirty = true;
+}
+
+void QGpgMECryptoConfigEntry::setURLValueList( const KURL::List& urls )
+{
+ QStringList lst;
+ for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
+ lst << splitURL( mRealArgType, *it );
+ }
+ mValue = lst;
+ if ( lst.isEmpty() && !isOptional() )
+ mSet = false;
+ else
+ mSet = true;
+ mDirty = true;
+}
+
+QString QGpgMECryptoConfigEntry::toString( bool escape ) const
+{
+ // Basically the opposite of stringToValue
+ if ( isStringType() ) {
+ if ( mValue.isNull() )
+ return QString::null;
+ else if ( isList() ) { // string list
+ QStringList lst = mValue.toStringList();
+ if ( escape ) {
+ for( QStringList::iterator it = lst.begin(); it != lst.end(); ++it ) {
+ if ( !(*it).isNull() )
+ *it = gpgconf_escape( *it ).prepend( "\"" );
+ }
+ }
+ QString res = lst.join( "," );
+ kdDebug(5150) << "toString: " << res << endl;
+ return res;
+ } else { // normal string
+ QString res = mValue.toString();
+ if ( escape )
+ res = gpgconf_escape( res ).prepend( "\"" );
+ return res;
+ }
+ }
+ if ( !isList() ) // non-list non-string
+ {
+ if ( mArgType == ArgType_None ) {
+ return mValue.toBool() ? QString::fromLatin1( "1" ) : QString::null;
+ } else { // some int
+ Q_ASSERT( mArgType == ArgType_Int || mArgType == ArgType_UInt );
+ return mValue.toString(); // int to string conversion
+ }
+ }
+
+ // Lists (of other types than strings)
+ if ( mArgType == ArgType_None )
+ return QString::number( numberOfTimesSet() );
+ QStringList ret;
+ QValueList<QVariant> lst = mValue.toList();
+ for( QValueList<QVariant>::const_iterator it = lst.begin(); it != lst.end(); ++it ) {
+ ret << (*it).toString(); // QVariant does the conversion
+ }
+ return ret.join( "," );
+}
+
+QString QGpgMECryptoConfigEntry::outputString() const
+{
+ Q_ASSERT( mSet );
+ return toString( true );
+}
+
+bool QGpgMECryptoConfigEntry::isStringType() const
+{
+ return ( mArgType == Kleo::CryptoConfigEntry::ArgType_String
+ || mArgType == Kleo::CryptoConfigEntry::ArgType_Path
+ || mArgType == Kleo::CryptoConfigEntry::ArgType_URL
+ || mArgType == Kleo::CryptoConfigEntry::ArgType_LDAPURL );
+}
+
+void QGpgMECryptoConfigEntry::setDirty( bool b )
+{
+ mDirty = b;
+}
+
+#include "qgpgmecryptoconfig.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h
new file mode 100644
index 000000000..bfcb8e5ca
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmecryptoconfig.h
@@ -0,0 +1,186 @@
+/*
+ qgpgmecryptoconfig.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef KLEO_QGPGMECRYPTOCONFIG_H
+#define KLEO_QGPGMECRYPTOCONFIG_H
+
+#include <kleo/cryptoconfig.h>
+#include <qdict.h>
+#include <qstringlist.h>
+#include <qobject.h>
+#include <qvariant.h>
+class KProcIO;
+
+class QGpgMECryptoConfigComponent;
+class QGpgMECryptoConfigEntry;
+/**
+ * CryptoConfig implementation around the gpgconf command-line tool
+ * For method docu, see kleo/cryptoconfig.h
+ */
+class QGpgMECryptoConfig : public QObject, public Kleo::CryptoConfig {
+
+ Q_OBJECT
+public:
+ /**
+ * Constructor
+ */
+ QGpgMECryptoConfig();
+ virtual ~QGpgMECryptoConfig();
+
+ virtual QStringList componentList() const;
+
+ virtual Kleo::CryptoConfigComponent* component( const QString& name ) const;
+
+ virtual void clear();
+ virtual void sync( bool runtime );
+
+private slots:
+ void slotCollectStdOut( KProcIO* proc );
+private:
+ /// @param showErrors if true, a messagebox will be shown if e.g. gpgconf wasn't found
+ void runGpgConf( bool showErrors );
+
+private:
+ QDict<QGpgMECryptoConfigComponent> mComponents;
+ bool mParsed;
+};
+
+class QGpgMECryptoConfigGroup;
+
+/// For docu, see kleo/cryptoconfig.h
+class QGpgMECryptoConfigComponent : public QObject, public Kleo::CryptoConfigComponent {
+
+ Q_OBJECT
+public:
+ QGpgMECryptoConfigComponent( QGpgMECryptoConfig*, const QString& name, const QString& description );
+ ~QGpgMECryptoConfigComponent();
+
+ QString name() const { return mName; }
+ QString iconName() const { return mName; }
+ QString description() const { return mDescription; }
+ QStringList groupList() const;
+ Kleo::CryptoConfigGroup* group( const QString& name ) const;
+
+ void sync( bool runtime );
+
+private slots:
+ void slotCollectStdOut( KProcIO* proc );
+private:
+ void runGpgConf();
+
+private:
+ QDict<QGpgMECryptoConfigGroup> mGroups;
+ QString mName;
+ QString mDescription;
+ QGpgMECryptoConfigGroup* mCurrentGroup; // during parsing
+ QString mCurrentGroupName; // during parsing
+};
+
+class QGpgMECryptoConfigGroup : public Kleo::CryptoConfigGroup {
+
+public:
+ QGpgMECryptoConfigGroup( const QString & name, const QString& description, int level );
+ ~QGpgMECryptoConfigGroup() {}
+
+ QString name() const { return mName; }
+ QString iconName() const { return QString::null; }
+ QString description() const { return mDescription; }
+ Kleo::CryptoConfigEntry::Level level() const { return mLevel; }
+ QStringList entryList() const;
+ Kleo::CryptoConfigEntry* entry( const QString& name ) const;
+
+private:
+ friend class QGpgMECryptoConfigComponent; // it adds the entries
+ QDict<QGpgMECryptoConfigEntry> mEntries;
+ QString mName;
+ QString mDescription;
+ Kleo::CryptoConfigEntry::Level mLevel;
+};
+
+class QGpgMECryptoConfigEntry : public Kleo::CryptoConfigEntry {
+public:
+ QGpgMECryptoConfigEntry( const QStringList& parsedLine );
+ ~QGpgMECryptoConfigEntry();
+
+ QString name() const { return mName; }
+ QString description() const { return mDescription; }
+ bool isOptional() const;
+ bool isReadOnly() const;
+ bool isList() const;
+ bool isRuntime() const;
+ Level level() const { return static_cast<Level>( mLevel ); }
+ ArgType argType() const { return static_cast<ArgType>( mArgType ); }
+ bool isSet() const;
+ bool boolValue() const;
+ QString stringValue() const;
+ int intValue() const;
+ unsigned int uintValue() const;
+ KURL urlValue() const;
+ unsigned int numberOfTimesSet() const;
+ QStringList stringValueList() const;
+ QValueList<int> intValueList() const;
+ QValueList<unsigned int> uintValueList() const;
+ KURL::List urlValueList() const;
+ void resetToDefault();
+ void setBoolValue( bool );
+ void setStringValue( const QString& );
+ void setIntValue( int );
+ void setUIntValue( unsigned int );
+ void setURLValue( const KURL& );
+ void setNumberOfTimesSet( unsigned int );
+ void setStringValueList( const QStringList& );
+ void setIntValueList( const QValueList<int>& );
+ void setUIntValueList( const QValueList<unsigned int>& );
+ void setURLValueList( const KURL::List& );
+ bool isDirty() const { return mDirty; }
+
+ void setDirty( bool b );
+ QString outputString() const;
+
+protected:
+ bool isStringType() const;
+ QVariant stringToValue( const QString& value, bool unescape ) const;
+ QString toString( bool escape ) const;
+private:
+ QString mName;
+ QString mDescription;
+ QVariant mDefaultValue;
+ QVariant mValue;
+ uint mFlags : 8; // bitfield with 8 bits
+ uint mLevel : 3; // max is 4 (2, in fact) -> 3 bits
+ uint mRealArgType : 6; // max is 33 -> 6 bits
+ uint mArgType : 3; // max is 6 (ArgType enum) -> 3 bits;
+ uint mDirty : 1;
+ uint mSet : 1;
+};
+
+#endif /* KLEO_QGPGMECRYPTOCONFIG_H */
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp
new file mode 100644
index 000000000..17905555e
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.cpp
@@ -0,0 +1,91 @@
+/*
+ qgpgmedecryptjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmedecryptjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/decryptionresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEDecryptJob::QGpgMEDecryptJob( GpgME::Context * context )
+ : DecryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDecryptJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEDecryptJob::~QGpgMEDecryptJob() {
+}
+
+void Kleo::QGpgMEDecryptJob::setup( const QByteArray & cipherText ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( cipherText );
+ createOutData();
+}
+
+GpgME::Error Kleo::QGpgMEDecryptJob::start( const QByteArray & cipherText ) {
+ setup( cipherText );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startDecryption( *mInData, *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+GpgME::DecryptionResult Kleo::QGpgMEDecryptJob::exec( const QByteArray & cipherText,
+ QByteArray & plainText ) {
+ setup( cipherText );
+ const GpgME::DecryptionResult result = mCtx->decrypt( *mInData, *mOutData );
+ plainText = mOutDataDataProvider->data();
+ getAuditLog();
+ return result;
+}
+
+void Kleo::QGpgMEDecryptJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->decryptionResult(), mOutDataDataProvider->data() );
+}
+
+#include "qgpgmedecryptjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h
new file mode 100644
index 000000000..7fc89dff2
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptjob.h
@@ -0,0 +1,74 @@
+/*
+ qgpgmedecryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEDECRYPTJOB_H__
+#define __KLEO_QGPGMEDECRYPTJOB_H__
+
+#include <kleo/decryptjob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEDecryptJob : public DecryptJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEDecryptJob( GpgME::Context * context );
+ ~QGpgMEDecryptJob();
+
+ /*! \reimp from DecryptJob */
+ GpgME::Error start( const QByteArray & cipherText );
+
+ /*! \reimp from DecryptJob */
+ GpgME::DecryptionResult exec( const QByteArray & cipherText,
+ QByteArray & plainText );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray & cipherText );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEDECRYPTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp
new file mode 100644
index 000000000..02cf1ef28
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.cpp
@@ -0,0 +1,95 @@
+/*
+ qgpgmedecryptverifyjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmedecryptverifyjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/decryptionresult.h>
+#include <gpgmepp/verificationresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEDecryptVerifyJob::QGpgMEDecryptVerifyJob( GpgME::Context * context )
+ : DecryptVerifyJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDecryptVerifyJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEDecryptVerifyJob::~QGpgMEDecryptVerifyJob() {
+}
+
+void Kleo::QGpgMEDecryptVerifyJob::setup( const QByteArray & cipherText ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( cipherText );
+ createOutData();
+}
+
+GpgME::Error Kleo::QGpgMEDecryptVerifyJob::start( const QByteArray & cipherText ) {
+ setup( cipherText );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startCombinedDecryptionAndVerification( *mInData, *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+std::pair<GpgME::DecryptionResult,GpgME::VerificationResult>
+Kleo::QGpgMEDecryptVerifyJob::exec( const QByteArray & cipherText, QByteArray & plainText ) {
+ setup( cipherText );
+ const std::pair<GpgME::DecryptionResult,GpgME::VerificationResult> result =
+ mCtx->decryptAndVerify( *mInData, *mOutData );
+ plainText = mOutDataDataProvider->data();
+ getAuditLog();
+ return result;
+}
+
+void Kleo::QGpgMEDecryptVerifyJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->decryptionResult(),
+ mCtx->verificationResult(),
+ mOutDataDataProvider->data() );
+}
+
+#include "qgpgmedecryptverifyjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h
new file mode 100644
index 000000000..a39188746
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedecryptverifyjob.h
@@ -0,0 +1,75 @@
+/*
+ qgpgmedecryptverifyjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEDECRYPTVERIFYJOB_H__
+#define __KLEO_QGPGMEDECRYPTVERIFYJOB_H__
+
+#include <kleo/decryptverifyjob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+#include <kdepimmacros.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class KDE_EXPORT QGpgMEDecryptVerifyJob : public DecryptVerifyJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEDecryptVerifyJob( GpgME::Context * context );
+ ~QGpgMEDecryptVerifyJob();
+
+ /*! \reimp from DecryptVerifyJob */
+ GpgME::Error start( const QByteArray & cipherText );
+
+ /*! \reimp from DecryptVerifyJob */
+ std::pair<GpgME::DecryptionResult,GpgME::VerificationResult>
+ exec( const QByteArray & cipherText, QByteArray & plainText );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray & );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEDECRYPTVERIFYJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp
new file mode 100644
index 000000000..c06907eea
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.cpp
@@ -0,0 +1,70 @@
+/*
+ qgpgmedeletejob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmedeletejob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+
+#include <gpgmepp/context.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEDeleteJob::QGpgMEDeleteJob( GpgME::Context * context )
+ : DeleteJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDeleteJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEDeleteJob::~QGpgMEDeleteJob() {
+}
+
+GpgME::Error Kleo::QGpgMEDeleteJob::start( const GpgME::Key & key, bool allowSecretKeyDeletion ) {
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startKeyDeletion( key, allowSecretKeyDeletion );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+void Kleo::QGpgMEDeleteJob::doOperationDoneEvent( const GpgME::Error & error ) {
+ emit result( error );
+}
+
+#include "qgpgmedeletejob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h
new file mode 100644
index 000000000..9dec128f7
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedeletejob.h
@@ -0,0 +1,68 @@
+/*
+ qgpgmedeletejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEDELETEJOB_H__
+#define __KLEO_QGPGMEDELETEJOB_H__
+
+#include <kleo/deletejob.h>
+
+#include "qgpgmejob.h"
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kleo {
+
+ class QGpgMEDeleteJob : public DeleteJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEDeleteJob( GpgME::Context * context );
+ ~QGpgMEDeleteJob();
+
+ /*! \reimp from DeleteJob */
+ GpgME::Error start( const GpgME::Key & key, bool allowSecretKeyDeletion );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEDELETEJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp
new file mode 100644
index 000000000..6ee771a04
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.cpp
@@ -0,0 +1,78 @@
+/*
+ qgpgmedownloadjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmedownloadjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <qstringlist.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEDownloadJob::QGpgMEDownloadJob( GpgME::Context * context )
+ : DownloadJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEDownloadJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEDownloadJob::~QGpgMEDownloadJob() {
+}
+
+GpgME::Error Kleo::QGpgMEDownloadJob::start( const QStringList & pats ) {
+ assert( !patterns() );
+ assert( !mOutData );
+
+ createOutData();
+ setPatterns( pats );
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startPublicKeyExport( patterns(), *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+void Kleo::QGpgMEDownloadJob::doOperationDoneEvent( const GpgME::Error & error ) {
+ emit result( error, mOutDataDataProvider->data() );
+}
+
+#include "qgpgmedownloadjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h
new file mode 100644
index 000000000..1402b127c
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmedownloadjob.h
@@ -0,0 +1,67 @@
+/*
+ qgpgmedownloadjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEDOWNLOADJOB_H__
+#define __KLEO_QGPGMEDOWNLOADJOB_H__
+
+#include <kleo/downloadjob.h>
+
+#include "qgpgmejob.h"
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEDownloadJob : public DownloadJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEDownloadJob( GpgME::Context * context );
+ ~QGpgMEDownloadJob();
+
+ /*! \reimp from DownloadJob */
+ GpgME::Error start( const QStringList & fingerprints );
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+ };
+
+}
+
+#endif // __KLEO_QGPGMEDOWNLOADJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp
new file mode 100644
index 000000000..3f223fc56
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.cpp
@@ -0,0 +1,108 @@
+/*
+ qgpgmeencryptjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeencryptjob.h"
+
+#include "ui/messagebox.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/encryptionresult.h>
+#include <gpgmepp/data.h>
+
+#include <klocale.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEEncryptJob::QGpgMEEncryptJob( GpgME::Context * context )
+ : EncryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEEncryptJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEEncryptJob::~QGpgMEEncryptJob() {
+}
+
+void Kleo::QGpgMEEncryptJob::setup( const QByteArray & plainText ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( plainText );
+ createOutData();
+}
+
+GpgME::Error Kleo::QGpgMEEncryptJob::start( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust ) {
+ setup( plainText );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Context::EncryptionFlags flags =
+ alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None;
+ const GpgME::Error err = mCtx->startEncryption( recipients, *mInData, *mOutData, flags );
+
+ if ( err )
+ deleteLater();
+ mResult = GpgME::EncryptionResult( err );
+ return err;
+}
+
+GpgME::EncryptionResult Kleo::QGpgMEEncryptJob::exec( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText,
+ bool alwaysTrust,
+ QByteArray & ciphertext ) {
+ setup( plainText );
+ const GpgME::Context::EncryptionFlags flags =
+ alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None;
+ mResult = mCtx->encrypt( recipients, *mInData, *mOutData, flags );
+ ciphertext = mOutDataDataProvider->data();
+ getAuditLog();
+ return mResult;
+}
+
+void Kleo::QGpgMEEncryptJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mResult = mCtx->encryptionResult(), mOutDataDataProvider->data() );
+}
+
+void Kleo::QGpgMEEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( mResult.error() && !mResult.error().isCanceled() )
+ Kleo::MessageBox::error( parent, mResult, this, caption );
+}
+
+#include "qgpgmeencryptjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h
new file mode 100644
index 000000000..362fb4e06
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeencryptjob.h
@@ -0,0 +1,86 @@
+/*
+ qgpgmeencryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEENCRYPTJOB_H__
+#define __KLEO_QGPGMEENCRYPTJOB_H__
+
+#include <kleo/encryptjob.h>
+
+#include "qgpgmejob.h"
+
+#include <gpgmepp/encryptionresult.h>
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kleo {
+
+ class QGpgMEEncryptJob : public EncryptJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEEncryptJob( GpgME::Context * context );
+ ~QGpgMEEncryptJob();
+
+ /*! \reimp from EncryptJob */
+ GpgME::Error start( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust );
+
+ /*! \reimp from EncryptJob */
+ GpgME::EncryptionResult exec( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust,
+ QByteArray & cipherText );
+
+ /*! \reimp from Job */
+ void showErrorDialog( QWidget * parent, const QString & caption ) const;
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray & );
+
+ private:
+ GpgME::EncryptionResult mResult;
+ };
+
+}
+
+#endif // __KLEO_QGPGMEENCRYPTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp
new file mode 100644
index 000000000..c9274f3b7
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.cpp
@@ -0,0 +1,78 @@
+/*
+ qgpgmeexportjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeexportjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <qstringlist.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEExportJob::QGpgMEExportJob( GpgME::Context * context )
+ : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEExportJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEExportJob::~QGpgMEExportJob() {
+}
+
+GpgME::Error Kleo::QGpgMEExportJob::start( const QStringList & pats ) {
+ assert( !patterns() );
+ assert( !mOutData );
+
+ createOutData();
+ setPatterns( pats );
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startPublicKeyExport( patterns(), *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+void Kleo::QGpgMEExportJob::doOperationDoneEvent( const GpgME::Error & error ) {
+ emit result( error, mOutDataDataProvider->data() );
+}
+
+#include "qgpgmeexportjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h
new file mode 100644
index 000000000..8b799b583
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeexportjob.h
@@ -0,0 +1,69 @@
+/*
+ qgpgmeexportjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEEXPORTJOB_H__
+#define __KLEO_QGPGMEEXPORTJOB_H__
+
+#include <kleo/exportjob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEExportJob : public ExportJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEExportJob( GpgME::Context * context );
+ ~QGpgMEExportJob();
+
+ /*! \reimp from ExportJob */
+ GpgME::Error start( const QStringList & patterns );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEEXPORTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp
new file mode 100644
index 000000000..fd1251b65
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.cpp
@@ -0,0 +1,86 @@
+/*
+ qgpgmeimportjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeimportjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/importresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEImportJob::QGpgMEImportJob( GpgME::Context * context )
+ : ImportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEImportJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEImportJob::~QGpgMEImportJob() {
+}
+
+void Kleo::QGpgMEImportJob::setup( const QByteArray & keyData ) {
+ assert( !mInData );
+
+ createInData( keyData );
+}
+
+GpgME::Error Kleo::QGpgMEImportJob::start( const QByteArray & keyData ) {
+ setup( keyData );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startKeyImport( *mInData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+GpgME::ImportResult Kleo::QGpgMEImportJob::exec( const QByteArray & keyData ) {
+ setup( keyData );
+ return mCtx->importKeys( *mInData );
+}
+
+void Kleo::QGpgMEImportJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->importResult() );
+}
+
+
+#include "qgpgmeimportjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h
new file mode 100644
index 000000000..8c2ee1ad4
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeimportjob.h
@@ -0,0 +1,73 @@
+/*
+ qgpgmeimportjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEIMPORTJOB_H__
+#define __KLEO_QGPGMEIMPORTJOB_H__
+
+#include <kleo/importjob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEImportJob : public ImportJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEImportJob( GpgME::Context * context );
+ ~QGpgMEImportJob();
+
+ /*! \reimp from ImportJob */
+ GpgME::Error start( const QByteArray & keyData );
+
+ /*! \reimp from ImportJob */
+ GpgME::ImportResult exec( const QByteArray & keyData );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray & );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEIMPORTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmejob.cpp
new file mode 100644
index 000000000..897e5ff7c
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmejob.cpp
@@ -0,0 +1,304 @@
+/*
+ qgpgmejob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmejob.h"
+#include "qgpgmeprogresstokenmapper.h"
+
+#include <kleo/job.h>
+#include <ui/passphrasedialog.h>
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <klocale.h>
+#include <kstandarddirs.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+#include <algorithm>
+
+#include <assert.h>
+#include <string.h>
+
+namespace {
+ class InvarianceChecker {
+ public:
+#ifdef NDEBUG
+ InvarianceChecker( const Kleo::QGpgMEJob * ) {}
+#else
+ InvarianceChecker( const Kleo::QGpgMEJob * job )
+ : _this( job )
+ {
+ assert( _this );
+ _this->checkInvariants();
+ }
+ ~InvarianceChecker() {
+ _this->checkInvariants();
+ }
+ private:
+ const Kleo::QGpgMEJob * _this;
+#endif
+ };
+}
+
+Kleo::QGpgMEJob::QGpgMEJob( Kleo::Job * _this, GpgME::Context * context )
+ : GpgME::ProgressProvider(),
+ GpgME::PassphraseProvider(),
+ mThis( _this ),
+ mCtx( context ),
+ mInData( 0 ),
+ mInDataDataProvider( 0 ),
+ mOutData( 0 ),
+ mOutDataDataProvider( 0 ),
+ mPatterns( 0 ),
+ mReplacedPattern( 0 ),
+ mNumPatterns( 0 ),
+ mChunkSize( 1024 ),
+ mPatternStartIndex( 0 ), mPatternEndIndex( 0 )
+{
+ InvarianceChecker check( this );
+ assert( context );
+ QObject::connect( QGpgME::EventLoopInteractor::instance(), SIGNAL(aboutToDestroy()),
+ _this, SLOT(slotCancel()) );
+ context->setProgressProvider( this );
+ // (mmutz) work around a gpgme bug in versions at least <= 0.9.0.
+ // These versions will return GPG_ERR_NOT_IMPLEMENTED from
+ // a CMS sign operation when a passphrase callback is set.
+ if ( context->protocol() == GpgME::Context::OpenPGP )
+ context->setPassphraseProvider( this );
+}
+
+void Kleo::QGpgMEJob::checkInvariants() const {
+#ifndef NDEBUG
+ if ( mPatterns ) {
+ assert( mPatterns[mNumPatterns] == 0 );
+ if ( mPatternEndIndex > 0 ) {
+ assert( mPatternEndIndex > mPatternStartIndex );
+ assert( mPatternEndIndex - mPatternStartIndex == mChunkSize );
+ } else {
+ assert( mPatternEndIndex == mPatternStartIndex );
+ }
+ if ( mPatternEndIndex < mNumPatterns ) {
+ assert( mPatterns[mPatternEndIndex] == 0 );
+ assert( mReplacedPattern != 0 );
+ } else {
+ assert( mReplacedPattern == 0 );
+ }
+ } else {
+ assert( mNumPatterns == 0 );
+ assert( mPatternStartIndex == 0 );
+ assert( mPatternEndIndex == 0 );
+ assert( mReplacedPattern == 0 );
+ }
+#endif
+}
+
+Kleo::QGpgMEJob::~QGpgMEJob() {
+ InvarianceChecker check( this );
+ delete mCtx; mCtx = 0;
+ delete mInData; mInData = 0;
+ delete mInDataDataProvider; mInDataDataProvider = 0;
+ delete mOutData; mOutData = 0;
+ delete mOutDataDataProvider; mOutDataDataProvider = 0;
+ deleteAllPatterns();
+}
+
+void Kleo::QGpgMEJob::deleteAllPatterns() {
+ if ( mPatterns )
+ for ( unsigned int i = 0 ; i < mNumPatterns ; ++i )
+ free( (void*)mPatterns[i] );
+ free( (void*)mReplacedPattern ); mReplacedPattern = 0;
+ delete[] mPatterns; mPatterns = 0;
+ mPatternEndIndex = mPatternStartIndex = mNumPatterns = 0;
+}
+
+void Kleo::QGpgMEJob::hookupContextToEventLoopInteractor() {
+ mCtx->setManagedByEventLoopInteractor( true );
+ QObject::connect( QGpgME::EventLoopInteractor::instance(),
+ SIGNAL(operationDoneEventSignal(GpgME::Context*,const GpgME::Error&)),
+ mThis, SLOT(slotOperationDoneEvent(GpgME::Context*,const GpgME::Error&)) );
+}
+
+void Kleo::QGpgMEJob::setPatterns( const QStringList & sl, bool allowEmpty ) {
+ InvarianceChecker check( this );
+ deleteAllPatterns();
+ // create a new null-terminated C array of char* from patterns:
+ mPatterns = new const char*[ sl.size() + 1 ];
+ const char* * pat_it = mPatterns;
+ mNumPatterns = 0;
+ for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it ) {
+ if ( (*it).isNull() )
+ continue;
+ if ( (*it).isEmpty() && !allowEmpty )
+ continue;
+ *pat_it++ = strdup( (*it).utf8().data() );
+ ++mNumPatterns;
+ }
+ *pat_it++ = 0;
+ mReplacedPattern = 0;
+ mPatternEndIndex = mChunkSize = mNumPatterns;
+}
+
+void Kleo::QGpgMEJob::setChunkSize( unsigned int chunksize ) {
+ InvarianceChecker check( this );
+ if ( mReplacedPattern ) {
+ mPatterns[mPatternEndIndex] = mReplacedPattern;
+ mReplacedPattern = 0;
+ }
+ mChunkSize = std::min( chunksize, mNumPatterns );
+ mPatternStartIndex = 0;
+ mPatternEndIndex = mChunkSize;
+ mReplacedPattern = mPatterns[mPatternEndIndex];
+ mPatterns[mPatternEndIndex] = 0;
+}
+
+const char* * Kleo::QGpgMEJob::nextChunk() {
+ InvarianceChecker check( this );
+ if ( mReplacedPattern ) {
+ mPatterns[mPatternEndIndex] = mReplacedPattern;
+ mReplacedPattern = 0;
+ }
+ mPatternStartIndex += mChunkSize;
+ mPatternEndIndex += mChunkSize;
+ if ( mPatternEndIndex < mNumPatterns ) { // could safely be <=, but the last entry is NULL anyway
+ mReplacedPattern = mPatterns[mPatternEndIndex];
+ mPatterns[mPatternEndIndex] = 0;
+ }
+ return patterns();
+}
+
+const char* * Kleo::QGpgMEJob::patterns() const {
+ InvarianceChecker check( this );
+ if ( mPatternStartIndex < mNumPatterns )
+ return mPatterns + mPatternStartIndex;
+ return 0;
+}
+
+GpgME::Error Kleo::QGpgMEJob::setSigningKeys( const std::vector<GpgME::Key> & signers ) {
+ mCtx->clearSigningKeys();
+ for ( std::vector<GpgME::Key>::const_iterator it = signers.begin() ; it != signers.end() ; ++it ) {
+ if ( (*it).isNull() )
+ continue;
+ if ( const GpgME::Error err = mCtx->addSigningKey( *it ) )
+ return err;
+ }
+ return 0;
+}
+
+void Kleo::QGpgMEJob::createInData( const QByteArray & in ) {
+ mInDataDataProvider = new QGpgME::QByteArrayDataProvider( in );
+ mInData = new GpgME::Data( mInDataDataProvider );
+ assert( !mInData->isNull() );
+}
+
+void Kleo::QGpgMEJob::createOutData() {
+ mOutDataDataProvider = new QGpgME::QByteArrayDataProvider();
+ mOutData = new GpgME::Data( mOutDataDataProvider );
+ assert( !mOutData->isNull() );
+}
+
+static const unsigned int GetAuditLogFlags = GpgME::Context::AuditLogWithHelp|GpgME::Context::HtmlAuditLog;
+
+static QString audit_log_as_html( GpgME::Context * ctx ) {
+ if ( !ctx )
+ return QString();
+ QGpgME::QByteArrayDataProvider dp;
+ GpgME::Data data( &dp );
+ assert( !data.isNull() );
+ if ( const GpgME::Error err = ctx->getAuditLog( data, GetAuditLogFlags ) )
+ return QString();
+ else
+ return QString::fromUtf8( dp.data().data() );
+}
+
+void Kleo::QGpgMEJob::doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ if ( context == mCtx ) {
+ getAuditLog();
+ doEmitDoneSignal();
+ doOperationDoneEvent( e );
+ mThis->deleteLater();
+ }
+}
+
+void Kleo::QGpgMEJob::getAuditLog() {
+ mAuditLogAsHtml = audit_log_as_html( mCtx );
+}
+
+void Kleo::QGpgMEJob::doSlotCancel() {
+ mCtx->cancelPendingOperation();
+}
+
+void Kleo::QGpgMEJob::showProgress( const char * what, int type, int current, int total ) {
+ doEmitProgressSignal( QGpgMEProgressTokenMapper::instance()->map( what, type, current, total ), current, total );
+}
+
+char * Kleo::QGpgMEJob::getPassphrase( const char * useridHint, const char * /*description*/,
+ bool previousWasBad, bool & canceled ) {
+ // DF: here, description is the key fingerprint, twice, then "17 0". Not really descriptive.
+ // So I'm ignoring QString::fromLocal8Bit( description ) )
+ QString msg = previousWasBad ?
+ i18n( "You need a passphrase to unlock the secret key for user:<br/> %1 (retry)" ) :
+ i18n( "You need a passphrase to unlock the secret key for user:<br/> %1" );
+ msg = msg.arg( QString::fromUtf8( useridHint ) ) + "<br/><br/>";
+ msg.prepend( "<qt>" );
+ msg += i18n( "This dialog will reappear every time the passphrase is needed. For a more secure solution that also allows caching the passphrase, use gpg-agent." ) + "<br/>";
+ const QString gpgAgent = KStandardDirs::findExe( "gpg-agent" );
+ if ( !gpgAgent.isEmpty() ) {
+ msg += i18n( "gpg-agent was found in %1, but does not appear to be running." )
+ .arg( gpgAgent );
+ } else {
+ msg += i18n( "gpg-agent is part of gnupg-%1, which you can download from %2" )
+ .arg( "1.9" )
+ .arg( "http://www.gnupg.org/download" ); // add #gnupg2 if you can make this a real link
+ }
+ msg += "<br/>";
+ msg += i18n( "For information on how to set up gpg-agent, see %1" )
+ .arg( "http://kmail.kde.org/kmail-pgpmime-howto.html" );
+ msg += "<br/><br/>";
+ msg += i18n( "Enter passphrase:" );
+ Kleo::PassphraseDialog dlg( msg, i18n("Passphrase Dialog") );
+ if ( dlg.exec() != QDialog::Accepted ) {
+ canceled = true;
+ return 0;
+ }
+ canceled = false;
+ // gpgme++ free()s it, and we need to copy as long as dlg isn't deleted :o
+ return strdup( dlg.passphrase() );
+}
diff --git a/certmanager/lib/backends/qgpgme/qgpgmejob.h b/certmanager/lib/backends/qgpgme/qgpgmejob.h
new file mode 100644
index 000000000..da7acf1c9
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmejob.h
@@ -0,0 +1,160 @@
+/*
+ qgpgmejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEJOB_H__
+#define __KLEO_QGPGMEJOB_H__
+
+#include <gpgmepp/interfaces/progressprovider.h>
+#include <gpgmepp/interfaces/passphraseprovider.h>
+
+#include <gpgmepp/key.h>
+
+#include <qcstring.h>
+#include <qstring.h>
+
+#include <vector>
+#include <kdepimmacros.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Data;
+}
+
+namespace Kleo {
+ class Job;
+}
+
+namespace QGpgME {
+ class QByteArrayDataProvider;
+}
+
+class QString;
+class QStringList;
+
+namespace Kleo {
+
+ /** This is a hackish helper class to avoid code duplication in this
+ backend's Kleo::Job subclasses. It contains several workarounds
+ for moc/signal/slot shortcomings, most of which the author of
+ this thinks are Qt bugs (lazy implementations), first and
+ foremost the inability of moc to handle inheritance from
+ multiple QObject-derived subclasses.
+
+ To use it, inherit from the Job-subclass, then from this class,
+ add QGPGME_JOB to just after Q OBJECT and implement
+ doOperationDoneEvent() by emitting your variant of the result()
+ signal there. Pass "this" as the first argument this QGpgMEJOb's
+ ctor. The rest is dealt with automatically.
+ */
+ class KDE_EXPORT QGpgMEJob : public GpgME::ProgressProvider, public GpgME::PassphraseProvider {
+ public:
+ QGpgMEJob( Kleo::Job * _this, GpgME::Context * context );
+ ~QGpgMEJob();
+
+ protected:
+ /*! Called on operation-done events, between emitting done() and
+ calling deleteLater(). You should emit your result signal here. */
+ virtual void doOperationDoneEvent( const GpgME::Error & e ) = 0;
+ /*! Hooks up mCtx to be managed by the event loop interactor */
+ void hookupContextToEventLoopInteractor();
+ /*! Fills mPatterns from the stringlist, resets chunking to the full list */
+ void setPatterns( const QStringList & sl, bool allowEmpty=false );
+ /*! Returnes the number of patterns set */
+ unsigned int numPatterns() const { return mNumPatterns; }
+ /*! Skips to the next chunk of patterns. @return patterns() */
+ const char* * nextChunk();
+ /*! @return patterns, offset by the current chunk */
+ const char* * patterns() const;
+ /*! Set the current pattern chunksize to size and reset the chunk index to zero */
+ void setChunkSize( unsigned int size );
+ /*! @return current chunksize */
+ unsigned int chunkSize() const { return mChunkSize; }
+ /*! Creates an empty GpgME::Data/QGpgME::QByteArrayDataProvider pair */
+ void createOutData();
+ /*! Creates a GpgME::Data/QGpgME::QByteArrayDataProvider pair,
+ filled with the contents of \a in */
+ void createInData( const QByteArray & in );
+ /*! Sets the list of signing keys */
+ GpgME::Error setSigningKeys( const std::vector<GpgME::Key> & signers );
+ /*! Call this to implement a slotOperationDoneEvent() */
+ void doSlotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e );
+ /*! Call this to extract the audit log from mCtx */
+ void getAuditLog();
+
+ //
+ // only boring stuff below this line...
+ //
+
+ protected:
+ virtual void doEmitProgressSignal( const QString & what, int current, int total ) = 0;
+ virtual void doEmitDoneSignal() = 0;
+ void doSlotCancel();
+ QString auditLogAsHtml() const { return mAuditLogAsHtml; }
+
+ private:
+ /*! \reimp from GpgME::ProgressProvider */
+ void showProgress( const char * what, int type, int current, int total );
+ char * getPassphrase( const char * useridHint, const char * description,
+ bool previousWasBad, bool & canceled );
+ void deleteAllPatterns();
+
+ public:
+ void checkInvariants() const;
+
+ protected:
+ Kleo::Job * mThis;
+ GpgME::Context * mCtx;
+ GpgME::Data * mInData;
+ QGpgME::QByteArrayDataProvider * mInDataDataProvider;
+ GpgME::Data * mOutData;
+ QGpgME::QByteArrayDataProvider * mOutDataDataProvider;
+ private:
+ const char* * mPatterns;
+ // holds the entry - if any - in mPattern that was replaced with
+ // NULL to create a temporary end-of-array marker for gpgme:
+ const char * mReplacedPattern;
+ unsigned int mNumPatterns;
+ unsigned int mChunkSize;
+ unsigned int mPatternStartIndex, mPatternEndIndex;
+ QString mAuditLogAsHtml;
+ };
+
+}
+
+#define make_slot_cancel private: void slotCancel() { QGpgMEJob::doSlotCancel(); }
+#define make_progress_emitter private: void doEmitProgressSignal( const QString & what, int cur, int tot ) { emit progress( what, cur, tot ); }
+#define make_done_emitter private: void doEmitDoneSignal() { emit done(); }
+#define make_auditLogAsHtml private: QString auditLogAsHtml() const { return QGpgMEJob::auditLogAsHtml(); }
+#define QGPGME_JOB make_slot_cancel make_progress_emitter make_done_emitter make_auditLogAsHtml
+
+#endif // __KLEO_QGPGMEJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp
new file mode 100644
index 000000000..a0ab78f23
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.cpp
@@ -0,0 +1,86 @@
+/*
+ qgpgmekeygenerationjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmekeygenerationjob.h"
+
+#include <qgpgme/dataprovider.h>
+#include <qgpgme/eventloopinteractor.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/keygenerationresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEKeyGenerationJob::QGpgMEKeyGenerationJob( GpgME::Context * context )
+ : KeyGenerationJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEKeyGenerationJob" ),
+ QGpgMEJob( this, context ),
+ mPubKeyDataProvider( 0 ),
+ mPubKey( 0 )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEKeyGenerationJob::~QGpgMEKeyGenerationJob() {
+ delete mPubKey; mPubKey = 0;
+ delete mPubKeyDataProvider; mPubKeyDataProvider = 0;
+}
+
+GpgME::Error Kleo::QGpgMEKeyGenerationJob::start( const QString & parameters ) {
+ assert( !mPubKey );
+
+ // set up empty data object for the public key data
+ if ( mCtx->protocol() == GpgME::Context::CMS ) {
+ mPubKeyDataProvider = new QGpgME::QByteArrayDataProvider();
+ mPubKey = new GpgME::Data( mPubKeyDataProvider );
+ assert( !mPubKey->isNull() );
+ }
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err =
+ mCtx->startKeyGeneration( parameters.utf8().data(), mPubKey ? *mPubKey : GpgME::Data::null );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+void Kleo::QGpgMEKeyGenerationJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->keyGenerationResult(), mPubKeyDataProvider ? mPubKeyDataProvider->data() : QByteArray() );
+}
+
+#include "qgpgmekeygenerationjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h
new file mode 100644
index 000000000..973aeb12d
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmekeygenerationjob.h
@@ -0,0 +1,78 @@
+/*
+ qgpgmekeygenerationjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEKEYGENERATIONJOB_H__
+#define __KLEO_QGPGMEKEYGENERATIONJOB_H__
+
+#include <kleo/keygenerationjob.h>
+
+#include "qgpgmejob.h"
+#include <kdepimmacros.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+ class Data;
+}
+
+namespace QGpgME {
+ class QByteArrayDataProvider;
+}
+
+namespace Kleo {
+
+ class KDE_EXPORT QGpgMEKeyGenerationJob : public KeyGenerationJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEKeyGenerationJob( GpgME::Context * context );
+ ~QGpgMEKeyGenerationJob();
+
+ /*! \reimp from KeygenerationJob */
+ GpgME::Error start( const QString & parameters );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & error ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, error );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+
+ private:
+ QGpgME::QByteArrayDataProvider * mPubKeyDataProvider;
+ GpgME::Data * mPubKey;
+ };
+
+}
+
+#endif // __KLEO_QGPGMEKEYGENERATIONJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp
new file mode 100644
index 000000000..9c87e3ef6
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.cpp
@@ -0,0 +1,187 @@
+/*
+ qgpgmekeylistjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmekeylistjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/context.h>
+#include <gpgmepp/keylistresult.h>
+#include <gpg-error.h>
+
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kdebug.h>
+
+#include <qstringlist.h>
+
+#include <algorithm>
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+Kleo::QGpgMEKeyListJob::QGpgMEKeyListJob( GpgME::Context * context )
+ : KeyListJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEKeyListJob" ),
+ QGpgMEJob( this, context ),
+ mResult(), mSecretOnly( false )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEKeyListJob::~QGpgMEKeyListJob() {
+}
+
+void Kleo::QGpgMEKeyListJob::setup( const QStringList & pats, bool secretOnly ) {
+ assert( !patterns() );
+
+ mSecretOnly = secretOnly;
+ setPatterns( pats );
+}
+
+GpgME::Error Kleo::QGpgMEKeyListJob::start( const QStringList & pats, bool secretOnly ) {
+ setup( pats, secretOnly );
+
+ hookupContextToEventLoopInteractor();
+ connect( QGpgME::EventLoopInteractor::instance(),
+ SIGNAL(nextKeyEventSignal(GpgME::Context*,const GpgME::Key&)),
+ SLOT(slotNextKeyEvent(GpgME::Context*,const GpgME::Key&)) );
+
+ // The communication channel between gpgme and gpgsm is limited in
+ // the number of patterns that can be transported, but they won't
+ // say to how much, so we need to find out ourselves if we get a
+ // LINE_TOO_LONG error back...
+
+ // We could of course just feed them single patterns, and that would
+ // probably be easier, but the performance penalty would currently
+ // be noticable.
+
+ while ( const GpgME::Error err = mCtx->startKeyListing( patterns(), mSecretOnly ) ) {
+ if ( err.code() == GPG_ERR_LINE_TOO_LONG ) {
+ setChunkSize( chunkSize()/2 );
+ if ( chunkSize() >= 1 ) {
+ kdDebug(5150) << "QGpgMEKeyListJob::start(): retrying keylisting with chunksize " << chunkSize() << endl;
+ continue;
+ }
+ }
+ deleteLater();
+ mResult = GpgME::KeyListResult( 0, err );
+ return err;
+ }
+ mResult = GpgME::KeyListResult( 0, 0 );
+ return 0;
+}
+
+GpgME::KeyListResult Kleo::QGpgMEKeyListJob::exec( const QStringList & pats, bool secretOnly, std::vector<GpgME::Key> & keys ) {
+ setup( pats, secretOnly );
+
+ // The communication channel between gpgme and gpgsm is limited in
+ // the number of patterns that can be transported, but they won't
+ // say to how much, so we need to find out ourselves if we get a
+ // LINE_TOO_LONG error back...
+
+ // We could of course just feed them single patterns, and that would
+ // probably be easier, but the performance penalty would currently
+ // be noticable.
+
+ for (;;) {
+ keys.clear();
+ mResult = attemptSyncKeyListing( keys );
+ if ( !mResult.error() || mResult.error().code() != GPG_ERR_LINE_TOO_LONG )
+ return mResult;
+ // got LINE_TOO_LONG, try a smaller chunksize:
+ setChunkSize( chunkSize()/2 );
+ if ( chunkSize() < 1 )
+ // chunks smaller than one can't be -> return the error.
+ return mResult;
+ kdDebug(5150) << "QGpgMEKeyListJob::exec(): retrying keylisting with chunksize " << chunkSize() << endl;
+ }
+ kdFatal(5150) << "QGpgMEKeyListJob::exec(): Oops, this is not supposed to happen!" << endl;
+ return GpgME::KeyListResult();
+}
+
+GpgME::KeyListResult Kleo::QGpgMEKeyListJob::attemptSyncKeyListing( std::vector<GpgME::Key> & keys ) {
+ GpgME::KeyListResult result;
+ for ( const char* * chunk = patterns() ; chunk ; chunk = nextChunk() ) {
+
+ if ( const GpgME::Error err = mCtx->startKeyListing( chunk, mSecretOnly ) )
+ return GpgME::KeyListResult( 0, err );
+
+ GpgME::Error err;
+ do
+ keys.push_back( mCtx->nextKey( err ) );
+ while ( !err );
+ keys.pop_back();
+ result.mergeWith( mCtx->endKeyListing() );
+ if ( result.error() )
+ break;
+ }
+ return result;
+}
+
+void Kleo::QGpgMEKeyListJob::slotNextKeyEvent( GpgME::Context * context, const GpgME::Key & key ) {
+ if ( context == mCtx )
+ emit nextKey( key );
+}
+
+void Kleo::QGpgMEKeyListJob::slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & ) {
+ if ( context != mCtx )
+ return;
+ mResult.mergeWith( mCtx->keyListResult() );
+ if ( !mResult.error() )
+ if ( const char* * chunk = nextChunk() ) {
+ if ( const GpgME::Error err = mCtx->startKeyListing( chunk, mSecretOnly ) )
+ mResult.mergeWith( GpgME::KeyListResult( 0, err ) );
+ else
+ return;
+ }
+ emit done();
+ emit result( mResult );
+ deleteLater();
+}
+
+void Kleo::QGpgMEKeyListJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( !mResult.error() || mResult.error().isCanceled() )
+ return;
+ const QString msg = i18n( "<qt><p>An error occurred while fetching "
+ "the keys from the backend:</p>"
+ "<p><b>%1</b></p></qt>" )
+ .arg( QString::fromLocal8Bit( mResult.error().asString() ) );
+ KMessageBox::error( parent, msg, caption );
+}
+
+#include "qgpgmekeylistjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h
new file mode 100644
index 000000000..8320e0134
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmekeylistjob.h
@@ -0,0 +1,81 @@
+/*
+ qgpgmekeylistjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEKEYLISTJOB_H__
+#define __KLEO_QGPGMEKEYLISTJOB_H__
+
+#include <kleo/keylistjob.h>
+
+#include <gpgmepp/keylistresult.h>
+
+#include "qgpgmejob.h"
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kleo {
+
+ class QGpgMEKeyListJob : public KeyListJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEKeyListJob( GpgME::Context * context );
+ ~QGpgMEKeyListJob();
+
+ /*! \reimp from KeyListJob */
+ GpgME::Error start( const QStringList & patterns, bool secretOnly );
+
+ /*! \reimp from KeyListJob */
+ GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, std::vector<GpgME::Key> & keys );
+
+ /*! \reimp from Job */
+ void showErrorDialog( QWidget * parent, const QString & caption ) const;
+
+ private slots:
+ void slotNextKeyEvent( GpgME::Context * context, const GpgME::Key & key );
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e );
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error &) {} // unused, we implement slotOperationDoneEvent ourselves.
+ void setup( const QStringList &, bool );
+ GpgME::KeyListResult attemptSyncKeyListing( std::vector<GpgME::Key> & );
+
+ private:
+ GpgME::KeyListResult mResult;
+ bool mSecretOnly;
+ };
+
+}
+
+#endif // __KLEO_QGPGMEKEYLISTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp
new file mode 100644
index 000000000..3b6ae35eb
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.cpp
@@ -0,0 +1,159 @@
+/* -*- mode: C++; c-file-style: "gnu" -*-
+ qgpgmeprogresstokenmapper.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeprogresstokenmapper.h"
+
+#include <klocale.h>
+
+#include <qstring.h>
+
+#include <assert.h>
+#include <map>
+
+struct Desc {
+ int type; // 0 == fallback
+ const char * display; // add %1 for useCur ^ useTot and %1 %2 for useCur == useTot == true
+ bool useCur : 1;
+ bool useTot : 1;
+};
+
+static const struct Desc pk_dsa[] = {
+ { 0, I18N_NOOP("Generating DSA key..."), false, false }
+};
+
+static const struct Desc pk_elg[] = {
+ { 0, I18N_NOOP("Generating ElGamal key..."), false, false }
+};
+
+static const struct Desc primegen[] = {
+ // FIXME: add all type's?
+ { 0, I18N_NOOP("Searching for a large prime number..."), false, false }
+};
+
+static const struct Desc need_entropy[] = {
+ { 0, I18N_NOOP("Waiting for new entropy from random number generator (you might want to exercise the harddisks or move the mouse)..."), false, false }
+};
+
+static const struct Desc tick[] = {
+ { 0, I18N_NOOP("Please wait..."), false, false }
+};
+
+static const struct Desc starting_agent[] = {
+ { 0, I18N_NOOP("Starting gpg-agent (you should consider starting a global instance instead)..."), false, false }
+};
+
+static const struct {
+ const char * token;
+ const Desc * desc;
+ unsigned int numDesc;
+} tokens[] = {
+#define make_token(x) { #x, x, sizeof(x) / sizeof(*x) }
+ make_token(pk_dsa),
+ make_token(pk_elg),
+ make_token(primegen),
+ make_token(need_entropy),
+ make_token(tick),
+ make_token(starting_agent)
+#undef make_token
+};
+
+
+
+Kleo::QGpgMEProgressTokenMapper * Kleo::QGpgMEProgressTokenMapper::mSelf = 0;
+
+const Kleo::QGpgMEProgressTokenMapper * Kleo::QGpgMEProgressTokenMapper::instance() {
+ if ( !mSelf )
+ (void) new QGpgMEProgressTokenMapper();
+ return mSelf;
+}
+
+Kleo::QGpgMEProgressTokenMapper::QGpgMEProgressTokenMapper() {
+ mSelf = this;
+}
+
+Kleo::QGpgMEProgressTokenMapper::~QGpgMEProgressTokenMapper() {
+ mSelf = 0;
+}
+
+typedef std::map< QString, std::map<int,Desc> > Map;
+
+static const Map & makeMap() { // return a reference to a static to avoid copying
+ static Map map;
+ for ( unsigned int i = 0 ; i < sizeof tokens / sizeof *tokens ; ++i ) {
+ assert( tokens[i].token );
+ const QString token = QString::fromLatin1( tokens[i].token ).lower();
+ for ( unsigned int j = 0 ; j < tokens[i].numDesc ; ++j ) {
+ const Desc & desc = tokens[i].desc[j];
+ assert( desc.display );
+ map[ token ][ desc.type ] = desc;
+ }
+ }
+ return map;
+}
+
+QString Kleo::QGpgMEProgressTokenMapper::map( const char * tokenUtf8, int subtoken, int cur, int tot ) const {
+ if ( !tokenUtf8 || !*tokenUtf8 )
+ return QString::null;
+
+ if ( qstrcmp( tokenUtf8, "file:" ) == 0 )
+ return QString::null; // gpgme's job
+
+ return map( QString::fromUtf8( tokenUtf8 ), subtoken, cur, tot );
+}
+
+QString Kleo::QGpgMEProgressTokenMapper::map( const QString & token, int subtoken, int cur, int tot ) const {
+ if ( token.startsWith( "file:" ) )
+ return QString::null; // gpgme's job
+
+ static const Map & tokenMap = makeMap();
+
+ const Map::const_iterator it1 = tokenMap.find( token.lower() );
+ if ( it1 == tokenMap.end() )
+ return token;
+ std::map<int,Desc>::const_iterator it2 = it1->second.find( subtoken );
+ if ( it2 == it1->second.end() )
+ it2 = it1->second.find( 0 );
+ if ( it2 == it1->second.end() )
+ return token;
+ const Desc & desc = it2->second;
+ QString result = i18n( desc.display );
+ if ( desc.useCur )
+ result = result.arg( cur );
+ if ( desc.useTot )
+ result = result.arg( tot );
+ return result;
+}
+
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h
new file mode 100644
index 000000000..d0a8da6c3
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeprogresstokenmapper.h
@@ -0,0 +1,58 @@
+/*
+ qgpgmeprogresstokenmapper.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+
+#ifndef __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__
+#define __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__
+
+
+class QString;
+
+namespace Kleo {
+
+ class QGpgMEProgressTokenMapper {
+ QGpgMEProgressTokenMapper();
+ ~QGpgMEProgressTokenMapper();
+ public:
+ static const QGpgMEProgressTokenMapper * instance();
+
+ QString map( const char * token, int subtoken, int current, int total ) const;
+ QString map( const QString & token, int subtoken, int current, int total ) const;
+
+ private:
+ static QGpgMEProgressTokenMapper * mSelf;
+ };
+
+}
+
+
+#endif // __KLEO_QGPGMEPROGRESSTOKENMAPPER_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp
new file mode 100644
index 000000000..325306e8c
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.cpp
@@ -0,0 +1,207 @@
+/*
+ qgpgmerefreshkeysjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmerefreshkeysjob.h"
+
+#include "gnupgprocessbase.h"
+#include "qgpgmeprogresstokenmapper.h"
+
+#include <kdebug.h>
+
+#include <gpgmepp/context.h>
+
+#include <qgpgme/eventloopinteractor.h>
+
+#include <qstringlist.h>
+
+#include <gpg-error.h>
+
+#include <assert.h>
+
+Kleo::QGpgMERefreshKeysJob::QGpgMERefreshKeysJob()
+ : RefreshKeysJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMERefreshKeysJob" ),
+ mProcess( 0 ),
+ mError( 0 )
+{
+
+}
+
+Kleo::QGpgMERefreshKeysJob::~QGpgMERefreshKeysJob() {
+
+}
+
+GpgME::Error Kleo::QGpgMERefreshKeysJob::start( const QStringList & patterns ) {
+ assert( mPatternsToDo.empty() );
+
+ mPatternsToDo = patterns;
+ if ( mPatternsToDo.empty() )
+ mPatternsToDo.push_back( " " ); // empty list means all -> mae
+ // sure to fail the first
+ // startAProcess() guard clause
+
+ return startAProcess();
+}
+
+#if MAX_CMD_LENGTH < 65 + 128
+#error MAX_CMD_LENGTH is too low
+#endif
+
+GpgME::Error Kleo::QGpgMERefreshKeysJob::startAProcess() {
+ if ( mPatternsToDo.empty() )
+ return 0;
+ // create and start gpgsm process:
+ mProcess = new GnuPGProcessBase( this, "gpgsm -k --with-validation --force-crl-refresh --enable-crl-checks" );
+
+ // FIXME: obbtain the path to gpgsm from gpgme, so we use the same instance.
+ *mProcess << "gpgsm" << "-k" << "--with-validation" << "--force-crl-refresh"
+ << "--enable-crl-checks";
+ unsigned int commandLineLength = MAX_CMD_LENGTH;
+ commandLineLength -=
+ strlen("gpgsm") + 1 + strlen("-k") + 1 +
+ strlen("--with-validation") + 1 + strlen("--force-crl-refresh") + 1 +
+ strlen("--enable-crl-checks") + 1;
+ while ( !mPatternsToDo.empty() ) {
+ const QCString pat = mPatternsToDo.front().utf8().stripWhiteSpace();
+ const unsigned int patLength = pat.length();
+ if ( patLength >= commandLineLength )
+ break;
+ mPatternsToDo.pop_front();
+ if ( pat.isEmpty() )
+ continue;
+ *mProcess << pat;
+ commandLineLength -= patLength + 1;
+ }
+
+ mProcess->setUseStatusFD( true );
+
+ connect( mProcess, SIGNAL(processExited(KProcess*)),
+ SLOT(slotProcessExited(KProcess*)) );
+ connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)),
+ SLOT(slotStderr(KProcess*,char*,int)) );
+ connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)),
+ SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) );
+
+ if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::Stderr ) ) {
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else?
+ deleteLater();
+ return mError;
+ } else
+ return 0;
+}
+
+void Kleo::QGpgMERefreshKeysJob::slotCancel() {
+ if ( mProcess )
+ mProcess->kill();
+ mProcess = 0;
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
+}
+
+void Kleo::QGpgMERefreshKeysJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) {
+ if ( proc != mProcess )
+ return;
+ QStringList::const_iterator it = args.begin();
+ bool ok = false;
+
+ if ( type == "ERROR" ) {
+
+
+ if ( args.size() < 2 ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
+ return;
+ }
+ const int source = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
+ return;
+ }
+ ok = false;
+ const int code = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
+ return;
+ }
+ mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
+
+
+ } else if ( type == "PROGRESS" ) {
+
+
+ if ( args.size() < 4 ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
+ return;
+ }
+ const QString what = *++it;
+ ++it; // don't use "type"...
+ const int cur = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"cur\", got something else" << endl;
+ return;
+ }
+ ok = false;
+ const int total = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMERefreshKeysJob::slotStatus() expected number for \"total\", got something else" << endl;
+ return;
+ }
+ emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
+
+
+ }
+}
+
+void Kleo::QGpgMERefreshKeysJob::slotStderr( KProcess *, char *, int ) {
+ // implement? or not?
+}
+
+void Kleo::QGpgMERefreshKeysJob::slotProcessExited( KProcess * proc ) {
+ if ( proc != mProcess )
+ return;
+
+ if ( !mError && !mPatternsToDo.empty() )
+ if ( const GpgME::Error err = startAProcess() )
+ mError = err;
+ else
+ return;
+
+ emit done();
+ if ( !mError &&
+ ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
+ emit result( mError );
+ deleteLater();
+}
+
+#include "qgpgmerefreshkeysjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h
new file mode 100644
index 000000000..a0132f223
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmerefreshkeysjob.h
@@ -0,0 +1,80 @@
+/*
+ qgpgmerefreshkeysjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEREFRESHKEYSJOB_H__
+#define __KLEO_QGPGMEREFRESHKEYSJOB_H__
+
+#include <kleo/refreshkeysjob.h>
+
+#include <qstringlist.h>
+
+namespace Kleo {
+ class GnuPGProcessBase;
+}
+
+namespace GpgME {
+ class Error;
+}
+
+class KProcess;
+
+namespace Kleo {
+
+ class QGpgMERefreshKeysJob : public RefreshKeysJob {
+ Q_OBJECT
+ public:
+ QGpgMERefreshKeysJob();
+ ~QGpgMERefreshKeysJob();
+
+ /*! \reimp from RefreshKeysJob */
+ GpgME::Error start( const QStringList & patterns );
+
+ private slots:
+ /*! \reimp from Job */
+ void slotCancel();
+
+ void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & );
+ void slotStderr( KProcess *, char *, int );
+ void slotProcessExited( KProcess * );
+
+ private:
+ GpgME::Error startAProcess();
+
+ private:
+ GnuPGProcessBase * mProcess;
+ int mError;
+ QStringList mPatternsToDo;
+ };
+
+}
+
+#endif // __KLEO_QGPGMEREFRESHKEYSJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp
new file mode 100644
index 000000000..0ce543cf9
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.cpp
@@ -0,0 +1,196 @@
+/*
+ qgpgmesecretexportjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmesecretkeyexportjob.h"
+
+#include "gnupgprocessbase.h"
+#include "qgpgmeprogresstokenmapper.h"
+
+#include <kdebug.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <qgpgme/eventloopinteractor.h>
+
+#include <qstringlist.h>
+
+#include <gpg-error.h>
+
+#include <string.h>
+#include <assert.h>
+
+Kleo::QGpgMESecretKeyExportJob::QGpgMESecretKeyExportJob( bool armour, const QString& charset )
+ : ExportJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESecretKeyExportJob" ),
+ mProcess( 0 ),
+ mError( 0 ),
+ mArmour( armour ),
+ mCharset( charset )
+{
+
+}
+
+Kleo::QGpgMESecretKeyExportJob::~QGpgMESecretKeyExportJob() {
+
+}
+
+GpgME::Error Kleo::QGpgMESecretKeyExportJob::start( const QStringList & patterns ) {
+ assert( mKeyData.isEmpty() );
+
+ if ( patterns.size() != 1 || patterns.front().isEmpty() ) {
+ deleteLater();
+ return mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_INV_VALUE );
+ }
+
+ // create and start gpgsm process:
+ mProcess = new GnuPGProcessBase( this, "gpgsm --export-secret-key-p12" );
+
+ // FIXME: obtain the path to gpgsm from gpgme, so we use the same instance.
+ *mProcess << "gpgsm" << "--export-secret-key-p12";
+ if ( mArmour )
+ *mProcess << "--armor";
+ if ( !mCharset.isEmpty() )
+ *mProcess << "--p12-charset" << mCharset;
+ *mProcess << patterns.front().utf8();
+
+ mProcess->setUseStatusFD( true );
+
+ connect( mProcess, SIGNAL(processExited(KProcess*)),
+ SLOT(slotProcessExited(KProcess*)) );
+ connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)),
+ SLOT(slotStdout(KProcess*,char*,int)) );
+ connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)),
+ SLOT(slotStderr(KProcess*,char*,int)) );
+ connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)),
+ SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) );
+
+ if ( !mProcess->start( KProcess::NotifyOnExit, KProcess::AllOutput ) ) {
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_ENOENT ); // what else?
+ deleteLater();
+ return mError;
+ } else
+ return 0;
+}
+
+void Kleo::QGpgMESecretKeyExportJob::slotCancel() {
+ if ( mProcess )
+ mProcess->kill();
+ mProcess = 0;
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_CANCELED );
+}
+
+void Kleo::QGpgMESecretKeyExportJob::slotStatus( GnuPGProcessBase * proc, const QString & type, const QStringList & args ) {
+ if ( proc != mProcess )
+ return;
+ QStringList::const_iterator it = args.begin();
+ bool ok = false;
+
+ if ( type == "ERROR" ) {
+
+
+ if ( args.size() < 2 ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising ERROR with < 2 args!" << endl;
+ return;
+ }
+ const int source = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for first ERROR arg, got something else" << endl;
+ return;
+ }
+ ok = false;
+ const int code = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for second ERROR arg, got something else" << endl;
+ return;
+ }
+ mError = gpg_err_make( (gpg_err_source_t)source, (gpg_err_code_t)code );
+
+
+ } else if ( type == "PROGRESS" ) {
+
+
+ if ( args.size() < 4 ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() not recognising PROGRESS with < 4 args!" << endl;
+ return;
+ }
+ const QString what = *++it;
+ ++it; // don't use "type"...
+ const int cur = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"cur\", got something else" << endl;
+ return;
+ }
+ ok = false;
+ const int total = (*++it).toInt( &ok );
+ if ( !ok ) {
+ kdDebug( 5150 ) << "Kleo::QGpgMESecretKeyExportJob::slotStatus() expected number for \"total\", got something else" << endl;
+ return;
+ }
+ emit progress( QGpgMEProgressTokenMapper::instance()->map( what, 0, cur, total ), cur, total );
+
+
+ }
+}
+
+void Kleo::QGpgMESecretKeyExportJob::slotStdout( KProcess * proc, char * buf, int buflen ) {
+ if ( proc != mProcess )
+ return;
+ if ( buflen <= 0 )
+ return;
+ if ( !buf )
+ return;
+ const unsigned int oldlen = mKeyData.size();
+ mKeyData.resize( oldlen + buflen );
+ memcpy( mKeyData.data() + oldlen, buf, buflen );
+}
+
+void Kleo::QGpgMESecretKeyExportJob::slotStderr( KProcess *, char *, int ) {
+ // implement? or not?
+}
+
+void Kleo::QGpgMESecretKeyExportJob::slotProcessExited( KProcess * proc ) {
+ if ( proc != mProcess )
+ return;
+
+ emit done();
+ if ( !mError &&
+ ( !mProcess->normalExit() || mProcess->exitStatus() != 0 ) )
+ mError = gpg_err_make( GPG_ERR_SOURCE_GPGSM, GPG_ERR_GENERAL );
+ emit result( mError, mKeyData );
+ deleteLater();
+}
+
+#include "qgpgmesecretkeyexportjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h
new file mode 100644
index 000000000..5f5e3b69c
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesecretkeyexportjob.h
@@ -0,0 +1,85 @@
+/*
+ qgpgmesecretkeyexportjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMESECRETKEYEXPORTJOB_H__
+#define __KLEO_QGPGMESECRETKEYEXPORTJOB_H__
+
+#include <kleo/exportjob.h>
+
+#include <qcstring.h>
+
+namespace Kleo {
+ class GnuPGProcessBase;
+}
+
+namespace GpgME {
+ class Error;
+ class Data;
+}
+
+namespace QGpgME {
+ class QByteArrayDataProvider;
+}
+
+class KProcess;
+
+namespace Kleo {
+
+ class QGpgMESecretKeyExportJob : public ExportJob {
+ Q_OBJECT
+ public:
+ QGpgMESecretKeyExportJob( bool armour, const QString& charset );
+ ~QGpgMESecretKeyExportJob();
+
+ /*! \reimp from ExportJob */
+ GpgME::Error start( const QStringList & patterns );
+
+ private slots:
+ /*! \reimp from Job */
+ void slotCancel();
+
+ void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & );
+ void slotStdout( KProcess *, char *, int );
+ void slotStderr( KProcess *, char *, int );
+ void slotProcessExited( KProcess * );
+
+ private:
+ GnuPGProcessBase * mProcess;
+ QByteArray mKeyData;
+ int mError;
+ bool mArmour;
+ QString mCharset;
+ };
+
+}
+
+#endif // __KLEO_QGPGMESECRETKEYEXPORTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp
new file mode 100644
index 000000000..fae748478
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.cpp
@@ -0,0 +1,121 @@
+/*
+ qgpgmesignencryptjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmesignencryptjob.h"
+
+#include "ui/messagebox.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+#include <gpgmepp/key.h>
+
+#include <klocale.h>
+
+#include <assert.h>
+
+Kleo::QGpgMESignEncryptJob::QGpgMESignEncryptJob( GpgME::Context * context )
+ : SignEncryptJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESignEncryptJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMESignEncryptJob::~QGpgMESignEncryptJob() {
+}
+
+GpgME::Error Kleo::QGpgMESignEncryptJob::setup( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( plainText );
+ createOutData();
+
+ return setSigningKeys( signers );
+}
+
+GpgME::Error Kleo::QGpgMESignEncryptJob::start( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust ) {
+ if ( const GpgME::Error error = setup( signers, plainText ) ) {
+ deleteLater();
+ return error;
+ }
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Context::EncryptionFlags flags =
+ alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None ;
+ const GpgME::Error err = mCtx->startCombinedSigningAndEncryption( recipients, *mInData, *mOutData, flags );
+
+ if ( err )
+ deleteLater();
+ mResult.first = GpgME::SigningResult( err );
+ mResult.second = GpgME::EncryptionResult( err );
+ return err;
+}
+
+std::pair<GpgME::SigningResult,GpgME::EncryptionResult>
+Kleo::QGpgMESignEncryptJob::exec( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust,
+ QByteArray & cipherText ) {
+ if ( GpgME::Error err = setup( signers, plainText ) )
+ return std::make_pair( GpgME::SigningResult( 0, err ), GpgME::EncryptionResult() );
+ const GpgME::Context::EncryptionFlags flags =
+ alwaysTrust ? GpgME::Context::AlwaysTrust : GpgME::Context::None ;
+ mResult = mCtx->signAndEncrypt( recipients, *mInData, *mOutData, flags );
+ cipherText = mOutDataDataProvider->data();
+ getAuditLog();
+ return mResult;
+}
+
+void Kleo::QGpgMESignEncryptJob::doOperationDoneEvent( const GpgME::Error & ) {
+ mResult.first = mCtx->signingResult();
+ mResult.second = mCtx->encryptionResult();
+ emit result( mResult.first, mResult.second, mOutDataDataProvider->data() );
+}
+
+void Kleo::QGpgMESignEncryptJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( mResult.first.error() && !mResult.first.error().isCanceled() ||
+ mResult.second.error() && !mResult.second.error().isCanceled() )
+ Kleo::MessageBox::error( parent, mResult.first, mResult.second, this, caption );
+}
+
+#include "qgpgmesignencryptjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h
new file mode 100644
index 000000000..a826edcbf
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesignencryptjob.h
@@ -0,0 +1,91 @@
+/*
+ qgpgmesignencryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMESIGNENCRYPTJOB_H__
+#define __KLEO_QGPGMESIGNENCRYPTJOB_H__
+
+#include <kleo/signencryptjob.h>
+
+#include "qgpgmejob.h"
+
+#include <gpgmepp/signingresult.h>
+#include <gpgmepp/encryptionresult.h>
+
+#include <qcstring.h>
+
+#include <utility>
+
+#include <kdepimmacros.h>
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kleo {
+
+ class KDE_EXPORT QGpgMESignEncryptJob : public SignEncryptJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMESignEncryptJob( GpgME::Context * context );
+ ~QGpgMESignEncryptJob();
+
+ /*! \reimp from SignEncryptJob */
+ GpgME::Error start( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust );
+
+ std::pair<GpgME::SigningResult,GpgME::EncryptionResult>
+ exec( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust,
+ QByteArray & cipherText );
+
+ /*! \reimp from Job */
+ void showErrorDialog( QWidget * parent, const QString & caption ) const;
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ GpgME::Error setup( const std::vector<GpgME::Key> &,
+ const QByteArray & );
+ private:
+ std::pair<GpgME::SigningResult,GpgME::EncryptionResult> mResult;
+ };
+
+}
+
+#endif // __KLEO_QGPGMESIGNENCRYPTJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp
new file mode 100644
index 000000000..84485ad5b
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesignjob.cpp
@@ -0,0 +1,113 @@
+/*
+ qgpgmesignjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmesignjob.h"
+
+#include "ui/messagebox.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/signingresult.h>
+#include <gpgmepp/data.h>
+#include <gpgmepp/key.h>
+
+#include <klocale.h>
+
+#include <assert.h>
+
+Kleo::QGpgMESignJob::QGpgMESignJob( GpgME::Context * context )
+ : SignJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMESignJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMESignJob::~QGpgMESignJob() {
+}
+
+GpgME::Error Kleo::QGpgMESignJob::setup( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( plainText );
+ createOutData();
+
+ return setSigningKeys( signers );
+}
+
+GpgME::Error Kleo::QGpgMESignJob::start( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode ) {
+ if ( const GpgME::Error error = setup( signers, plainText ) ) {
+ deleteLater();
+ return error;
+ }
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startSigning( *mInData, *mOutData, mode );
+
+ if ( err )
+ deleteLater();
+ mResult = GpgME::SigningResult( err );
+ return err;
+}
+
+GpgME::SigningResult Kleo::QGpgMESignJob::exec( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode,
+ QByteArray & signature ) {
+ if ( const GpgME::Error err = setup( signers, plainText ) )
+ return mResult = GpgME::SigningResult( 0, err );
+ mResult = mCtx->sign( *mInData, *mOutData, mode );
+ signature = mOutDataDataProvider->data();
+ getAuditLog();
+ return mResult;
+}
+
+void Kleo::QGpgMESignJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mResult = mCtx->signingResult(), mOutDataDataProvider->data() );
+}
+
+void Kleo::QGpgMESignJob::showErrorDialog( QWidget * parent, const QString & caption ) const {
+ if ( mResult.error() && !mResult.error().isCanceled() )
+ Kleo::MessageBox::error( parent, mResult, this, caption );
+}
+
+#include "qgpgmesignjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmesignjob.h b/certmanager/lib/backends/qgpgme/qgpgmesignjob.h
new file mode 100644
index 000000000..c2589b477
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmesignjob.h
@@ -0,0 +1,87 @@
+/*
+ qgpgmesignjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMESIGNJOB_H__
+#define __KLEO_QGPGMESIGNJOB_H__
+
+#include <kleo/signjob.h>
+
+#include "qgpgmejob.h"
+
+#include <gpgmepp/signingresult.h>
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+ class Key;
+}
+
+namespace Kleo {
+
+ class QGpgMESignJob : public SignJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMESignJob( GpgME::Context * context );
+ ~QGpgMESignJob();
+
+ /*! \reimp from SignJob */
+ GpgME::Error start( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode );
+
+ /*! \reimp from SignJob */
+ GpgME::SigningResult exec( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode,
+ QByteArray & signature );
+
+ /*! \reimp from Job */
+ void showErrorDialog( QWidget * parent, const QString & caption ) const;
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ GpgME::Error setup( const std::vector<GpgME::Key> &, const QByteArray & );
+
+ private:
+ GpgME::SigningResult mResult;
+ };
+
+}
+
+#endif // __KLEO_QGPGMESIGNJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp
new file mode 100644
index 000000000..cc1186373
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.cpp
@@ -0,0 +1,96 @@
+/*
+ qgpgmeverifydetachedjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeverifydetachedjob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/verificationresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEVerifyDetachedJob::QGpgMEVerifyDetachedJob( GpgME::Context * context )
+ : VerifyDetachedJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEVerifyDetachedJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEVerifyDetachedJob::~QGpgMEVerifyDetachedJob() {
+}
+
+void Kleo::QGpgMEVerifyDetachedJob::setup( const QByteArray & signature, const QByteArray & signedData ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( signature );
+
+ // two "in" data objects - (mis|re)use the "out" data object for the second...
+ mOutDataDataProvider = new QGpgME::QByteArrayDataProvider( signedData );
+ mOutData = new GpgME::Data( mOutDataDataProvider );
+ assert( !mOutData->isNull() );
+}
+
+GpgME::Error Kleo::QGpgMEVerifyDetachedJob::start( const QByteArray & signature,
+ const QByteArray & signedData ) {
+ setup( signature, signedData );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startDetachedSignatureVerification( *mInData, *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+GpgME::VerificationResult Kleo::QGpgMEVerifyDetachedJob::exec( const QByteArray & signature,
+ const QByteArray & signedData ) {
+ setup( signature, signedData );
+ const GpgME::VerificationResult r = mCtx->verifyDetachedSignature( *mInData, *mOutData );
+ getAuditLog();
+ return r;
+}
+
+void Kleo::QGpgMEVerifyDetachedJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->verificationResult() );
+}
+
+
+#include "qgpgmeverifydetachedjob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h
new file mode 100644
index 000000000..76141fb80
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeverifydetachedjob.h
@@ -0,0 +1,75 @@
+/*
+ qgpgmeverifydetachedjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEVERIFYDETACHEDJOB_H__
+#define __KLEO_QGPGMEVERIFYDETACHEDJOB_H__
+
+#include <kleo/verifydetachedjob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEVerifyDetachedJob : public VerifyDetachedJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEVerifyDetachedJob( GpgME::Context * context );
+ ~QGpgMEVerifyDetachedJob();
+
+ /*! \reimp from VerifyDetachedJob */
+ GpgME::Error start( const QByteArray & signature,
+ const QByteArray & signedData );
+
+ /*! \reimp from VerifyDetachedJob */
+ GpgME::VerificationResult exec( const QByteArray & signature,
+ const QByteArray & signedData );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray &, const QByteArray & );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEVERIFYDETACHEDJOB_H__
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp
new file mode 100644
index 000000000..15f075963
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.cpp
@@ -0,0 +1,91 @@
+/*
+ qgpgmeverifyopaquejob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "qgpgmeverifyopaquejob.h"
+
+#include <qgpgme/eventloopinteractor.h>
+#include <qgpgme/dataprovider.h>
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/verificationresult.h>
+#include <gpgmepp/data.h>
+
+#include <assert.h>
+
+Kleo::QGpgMEVerifyOpaqueJob::QGpgMEVerifyOpaqueJob( GpgME::Context * context )
+ : VerifyOpaqueJob( QGpgME::EventLoopInteractor::instance(), "Kleo::QGpgMEVerifyOpaqueJob" ),
+ QGpgMEJob( this, context )
+{
+ assert( context );
+}
+
+Kleo::QGpgMEVerifyOpaqueJob::~QGpgMEVerifyOpaqueJob() {
+}
+
+void Kleo::QGpgMEVerifyOpaqueJob::setup( const QByteArray & signedData ) {
+ assert( !mInData );
+ assert( !mOutData );
+
+ createInData( signedData );
+ createOutData();
+}
+
+GpgME::Error Kleo::QGpgMEVerifyOpaqueJob::start( const QByteArray & signedData ) {
+ setup( signedData );
+
+ hookupContextToEventLoopInteractor();
+
+ const GpgME::Error err = mCtx->startOpaqueSignatureVerification( *mInData, *mOutData );
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+GpgME::VerificationResult Kleo::QGpgMEVerifyOpaqueJob::exec( const QByteArray & signedData, QByteArray & plainText ) {
+ setup( signedData );
+ const GpgME::VerificationResult res = mCtx->verifyOpaqueSignature( *mInData, *mOutData );
+ plainText = mOutDataDataProvider->data();
+ getAuditLog();
+ return res;
+}
+
+void Kleo::QGpgMEVerifyOpaqueJob::doOperationDoneEvent( const GpgME::Error & ) {
+ emit result( mCtx->verificationResult(), mOutDataDataProvider->data() );
+}
+
+
+#include "qgpgmeverifyopaquejob.moc"
diff --git a/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h
new file mode 100644
index 000000000..2c167fb1d
--- /dev/null
+++ b/certmanager/lib/backends/qgpgme/qgpgmeverifyopaquejob.h
@@ -0,0 +1,73 @@
+/*
+ qgpgmeverifyopaquejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_QGPGMEVERIFYOPAQUEJOB_H__
+#define __KLEO_QGPGMEVERIFYOPAQUEJOB_H__
+
+#include <kleo/verifyopaquejob.h>
+
+#include "qgpgmejob.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Context;
+}
+
+namespace Kleo {
+
+ class QGpgMEVerifyOpaqueJob : public VerifyOpaqueJob, private QGpgMEJob {
+ Q_OBJECT QGPGME_JOB
+ public:
+ QGpgMEVerifyOpaqueJob( GpgME::Context * context );
+ ~QGpgMEVerifyOpaqueJob();
+
+ /*! \reimp from VerifyOpaqueJob */
+ GpgME::Error start( const QByteArray & signedData );
+
+ /*! \reimp form VerifyOpaqueJob */
+ GpgME::VerificationResult exec( const QByteArray & signedData, QByteArray & plainData );
+
+ private slots:
+ void slotOperationDoneEvent( GpgME::Context * context, const GpgME::Error & e ) {
+ QGpgMEJob::doSlotOperationDoneEvent( context, e );
+ }
+
+ private:
+ void doOperationDoneEvent( const GpgME::Error & e );
+ void setup( const QByteArray & );
+ };
+
+}
+
+#endif // __KLEO_QGPGMEVERIFYOPAQUEJOB_H__
diff --git a/certmanager/lib/cryptplug.cpp b/certmanager/lib/cryptplug.cpp
new file mode 100644
index 000000000..f9d1aa632
--- /dev/null
+++ b/certmanager/lib/cryptplug.cpp
@@ -0,0 +1,1123 @@
+/* -*- Mode: C++ -*-
+
+ this is a C++-ification of:
+ GPGMEPLUG - an GPGME based cryptography plug-in following
+ the common CRYPTPLUG specification.
+
+ Copyright (C) 2001 by Klarälvdalens Datakonsult AB
+ Copyright (C) 2002 g10 Code GmbH
+ Copyright (C) 2004 Klarälvdalens Datakonsult AB
+
+ GPGMEPLUG is free software; you can redistribute it and/or modify
+ it under the terms of GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ GPGMEPLUG is distributed in the hope that it will be useful,
+ it under the terms of GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kleo/oidmap.h"
+
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+#include <gpgmepp/importresult.h>
+
+/*! \file gpgmeplug.c
+ \brief GPGME implementation of CRYPTPLUG following the
+ specification located in common API header cryptplug.h.
+
+ CRYPTPLUG is an independent cryptography plug-in API
+ developed for Sphinx-enabeling KMail and Mutt.
+
+ CRYPTPLUG was designed for the Aegypten project, but it may
+ be used by 3rd party developers as well to design pluggable
+ crypto backends for the above mentioned MUAs.
+
+ \note All string parameters appearing in this API are to be
+ interpreted as UTF-8 encoded.
+
+ \see cryptplug.h
+*/
+
+#include <qstring.h>
+
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <iostream>
+#include <memory>
+
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <assert.h>
+#include <errno.h>
+#include <time.h>
+#include <ctype.h>
+#include <locale.h>
+
+#define __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO "Error: Cannot run checkMessageSignature() with cleartext == 0"
+
+/* Note: The following specification will result in
+ function encryptAndSignMessage() producing
+ _empty_ mails.
+ This must be changed as soon as our plugin
+ is supporting the encryptAndSignMessage() function. */
+#ifndef GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT
+#define GPGMEPLUG_ENCSIGN_INCLUDE_CLEARTEXT false
+#define GPGMEPLUG_ENCSIGN_MAKE_MIME_OBJECT false
+#define GPGMEPLUG_ENCSIGN_MAKE_MULTI_MIME false
+#define GPGMEPLUG_ENCSIGN_CTYPE_MAIN ""
+#define GPGMEPLUG_ENCSIGN_CDISP_MAIN ""
+#define GPGMEPLUG_ENCSIGN_CTENC_MAIN ""
+#define GPGMEPLUG_ENCSIGN_CTYPE_VERSION ""
+#define GPGMEPLUG_ENCSIGN_CDISP_VERSION ""
+#define GPGMEPLUG_ENCSIGN_CTENC_VERSION ""
+#define GPGMEPLUG_ENCSIGN_BTEXT_VERSION ""
+#define GPGMEPLUG_ENCSIGN_CTYPE_CODE ""
+#define GPGMEPLUG_ENCSIGN_CDISP_CODE ""
+#define GPGMEPLUG_ENCSIGN_CTENC_CODE ""
+#define GPGMEPLUG_ENCSIGN_FLAT_PREFIX ""
+#define GPGMEPLUG_ENCSIGN_FLAT_SEPARATOR ""
+#define GPGMEPLUG_ENCSIGN_FLAT_POSTFIX ""
+#endif
+
+#include "cryptplug.h"
+#include <kdebug.h>
+
+SMIMECryptPlug::SMIMECryptPlug() : CryptPlug() {
+ GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_CMS;
+ mProtocol = GpgME::Context::CMS;
+
+ /* definitions for signing */
+ // 1. opaque signatures (only used for S/MIME)
+ GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT = false;
+ GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT = true;
+ GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME = false;
+ GPGMEPLUG_OPA_SIGN_CTYPE_MAIN = "application/pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"";
+ GPGMEPLUG_OPA_SIGN_CDISP_MAIN = "attachment; filename=\"smime.p7m\"";
+ GPGMEPLUG_OPA_SIGN_CTENC_MAIN = "base64";
+ GPGMEPLUG_OPA_SIGN_CTYPE_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CDISP_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CTENC_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_BTEXT_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CTYPE_CODE = "";
+ GPGMEPLUG_OPA_SIGN_CDISP_CODE = "";
+ GPGMEPLUG_OPA_SIGN_CTENC_CODE = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_PREFIX = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX = "";
+ // 2. detached signatures (used for S/MIME and for OpenPGP)
+ GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT = true;
+ GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT = true;
+ GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME = true;
+ GPGMEPLUG_DET_SIGN_CTYPE_MAIN = "multipart/signed; protocol=\"application/pkcs7-signature\"; micalg=sha1";
+ GPGMEPLUG_DET_SIGN_CDISP_MAIN = "";
+ GPGMEPLUG_DET_SIGN_CTENC_MAIN = "";
+ GPGMEPLUG_DET_SIGN_CTYPE_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CDISP_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CTENC_VERSION = "";
+ GPGMEPLUG_DET_SIGN_BTEXT_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CTYPE_CODE = "application/pkcs7-signature; name=\"smime.p7s\"";
+ GPGMEPLUG_DET_SIGN_CDISP_CODE = "attachment; filename=\"smime.p7s\"";
+ GPGMEPLUG_DET_SIGN_CTENC_CODE = "base64";
+ GPGMEPLUG_DET_SIGN_FLAT_PREFIX = "";
+ GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR = "";
+ GPGMEPLUG_DET_SIGN_FLAT_POSTFIX = "";
+ // 3. common definitions for opaque and detached signing
+ __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY = true;
+
+ /* definitions for encoding */
+ GPGMEPLUG_ENC_INCLUDE_CLEARTEXT = false;
+ GPGMEPLUG_ENC_MAKE_MIME_OBJECT = true;
+ GPGMEPLUG_ENC_MAKE_MULTI_MIME = false;
+ GPGMEPLUG_ENC_CTYPE_MAIN = "application/pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"";
+ GPGMEPLUG_ENC_CDISP_MAIN = "attachment; filename=\"smime.p7m\"";
+ GPGMEPLUG_ENC_CTENC_MAIN = "base64";
+ GPGMEPLUG_ENC_CTYPE_VERSION = "";
+ GPGMEPLUG_ENC_CDISP_VERSION = "";
+ GPGMEPLUG_ENC_CTENC_VERSION = "";
+ GPGMEPLUG_ENC_BTEXT_VERSION = "";
+ GPGMEPLUG_ENC_CTYPE_CODE = "";
+ GPGMEPLUG_ENC_CDISP_CODE = "";
+ GPGMEPLUG_ENC_CTENC_CODE = "";
+ GPGMEPLUG_ENC_FLAT_PREFIX = "";
+ GPGMEPLUG_ENC_FLAT_SEPARATOR = "";
+ GPGMEPLUG_ENC_FLAT_POSTFIX = "";
+ __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY = true;
+}
+
+OpenPGPCryptPlug::OpenPGPCryptPlug() : CryptPlug() {
+ GPGMEPLUG_PROTOCOL = GPGME_PROTOCOL_OpenPGP;
+ mProtocol = GpgME::Context::OpenPGP;
+
+ /* definitions for signing */
+ // 1. opaque signatures (only used for S/MIME)
+ GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT = false;
+ GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT = false;
+ GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME = false;
+ GPGMEPLUG_OPA_SIGN_CTYPE_MAIN = "";
+ GPGMEPLUG_OPA_SIGN_CDISP_MAIN = "";
+ GPGMEPLUG_OPA_SIGN_CTENC_MAIN = "";
+ GPGMEPLUG_OPA_SIGN_CTYPE_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CDISP_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CTENC_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_BTEXT_VERSION = "";
+ GPGMEPLUG_OPA_SIGN_CTYPE_CODE = "";
+ GPGMEPLUG_OPA_SIGN_CDISP_CODE = "";
+ GPGMEPLUG_OPA_SIGN_CTENC_CODE = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_PREFIX = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR = "";
+ GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX = "";
+ // 2. detached signatures (used for S/MIME and for OpenPGP)
+ GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT = true;
+ GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT = true;
+ GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME = true;
+ GPGMEPLUG_DET_SIGN_CTYPE_MAIN = "multipart/signed; protocol=\"application/pgp-signature\"; micalg=pgp-sha1";
+ GPGMEPLUG_DET_SIGN_CDISP_MAIN = "";
+ GPGMEPLUG_DET_SIGN_CTENC_MAIN = "";
+ GPGMEPLUG_DET_SIGN_CTYPE_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CDISP_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CTENC_VERSION = "";
+ GPGMEPLUG_DET_SIGN_BTEXT_VERSION = "";
+ GPGMEPLUG_DET_SIGN_CTYPE_CODE = "application/pgp-signature";
+ GPGMEPLUG_DET_SIGN_CDISP_CODE = "";
+ GPGMEPLUG_DET_SIGN_CTENC_CODE = "";
+ GPGMEPLUG_DET_SIGN_FLAT_PREFIX = "";
+ GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR = "";
+ GPGMEPLUG_DET_SIGN_FLAT_POSTFIX = "";
+ // 3. common definitions for opaque and detached signing
+ __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY = false;
+
+ /* definitions for encoding */
+ GPGMEPLUG_ENC_INCLUDE_CLEARTEXT = false;
+ GPGMEPLUG_ENC_MAKE_MIME_OBJECT = true;
+ GPGMEPLUG_ENC_MAKE_MULTI_MIME = true;
+ GPGMEPLUG_ENC_CTYPE_MAIN = "multipart/encrypted; protocol=\"application/pgp-encrypted\"";
+ GPGMEPLUG_ENC_CDISP_MAIN = "";
+ GPGMEPLUG_ENC_CTENC_MAIN = "";
+ GPGMEPLUG_ENC_CTYPE_VERSION = "application/pgp-encrypted";
+ GPGMEPLUG_ENC_CDISP_VERSION = "attachment";
+ GPGMEPLUG_ENC_CTENC_VERSION = "";
+ GPGMEPLUG_ENC_BTEXT_VERSION = "Version: 1";
+ GPGMEPLUG_ENC_CTYPE_CODE = "application/octet-stream";
+ GPGMEPLUG_ENC_CDISP_CODE = "inline; filename=\"msg.asc\"";
+ GPGMEPLUG_ENC_CTENC_CODE = "";
+ GPGMEPLUG_ENC_FLAT_PREFIX = "";
+ GPGMEPLUG_ENC_FLAT_SEPARATOR = "";
+ GPGMEPLUG_ENC_FLAT_POSTFIX = "";
+ __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY = false;
+}
+
+#define days_from_seconds(x) ((x)/86400)
+
+/* Max number of parts in a DN */
+#define MAX_GPGME_IDX 20
+
+/* some macros to replace ctype ones and avoid locale problems */
+#define spacep(p) (*(p) == ' ' || *(p) == '\t')
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+/* the atoi macros assume that the buffer has only valid digits */
+#define atoi_1(p) (*(p) - '0' )
+#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1))
+#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+static void *
+xmalloc (size_t n)
+{
+ void *p = malloc (n);
+ if (!p)
+ {
+ fputs ("\nfatal: out of core\n", stderr);
+ exit (4);
+ }
+ return p;
+}
+
+/* Please: Don't call an allocation function xfoo when it may return NULL. */
+/* Wrong: #define xstrdup( x ) (x)?strdup(x):0 */
+/* Right: */
+static char *
+xstrdup (const char *string)
+{
+ char *p = (char*)xmalloc (strlen (string)+1);
+ strcpy (p, string);
+ return p;
+}
+
+
+CryptPlug::CryptPlug() {
+}
+
+CryptPlug::~CryptPlug() {
+}
+
+bool CryptPlug::initialize() {
+ GpgME::setDefaultLocale( LC_CTYPE, setlocale( LC_CTYPE, 0 ) );
+ GpgME::setDefaultLocale( LC_MESSAGES, setlocale( LC_MESSAGES, 0 ) );
+ return (gpgme_engine_check_version (GPGMEPLUG_PROTOCOL) == GPG_ERR_NO_ERROR);
+}
+
+
+bool CryptPlug::hasFeature( Feature flag )
+{
+ /* our own plugins are supposed to support everything */
+ switch ( flag ) {
+ case Feature_SignMessages:
+ case Feature_VerifySignatures:
+ case Feature_EncryptMessages:
+ case Feature_DecryptMessages:
+ case Feature_SendCertificates:
+ case Feature_PinEntrySettings:
+ case Feature_StoreMessagesWithSigs:
+ case Feature_EncryptionCRLs:
+ case Feature_StoreMessagesEncrypted:
+ case Feature_CheckCertificatePath:
+ return true;
+ case Feature_WarnSignCertificateExpiry:
+ case Feature_WarnSignEmailNotInCertificate:
+ case Feature_WarnEncryptCertificateExpiry:
+ case Feature_WarnEncryptEmailNotInCertificate:
+ return GPGMEPLUG_PROTOCOL == GPGME_PROTOCOL_CMS;
+ /* undefined or not yet implemented: */
+ case Feature_CRLDirectoryService:
+ case Feature_CertificateDirectoryService:
+ case Feature_undef:
+ default:
+ return false;
+ }
+}
+
+
+static
+void storeNewCharPtr( char** dest, const char* src )
+{
+ int sLen = strlen( src );
+ *dest = (char*)xmalloc( sLen + 1 );
+ strcpy( *dest, src );
+}
+
+bool CryptPlug::decryptMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ const char** cleartext,
+ const char* /*certificate*/,
+ int* errId,
+ char** errTxt )
+{
+ gpgme_ctx_t ctx;
+ gpgme_error_t err;
+ gpgme_data_t gCiphertext, gPlaintext;
+ size_t rCLen = 0;
+ char* rCiph = 0;
+ bool bOk = false;
+
+ if( !ciphertext )
+ return false;
+
+ err = gpgme_new (&ctx);
+ gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
+
+ gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
+ /* gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */
+
+ /*
+ gpgme_data_new_from_mem( &gCiphertext, ciphertext,
+ 1+strlen( ciphertext ), 1 ); */
+ gpgme_data_new_from_mem( &gCiphertext,
+ ciphertext,
+ cipherIsBinary
+ ? cipherLen
+ : strlen( ciphertext ),
+ 1 );
+
+ gpgme_data_new( &gPlaintext );
+
+ err = gpgme_op_decrypt( ctx, gCiphertext, gPlaintext );
+ if( err ) {
+ fprintf( stderr, "\ngpgme_op_decrypt() returned this error code: %i\n\n", err );
+ if( errId )
+ *errId = err;
+ if( errTxt ) {
+ const char* _errTxt = gpgme_strerror( err );
+ *errTxt = (char*)malloc( strlen( _errTxt ) + 1 );
+ if( *errTxt )
+ strcpy(*errTxt, _errTxt );
+ }
+ }
+
+ gpgme_data_release( gCiphertext );
+
+ rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
+
+ *cleartext = (char*)malloc( rCLen + 1 );
+ if( *cleartext ) {
+ if( rCLen ) {
+ bOk = true;
+ strncpy((char*)*cleartext, rCiph, rCLen );
+ }
+ ((char*)(*cleartext))[rCLen] = 0;
+ }
+
+ free( rCiph );
+ gpgme_release( ctx );
+ return bOk;
+}
+
+
+static char *
+trim_trailing_spaces( char *string )
+{
+ char *p, *mark;
+
+ for( mark = NULL, p = string; *p; p++ ) {
+ if( isspace( *p ) ) {
+ if( !mark )
+ mark = p;
+ }
+ else
+ mark = NULL;
+ }
+ if( mark )
+ *mark = '\0' ;
+
+ return string ;
+}
+
+/* Parse a DN and return an array-ized one. This is not a validating
+ parser and it does not support any old-stylish syntax; gpgme is
+ expected to return only rfc2253 compatible strings. */
+static const unsigned char *
+parse_dn_part (CryptPlug::DnPair *array, const unsigned char *string)
+{
+ const unsigned char *s, *s1;
+ size_t n;
+ char *p;
+
+ /* parse attributeType */
+ for (s = string+1; *s && *s != '='; s++)
+ ;
+ if (!*s)
+ return NULL; /* error */
+ n = s - string;
+ if (!n)
+ return NULL; /* empty key */
+ p = (char*)xmalloc (n+1);
+
+
+ memcpy (p, string, n);
+ p[n] = 0;
+ trim_trailing_spaces ((char*)p);
+ // map OIDs to their names:
+ for ( unsigned int i = 0 ; i < numOidMaps ; ++i )
+ if ( !strcasecmp ((char*)p, oidmap[i].oid) ) {
+ free( p );
+ p = xstrdup (oidmap[i].name);
+ break;
+ }
+ array->key = p;
+ string = s + 1;
+
+ if (*string == '#')
+ { /* hexstring */
+ string++;
+ for (s=string; hexdigitp (s); s++)
+ s++;
+ n = s - string;
+ if (!n || (n & 1))
+ return NULL; /* empty or odd number of digits */
+ n /= 2;
+ array->value = p = (char*)xmalloc (n+1);
+
+
+ for (s1=string; n; s1 += 2, n--)
+ *p++ = xtoi_2 (s1);
+ *p = 0;
+ }
+ else
+ { /* regular v3 quoted string */
+ for (n=0, s=string; *s; s++)
+ {
+ if (*s == '\\')
+ { /* pair */
+ s++;
+ if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';'
+ || *s == '\\' || *s == '\"' || *s == ' ')
+ n++;
+ else if (hexdigitp (s) && hexdigitp (s+1))
+ {
+ s++;
+ n++;
+ }
+ else
+ return NULL; /* invalid escape sequence */
+ }
+ else if (*s == '\"')
+ return NULL; /* invalid encoding */
+ else if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';' )
+ break;
+ else
+ n++;
+ }
+
+ array->value = p = (char*)xmalloc (n+1);
+
+
+ for (s=string; n; s++, n--)
+ {
+ if (*s == '\\')
+ {
+ s++;
+ if (hexdigitp (s))
+ {
+ *p++ = xtoi_2 (s);
+ s++;
+ }
+ else
+ *p++ = *s;
+ }
+ else
+ *p++ = *s;
+ }
+ *p = 0;
+ }
+ return s;
+}
+
+
+/* Parse a DN and return an array-ized one. This is not a validating
+ parser and it does not support any old-stylish syntax; gpgme is
+ expected to return only rfc2253 compatible strings. */
+static CryptPlug::DnPair *
+parse_dn (const unsigned char *string)
+{
+ struct CryptPlug::DnPair *array;
+ size_t arrayidx, arraysize;
+
+ if( !string )
+ return NULL;
+
+ arraysize = 7; /* C,ST,L,O,OU,CN,email */
+ arrayidx = 0;
+ array = (CryptPlug::DnPair*)xmalloc ((arraysize+1) * sizeof *array);
+
+
+ while (*string)
+ {
+ while (*string == ' ')
+ string++;
+ if (!*string)
+ break; /* ready */
+ if (arrayidx >= arraysize)
+ { /* mutt lacks a real safe_realoc - so we need to copy */
+ struct CryptPlug::DnPair *a2;
+
+ arraysize += 5;
+ a2 = (CryptPlug::DnPair*)xmalloc ((arraysize+1) * sizeof *array);
+ for (unsigned int i=0; i < arrayidx; i++)
+ {
+ a2[i].key = array[i].key;
+ a2[i].value = array[i].value;
+ }
+ free (array);
+ array = a2;
+ }
+ array[arrayidx].key = NULL;
+ array[arrayidx].value = NULL;
+ string = parse_dn_part (array+arrayidx, string);
+ arrayidx++;
+ if (!string)
+ goto failure;
+ while (*string == ' ')
+ string++;
+ if (*string && *string != ',' && *string != ';' && *string != '+')
+ goto failure; /* invalid delimiter */
+ if (*string)
+ string++;
+ }
+ array[arrayidx].key = NULL;
+ array[arrayidx].value = NULL;
+ return array;
+
+ failure:
+ for (unsigned i=0; i < arrayidx; i++)
+ {
+ free (array[i].key);
+ free (array[i].value);
+ }
+ free (array);
+ return NULL;
+}
+
+static void
+add_dn_part( QCString& result, struct CryptPlug::DnPair& dnPair )
+{
+ /* email hack */
+ QCString mappedPart( dnPair.key );
+ for ( unsigned int i = 0 ; i < numOidMaps ; ++i ){
+ if( !strcasecmp( dnPair.key, oidmap[i].oid ) ) {
+ mappedPart = oidmap[i].name;
+ break;
+ }
+ }
+ result.append( mappedPart );
+ result.append( "=" );
+ result.append( dnPair.value );
+}
+
+static int
+add_dn_parts( QCString& result, struct CryptPlug::DnPair* dn, const char* part )
+{
+ int any = 0;
+
+ if( dn ) {
+ for(; dn->key; ++dn ) {
+ if( !strcmp( dn->key, part ) ) {
+ if( any )
+ result.append( "," );
+ add_dn_part( result, *dn );
+ any = 1;
+ }
+ }
+ }
+ return any;
+}
+
+static char*
+reorder_dn( struct CryptPlug::DnPair *dn,
+ char** attrOrder = 0,
+ const char* unknownAttrsHandling = 0 )
+{
+ struct CryptPlug::DnPair *dnOrg = dn;
+
+ /* note: The must parts are: CN, L, OU, O, C */
+ const char* defaultpart[] = {
+ "CN", "S", "SN", "GN", "T", "UID",
+ "MAIL", "EMAIL", "MOBILE", "TEL", "FAX", "STREET",
+ "L", "PC", "SP", "ST",
+ "OU",
+ "O",
+ "C",
+ NULL
+ };
+ const char** stdpart = attrOrder ? ((const char**)attrOrder) : defaultpart;
+ int any=0, any2=0, found_X_=0, i;
+ QCString result;
+ QCString resultUnknowns;
+
+ /* find and save the non-standard parts in their original order */
+ if( dn ){
+ for(; dn->key; ++dn ) {
+ for( i = 0; stdpart[i]; ++i ) {
+ if( !strcmp( dn->key, stdpart[i] ) ) {
+ break;
+ }
+ }
+ if( !stdpart[i] ) {
+ if( any2 )
+ resultUnknowns.append( "," );
+ add_dn_part( resultUnknowns, *dn );
+ any2 = 1;
+ }
+ }
+ dn = dnOrg;
+ }
+
+ /* prepend the unknown attrs if desired */
+ if( unknownAttrsHandling &&
+ !strcmp(unknownAttrsHandling, "PREFIX")
+ && *resultUnknowns ){
+ result.append( resultUnknowns );
+ any = 1;
+ }else{
+ any = 0;
+ }
+
+ /* add standard parts */
+ for( i = 0; stdpart[i]; ++i ) {
+ dn = dnOrg;
+ if( any ) {
+ result.append( "," );
+ }
+ if( any2 &&
+ !strcmp(stdpart[i], "_X_") &&
+ unknownAttrsHandling &&
+ !strcmp(unknownAttrsHandling, "INFIX") ){
+ if ( !resultUnknowns.isEmpty() ) {
+ result.append( resultUnknowns );
+ any = 1;
+ }
+ found_X_ = 1;
+ }else{
+ any = add_dn_parts( result, dn, stdpart[i] );
+ }
+ }
+
+ /* append the unknown attrs if desired */
+ if( !unknownAttrsHandling ||
+ !strcmp(unknownAttrsHandling, "POSTFIX") ||
+ ( !strcmp(unknownAttrsHandling, "INFIX") && !found_X_ ) ){
+ if( !resultUnknowns.isEmpty() ) {
+ if( any ){
+ result.append( "," );
+ }
+ result.append( resultUnknowns );
+ }
+ }
+
+ char* cResult = (char*)xmalloc( (result.length()+1)*sizeof(char) );
+ if( result.isEmpty() )
+ *cResult = 0;
+ else
+ strcpy( cResult, result );
+ return cResult;
+}
+
+GpgME::ImportResult CryptPlug::importCertificateFromMem( const char* data, size_t length )
+{
+ using namespace GpgME;
+
+ std::auto_ptr<Context> context( Context::createForProtocol( mProtocol ) );
+ if ( !context.get() )
+ return ImportResult();
+
+ Data keydata( data, length, false );
+ if ( keydata.isNull() )
+ return ImportResult();
+
+ return context->importKeys( keydata );
+}
+
+
+/* == == == == == == == == == == == == == == == == == == == == == == == == ==
+ == ==
+ == Continuation of CryptPlug code ==
+ == ==
+== == == == == == == == == == == == == == == == == == == == == == == == == */
+
+// these are from gpgme-0.4.3:
+static gpgme_sig_stat_t
+sig_stat_from_status( gpgme_error_t err )
+{
+ switch ( gpg_err_code(err) ) {
+ case GPG_ERR_NO_ERROR:
+ return GPGME_SIG_STAT_GOOD;
+ case GPG_ERR_BAD_SIGNATURE:
+ return GPGME_SIG_STAT_BAD;
+ case GPG_ERR_NO_PUBKEY:
+ return GPGME_SIG_STAT_NOKEY;
+ case GPG_ERR_NO_DATA:
+ return GPGME_SIG_STAT_NOSIG;
+ case GPG_ERR_SIG_EXPIRED:
+ return GPGME_SIG_STAT_GOOD_EXP;
+ case GPG_ERR_KEY_EXPIRED:
+ return GPGME_SIG_STAT_GOOD_EXPKEY;
+ default:
+ return GPGME_SIG_STAT_ERROR;
+ }
+}
+
+
+static gpgme_sig_stat_t
+intersect_stati( gpgme_signature_t first )
+{
+ if ( !first )
+ return GPGME_SIG_STAT_NONE;
+ gpgme_sig_stat_t result = sig_stat_from_status( first->status );
+ for ( gpgme_signature_t sig = first->next ; sig ; sig = sig->next )
+ if ( sig_stat_from_status( sig->status ) != result )
+ return GPGME_SIG_STAT_DIFF;
+ return result;
+}
+
+static const char*
+sig_status_to_string( gpgme_sig_stat_t status )
+{
+ const char *result;
+
+ switch (status) {
+ case GPGME_SIG_STAT_NONE:
+ result = "Oops: Signature not verified";
+ break;
+ case GPGME_SIG_STAT_NOSIG:
+ result = "No signature found";
+ break;
+ case GPGME_SIG_STAT_GOOD:
+ result = "Good signature";
+ break;
+ case GPGME_SIG_STAT_BAD:
+ result = "BAD signature";
+ break;
+ case GPGME_SIG_STAT_NOKEY:
+ result = "No public key to verify the signature";
+ break;
+ case GPGME_SIG_STAT_ERROR:
+ result = "Error verifying the signature";
+ break;
+ case GPGME_SIG_STAT_DIFF:
+ result = "Different results for signatures";
+ break;
+ default:
+ result = "Error: Unknown status";
+ break;
+ }
+
+ return result;
+}
+
+// WARNING: if you fix a bug here, you have to likely fix it in the
+// gpgme 0.3 version below, too!
+static
+void obtain_signature_information( gpgme_ctx_t ctx,
+ gpgme_sig_stat_t & overallStatus,
+ struct CryptPlug::SignatureMetaData* sigmeta,
+ char** attrOrder,
+ const char* unknownAttrsHandling,
+ bool * signatureFound=0 )
+{
+ gpgme_error_t err;
+ unsigned long sumGPGME;
+ SigStatusFlags sumPlug;
+ struct CryptPlug::DnPair* a;
+ int sig_idx=0;
+
+ assert( ctx );
+ assert( sigmeta );
+
+ sigmeta->extended_info = 0;
+ gpgme_verify_result_t result = gpgme_op_verify_result( ctx );
+ if ( !result )
+ return;
+ for ( gpgme_signature_t signature = result->signatures ; signature ; signature = signature->next, ++sig_idx ) {
+ void* alloc_return = realloc( sigmeta->extended_info,
+ sizeof( CryptPlug::SignatureMetaDataExtendedInfo )
+ * ( sig_idx + 1 ) );
+ if ( !alloc_return )
+ break;
+ sigmeta->extended_info = (CryptPlug::SignatureMetaDataExtendedInfo*)alloc_return;
+
+ /* shorthand notation :) */
+ CryptPlug::SignatureMetaDataExtendedInfo & this_info = sigmeta->extended_info[sig_idx];
+
+ /* clear the data area */
+ memset( &this_info, 0, sizeof (CryptPlug::SignatureMetaDataExtendedInfo) );
+
+ /* the creation time */
+ if ( signature->timestamp ) {
+ this_info.creation_time = (tm*)malloc( sizeof( struct tm ) );
+ if ( this_info.creation_time ) {
+ struct tm * ctime_val = localtime( (time_t*)&signature->timestamp );
+ memcpy( this_info.creation_time,
+ ctime_val, sizeof( struct tm ) );
+ }
+ }
+
+ /* the extended signature verification status */
+ sumGPGME = signature->summary;
+ fprintf( stderr, "gpgmeplug checkMessageSignature status flags: %lX\n", sumGPGME );
+ /* translate GPGME status flags to common CryptPlug status flags */
+ sumPlug = 0;
+#define convert(X) if ( sumGPGME & GPGME_SIGSUM_##X ) sumPlug |= SigStat_##X
+ convert(VALID);
+ convert(GREEN);
+ convert(RED);
+ convert(KEY_REVOKED);
+ convert(KEY_EXPIRED);
+ convert(SIG_EXPIRED);
+ convert(KEY_MISSING);
+ convert(CRL_MISSING);
+ convert(CRL_TOO_OLD);
+ convert(BAD_POLICY);
+ convert(SYS_ERROR);
+#undef convert
+ if( sumGPGME && !sumPlug )
+ sumPlug = SigStat_NUMERICAL_CODE | sumGPGME;
+ this_info.sigStatusFlags = sumPlug;
+
+ /* extract finger print */
+ if ( signature->fpr )
+ storeNewCharPtr( &this_info.fingerprint, signature->fpr );
+
+ /* validity */
+ this_info.validity = GPGME_VALIDITY_UNKNOWN;
+
+ /* sig key data */
+ gpgme_key_t key = 0;
+ // PENDING(marc) if this is deprecated, how shall we get at all
+ // the infos below?
+ err = gpgme_get_sig_key (ctx, sig_idx, &key);
+
+ if ( !err && key ) {
+ const char* attr_string;
+ unsigned long attr_ulong;
+
+ /* extract key identidy */
+ attr_string = key->subkeys ? key->subkeys->keyid : 0 ;
+ if ( attr_string )
+ storeNewCharPtr( &this_info.keyid, attr_string );
+
+ /* pubkey algorithm */
+ attr_string = key->subkeys ? gpgme_pubkey_algo_name( key->subkeys->pubkey_algo ) : 0 ;
+ if (attr_string != 0)
+ storeNewCharPtr( &this_info.algo, attr_string );
+ attr_ulong = key->subkeys ? key->subkeys->pubkey_algo : 0 ;
+ this_info.algo_num = attr_ulong;
+
+ /* extract key validity */
+ attr_ulong = key->uids ? key->uids->validity : 0 ;
+ this_info.validity = attr_ulong;
+
+ /* extract user id, according to the documentation it's representable
+ * as a number, but it seems that it also has a string representation
+ */
+ attr_string = key->uids ? key->uids->uid : 0 ;
+ if (attr_string != 0) {
+ a = parse_dn( (const unsigned char*)attr_string );
+ this_info.userid = reorder_dn( a, attrOrder, unknownAttrsHandling );
+ }
+
+ attr_ulong = 0;
+ this_info.userid_num = attr_ulong;
+
+ /* extract the length */
+ this_info.keylen = key->subkeys ? key->subkeys->length : 0 ;
+
+ /* extract the creation time of the key */
+ attr_ulong = key->subkeys ? key->subkeys->timestamp : 0 ;
+ this_info.key_created = attr_ulong;
+
+ /* extract the expiration time of the key */
+ attr_ulong = key->subkeys ? key->subkeys->expires : 0 ;
+ this_info.key_expires = attr_ulong;
+
+ /* extract user name */
+ attr_string = key->uids ? key->uids->name : 0 ;
+ if (attr_string != 0) {
+ a = parse_dn( (const unsigned char*)attr_string );
+ this_info.name = reorder_dn( a, attrOrder, unknownAttrsHandling );
+ }
+
+ /* extract email(s) */
+ this_info.emailCount = 0;
+ this_info.emailList = 0;
+ for ( gpgme_user_id_t uid = key->uids ; uid ; uid = uid->next ) {
+ attr_string = uid->email;
+ if ( attr_string && *attr_string) {
+ fprintf( stderr, "gpgmeplug checkMessageSignature found email: %s\n", attr_string );
+ if( !this_info.emailCount )
+ alloc_return = malloc( sizeof( char*) );
+ else
+ alloc_return = realloc( this_info.emailList,
+ sizeof( char*)
+ * (this_info.emailCount + 1) );
+ if( alloc_return ) {
+ this_info.emailList = (char**)alloc_return;
+ storeNewCharPtr( &( this_info.emailList[ this_info.emailCount ] ),
+ attr_string );
+ ++this_info.emailCount;
+ }
+ }
+ }
+ if( !this_info.emailCount )
+ fprintf( stderr, "gpgmeplug checkMessageSignature found NO EMAIL\n" );
+
+ /* extract the comment */
+ attr_string = key->uids ? key->uids->comment : 0 ;
+ if (attr_string != 0)
+ storeNewCharPtr( &this_info.comment, attr_string );
+ }
+
+ gpgme_sig_stat_t status = sig_stat_from_status( signature->status );
+ const char* sig_status = sig_status_to_string( status );
+ storeNewCharPtr( &this_info.status_text, sig_status );
+ }
+ sigmeta->extended_info_count = sig_idx;
+ overallStatus = intersect_stati( result->signatures );
+ sigmeta->status_code = overallStatus;
+ storeNewCharPtr( &sigmeta->status, sig_status_to_string( overallStatus ) );
+ if ( signatureFound )
+ *signatureFound = ( overallStatus != GPGME_SIG_STAT_NONE );
+}
+
+bool CryptPlug::checkMessageSignature( char** cleartext,
+ const char* signaturetext,
+ bool signatureIsBinary,
+ int signatureLen,
+ struct CryptPlug::SignatureMetaData* sigmeta,
+ char** attrOrder,
+ const char* unknownAttrsHandling )
+{
+ gpgme_ctx_t ctx;
+ gpgme_sig_stat_t status = GPGME_SIG_STAT_NONE;
+ gpgme_data_t datapart, sigpart;
+ char* rClear = 0;
+ size_t clearLen;
+ bool isOpaqueSigned;
+
+ if( !cleartext ) {
+ if( sigmeta )
+ storeNewCharPtr( &sigmeta->status,
+ __GPGMEPLUG_ERROR_CLEARTEXT_IS_ZERO );
+
+ return false;
+ }
+
+ isOpaqueSigned = !*cleartext;
+
+ gpgme_new( &ctx );
+ gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
+ gpgme_set_armor (ctx, signatureIsBinary ? 0 : 1);
+ /* gpgme_set_textmode (ctx, signatureIsBinary ? 0 : 1); */
+
+ if( isOpaqueSigned )
+ gpgme_data_new( &datapart );
+ else
+ gpgme_data_new_from_mem( &datapart, *cleartext,
+ strlen( *cleartext ), 1 );
+
+ gpgme_data_new_from_mem( &sigpart,
+ signaturetext,
+ signatureIsBinary
+ ? signatureLen
+ : strlen( signaturetext ),
+ 1 );
+
+ if ( isOpaqueSigned )
+ gpgme_op_verify( ctx, sigpart, 0, datapart );
+ else
+ gpgme_op_verify( ctx, sigpart, datapart, 0 );
+
+ if( isOpaqueSigned ) {
+ rClear = gpgme_data_release_and_get_mem( datapart, &clearLen );
+ *cleartext = (char*)malloc( clearLen + 1 );
+ if( *cleartext ) {
+ if( clearLen )
+ strncpy(*cleartext, rClear, clearLen );
+ (*cleartext)[clearLen] = '\0';
+ }
+ free( rClear );
+ }
+ else
+ gpgme_data_release( datapart );
+
+ gpgme_data_release( sigpart );
+
+ obtain_signature_information( ctx, status, sigmeta,
+ attrOrder, unknownAttrsHandling );
+
+ gpgme_release( ctx );
+ return ( status == GPGME_SIG_STAT_GOOD );
+}
+
+bool CryptPlug::decryptAndCheckMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ const char** cleartext,
+ const char* /*certificate*/,
+ bool* signatureFound,
+ struct CryptPlug::SignatureMetaData* sigmeta,
+ int* errId,
+ char** errTxt,
+ char** attrOrder,
+ const char* unknownAttrsHandling )
+{
+ gpgme_ctx_t ctx;
+ gpgme_error_t err;
+ gpgme_decrypt_result_t decryptresult;
+ gpgme_data_t gCiphertext, gPlaintext;
+ gpgme_sig_stat_t sigstatus = GPGME_SIG_STAT_NONE;
+ size_t rCLen = 0;
+ char* rCiph = 0;
+ bool bOk = false;
+
+ if( !ciphertext )
+ return false;
+
+ err = gpgme_new (&ctx);
+ gpgme_set_protocol (ctx, GPGMEPLUG_PROTOCOL);
+
+ gpgme_set_armor (ctx, cipherIsBinary ? 0 : 1);
+ /* gpgme_set_textmode (ctx, cipherIsBinary ? 0 : 1); */
+
+ /*
+ gpgme_data_new_from_mem( &gCiphertext, ciphertext,
+ 1+strlen( ciphertext ), 1 ); */
+ gpgme_data_new_from_mem( &gCiphertext,
+ ciphertext,
+ cipherIsBinary
+ ? cipherLen
+ : strlen( ciphertext ),
+ 1 );
+
+ gpgme_data_new( &gPlaintext );
+
+ err = gpgme_op_decrypt_verify( ctx, gCiphertext, gPlaintext );
+ gpgme_data_release( gCiphertext );
+
+ if( err ) {
+ fprintf( stderr, "\ngpgme_op_decrypt_verify() returned this error code: %i\n\n", err );
+ if( errId )
+ *errId = err;
+ if( errTxt ) {
+ const char* _errTxt = gpgme_strerror( err );
+ *errTxt = (char*)malloc( strlen( _errTxt ) + 1 );
+ if( *errTxt )
+ strcpy(*errTxt, _errTxt );
+ }
+ gpgme_data_release( gPlaintext );
+ gpgme_release( ctx );
+ return bOk;
+ }
+ decryptresult = gpgme_op_decrypt_result( ctx );
+
+ bool bWrongKeyUsage = false;
+#ifdef HAVE_GPGME_WRONG_KEY_USAGE
+ if( decryptresult && decryptresult->wrong_key_usage )
+ bWrongKeyUsage = true;
+#endif
+
+ if( bWrongKeyUsage ) {
+ if( errId )
+ *errId = CRYPTPLUG_ERR_WRONG_KEY_USAGE; // report the wrong key usage
+ }
+
+ rCiph = gpgme_data_release_and_get_mem( gPlaintext, &rCLen );
+
+ *cleartext = (char*)malloc( rCLen + 1 );
+ if( *cleartext ) {
+ if( rCLen ) {
+ bOk = true;
+ strncpy((char*)*cleartext, rCiph, rCLen );
+ }
+ ((char*)(*cleartext))[rCLen] = 0;
+ }
+ free( rCiph );
+
+ obtain_signature_information( ctx, sigstatus, sigmeta,
+ attrOrder, unknownAttrsHandling,
+ signatureFound );
+
+ gpgme_release( ctx );
+ return bOk;
+}
+
diff --git a/certmanager/lib/cryptplug.h b/certmanager/lib/cryptplug.h
new file mode 100644
index 000000000..081702a7a
--- /dev/null
+++ b/certmanager/lib/cryptplug.h
@@ -0,0 +1,954 @@
+/* -*- Mode: C++ -*-
+
+ this is a C++-ification of:
+ CRYPTPLUG - an independent cryptography plug-in API
+
+ Copyright (C) 2001,2004 Klarälvdalens Datakonsult AB
+
+ CRYPTPLUG is free software; you can redistribute it and/or modify
+ it under the terms of GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ CRYPTPLUG is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef CRYPTPLUG_H
+#define CRYPTPLUG_H
+
+#include <stdlib.h>
+
+#include <gpgmepp/context.h>
+#include <gpgme.h> // need it for gpgme_protocol_t :(
+#include <kdepimmacros.h>
+
+namespace GpgME {
+ class ImportResult;
+}
+
+/*! \file cryptplug.h
+ \brief Common API header for CRYPTPLUG.
+
+ CRYPTPLUG is an independent cryptography plug-in API
+ developed for Sphinx-enabeling KMail and Mutt.
+
+ CRYPTPLUG was designed for the Aegypten project, but it may
+ be used by 3rd party developers as well to design pluggable
+ crypto backends for the above mentioned MUAs.
+
+ \note All string parameters appearing in this API are to be
+ interpreted as UTF-8 encoded.
+
+ \see pgpplugin.c
+ \see gpgplugin.c
+*/
+
+/*! \defgroup groupGeneral Loading and Unloading the Plugin, General Functionality
+
+ The functions in this section are used for loading and
+ unloading plugins. Note that the actual locating of the plugin
+ and the loading and unloading of the dynamic library is not
+ covered here; this is MUA-specific code for which support code
+ might already exist in the programming environments.
+*/
+
+/*! \defgroup groupDisplay Graphical Display Functionality
+
+ The functions in this section return stationery that the
+ MUAs can use in order to display security functionality
+ graphically. This can be toolbar icons, shortcuts, tooltips,
+ etc. Not all MUAs will use all this functionality.
+*/
+
+/*! \defgroup groupConfig Configuration Support
+
+ The functions in this section provide the necessary
+ functionality to configure the security functionality as well
+ as to query configuration settings. Since all configuration
+ settings will not be saved with the plugin, but rather with
+ the MUA, there are also functions to set configuration
+ settings programmatically; these will be used on startup of
+ the plugin when the MUA transfers the configuration values it
+ has read into the plugin. Usually, the functions to query and
+ set the configuration values are not needed for anything but
+ saving to and restoring from configuration files.
+*/
+
+
+/*! \defgroup groupConfigSign Signature Configuration
+ \ingroup groupConfig
+
+ The functions in this section provide the functionality
+ to configure signature handling and set and query the
+ signature configuration.
+*/
+
+/*! \defgroup groupConfigCrypt Encryption Configuration
+ \ingroup groupConfig
+
+ The functions in this section provide the functionality
+ to configure encryption handling and set and query the
+ encryption configuration.
+
+ \note Whenever the term <b> encryption</b> is used here,
+ it is supposed to mean both encryption and decryption,
+ unless otherwise specified.
+*/
+
+/*! \defgroup groupConfigDir Directory Service Configuration
+ \ingroup groupConfig
+
+ This section contains messages for configuring the
+ directory service.
+*/
+
+
+/*! \defgroup groupCertHand Certificate Handling
+
+ The following methods are used to maintain and query certificates.
+*/
+
+
+/*! \defgroup groupSignCryptAct Signing and Encrypting Actions
+
+ This section describes methods and structures
+ used for signing and/or encrypting your mails.
+*/
+
+
+/*! \defgroup groupSignAct Signature Actions
+ \ingroup groupSignCryptAct
+
+ This section describes methods that are used for working
+ with signatures.
+*/
+
+/*! \defgroup groupCryptAct Encryption and Decryption
+ \ingroup groupSignCryptAct
+
+ The following methods are used to encrypt and decrypt
+ email messages.
+*/
+
+/*! \defgroup groupCertAct Certificate Handling Actions
+
+ The functions in this section provide local certificate management.
+*/
+
+/*! \defgroup groupCRLAct CRL Handling Actions
+
+ This section describes functions for managing CRLs.
+*/
+
+/*! \defgroup groupAdUsoInterno Important functions to be used by plugin implementors ONLY.
+
+ This section describes functions that have to be used by
+ plugin implementors but should not be used by plugin users
+ directly.
+
+ If you are not planning to write your own cryptography
+ plugin <b>you should ignore this</b> section!
+*/
+
+/*! \defgroup certList Certificate Info listing functions
+ */
+
+typedef enum {
+ Feature_undef = 0,
+
+ Feature_SignMessages = 1,
+ Feature_VerifySignatures = 2,
+ Feature_EncryptMessages = 3,
+ Feature_DecryptMessages = 4,
+ Feature_SendCertificates = 5,
+ Feature_WarnSignCertificateExpiry = 6,
+ Feature_WarnSignEmailNotInCertificate = 7,
+ Feature_PinEntrySettings = 8,
+ Feature_StoreMessagesWithSigs = 9,
+ Feature_EncryptionCRLs = 10,
+ Feature_WarnEncryptCertificateExpiry = 11,
+ Feature_WarnEncryptEmailNotInCertificate = 12,
+ Feature_StoreMessagesEncrypted = 13,
+ Feature_CheckCertificatePath = 14,
+ Feature_CertificateDirectoryService = 15,
+ Feature_CRLDirectoryService = 16,
+ Feature_CertificateInfo = 17
+} Feature;
+
+/* dummy values */
+typedef enum {
+ PinRequest_undef = 0,
+
+ PinRequest_Always = 1,
+ PinRequest_WhenAddingCerts = 2,
+ PinRequest_AlwaysWhenSigning = 3,
+ PinRequest_OncePerSession = 4,
+ PinRequest_AfterMinutes = 5
+} PinRequests;
+
+
+typedef enum {
+ SignatureCompoundMode_undef = 0,
+
+ SignatureCompoundMode_Opaque = 1,
+ SignatureCompoundMode_Detached = 2
+} SignatureCompoundMode;
+
+
+typedef enum {
+ SendCert_undef = 0,
+
+ SendCert_DontSend = 1,
+ SendCert_SendOwn = 2,
+ SendCert_SendChainWithoutRoot = 3,
+ SendCert_SendChainWithRoot = 4
+} SendCertificates;
+
+
+typedef enum {
+ SignAlg_undef = 0,
+
+ SignAlg_SHA1 = 1
+} SignatureAlgorithm;
+
+
+
+typedef enum {
+ EncryptAlg_undef = 0,
+
+ EncryptAlg_RSA = 1,
+ EncryptAlg_SHA1 = 2,
+ EncryptAlg_TripleDES = 3
+} EncryptionAlgorithm;
+
+typedef enum {
+ SignEmail_undef = 0,
+
+ SignEmail_SignAll = 1,
+ SignEmail_Ask = 2,
+ SignEmail_DontSign = 3
+} SignEmail;
+
+typedef enum {
+ EncryptEmail_undef = 0,
+
+ EncryptEmail_EncryptAll = 1,
+ EncryptEmail_Ask = 2,
+ EncryptEmail_DontEncrypt = 3
+} EncryptEmail;
+
+typedef enum {
+ CertSrc_undef = 0,
+
+ CertSrc_Server = 1,
+ CertSrc_Local = 2,
+ CertSrc_ServerLocal = CertSrc_Server | CertSrc_Local
+} CertificateSource;
+
+
+/*! \ingroup groupSignAct
+ \brief Flags used to compose the SigStatusFlags value.
+
+ This status flags are used to compose the SigStatusFlags value
+ returned in \c SignatureMetaDataExtendedInfo after trying to
+ verify a signed message part's signature status.
+
+ The normal flags may <b>not</b> be used together with the
+ special SigStat_NUMERICAL_CODE flag. When finding the special
+ SigStat_NUMERICAL_CODE flag in a SigStatusFlags value you
+ can obtain the respective error code number by substracting
+ the SigStatusFlags value by SigStat_NUMERICAL_CODE: this is
+ used to transport special status information NOT matching
+ any of the normal predefined status codes.
+
+ \note to PlugIn developers: Implementations of the CryptPlug API
+ should try to express their signature states by bit-wise OR'ing
+ the normal SigStatusFlags values. Using the SigStat_NUMERICAL_CODE
+ flag should only be used as for exceptional situations where no
+ other flag(s) could be used. By using the normal status flags your
+ PlugIn's users will be told an understandable description of the
+ status - when using (SigStat_NUMERICAL_CODE + internalCode) they
+ will only be shown the respective code number and have to look
+ into your PlugIn's manual to learn about it's meaning...
+*/
+enum {
+ SigStat_VALID = 0x0001, /* The signature is fully valid */
+ SigStat_GREEN = 0x0002, /* The signature is good. */
+ SigStat_RED = 0x0004, /* The signature is bad. */
+ SigStat_KEY_REVOKED = 0x0010, /* One key has been revoked. */
+ SigStat_KEY_EXPIRED = 0x0020, /* One key has expired. */
+ SigStat_SIG_EXPIRED = 0x0040, /* The signature has expired. */
+ SigStat_KEY_MISSING = 0x0080, /* Can't verify: key missing. */
+ SigStat_CRL_MISSING = 0x0100, /* CRL not available. */
+ SigStat_CRL_TOO_OLD = 0x0200, /* Available CRL is too old. */
+ SigStat_BAD_POLICY = 0x0400, /* A policy was not met. */
+ SigStat_SYS_ERROR = 0x0800, /* A system error occurred. */
+
+ SigStat_NUMERICAL_CODE = 0x8000 /* An other error occurred. */
+};
+typedef unsigned long SigStatusFlags;
+
+class CryptPlugWrapper;
+
+class KDE_EXPORT CryptPlug {
+ friend class CryptPlugWrapper;
+protected:
+ CryptPlug();
+ virtual ~CryptPlug();
+
+ // these must be set by subclasses:
+ gpgme_protocol_t GPGMEPLUG_PROTOCOL;
+ GpgME::Context::Protocol mProtocol;
+
+ /* definitions for signing */
+ // 1. opaque signatures (only used for S/MIME)
+ int GPGMEPLUG_OPA_SIGN_INCLUDE_CLEARTEXT;
+ int GPGMEPLUG_OPA_SIGN_MAKE_MIME_OBJECT;
+ int GPGMEPLUG_OPA_SIGN_MAKE_MULTI_MIME;
+ const char * GPGMEPLUG_OPA_SIGN_CTYPE_MAIN;
+ const char * GPGMEPLUG_OPA_SIGN_CDISP_MAIN;
+ const char * GPGMEPLUG_OPA_SIGN_CTENC_MAIN;
+ const char * GPGMEPLUG_OPA_SIGN_CTYPE_VERSION;
+ const char * GPGMEPLUG_OPA_SIGN_CDISP_VERSION;
+ const char * GPGMEPLUG_OPA_SIGN_CTENC_VERSION;
+ const char * GPGMEPLUG_OPA_SIGN_BTEXT_VERSION;
+ const char * GPGMEPLUG_OPA_SIGN_CTYPE_CODE;
+ const char * GPGMEPLUG_OPA_SIGN_CDISP_CODE;
+ const char * GPGMEPLUG_OPA_SIGN_CTENC_CODE;
+ const char * GPGMEPLUG_OPA_SIGN_FLAT_PREFIX;
+ const char * GPGMEPLUG_OPA_SIGN_FLAT_SEPARATOR;
+ const char * GPGMEPLUG_OPA_SIGN_FLAT_POSTFIX;
+ // 2. detached signatures (used for S/MIME and for OpenPGP)
+ int GPGMEPLUG_DET_SIGN_INCLUDE_CLEARTEXT;
+ int GPGMEPLUG_DET_SIGN_MAKE_MIME_OBJECT;
+ int GPGMEPLUG_DET_SIGN_MAKE_MULTI_MIME;
+ const char * GPGMEPLUG_DET_SIGN_CTYPE_MAIN;
+ const char * GPGMEPLUG_DET_SIGN_CDISP_MAIN;
+ const char * GPGMEPLUG_DET_SIGN_CTENC_MAIN;
+ const char * GPGMEPLUG_DET_SIGN_CTYPE_VERSION;
+ const char * GPGMEPLUG_DET_SIGN_CDISP_VERSION;
+ const char * GPGMEPLUG_DET_SIGN_CTENC_VERSION;
+ const char * GPGMEPLUG_DET_SIGN_BTEXT_VERSION;
+ const char * GPGMEPLUG_DET_SIGN_CTYPE_CODE;
+ const char * GPGMEPLUG_DET_SIGN_CDISP_CODE;
+ const char * GPGMEPLUG_DET_SIGN_CTENC_CODE;
+ const char * GPGMEPLUG_DET_SIGN_FLAT_PREFIX;
+ const char * GPGMEPLUG_DET_SIGN_FLAT_SEPARATOR;
+ const char * GPGMEPLUG_DET_SIGN_FLAT_POSTFIX;
+ // 3. common definitions for opaque and detached signing
+ int __GPGMEPLUG_SIGNATURE_CODE_IS_BINARY;
+
+ /* definitions for encoding */
+ int GPGMEPLUG_ENC_INCLUDE_CLEARTEXT;
+ int GPGMEPLUG_ENC_MAKE_MIME_OBJECT;
+ int GPGMEPLUG_ENC_MAKE_MULTI_MIME;
+ const char * GPGMEPLUG_ENC_CTYPE_MAIN;
+ const char * GPGMEPLUG_ENC_CDISP_MAIN;
+ const char * GPGMEPLUG_ENC_CTENC_MAIN;
+ const char * GPGMEPLUG_ENC_CTYPE_VERSION;
+ const char * GPGMEPLUG_ENC_CDISP_VERSION;
+ const char * GPGMEPLUG_ENC_CTENC_VERSION;
+ const char * GPGMEPLUG_ENC_BTEXT_VERSION;
+ const char * GPGMEPLUG_ENC_CTYPE_CODE;
+ const char * GPGMEPLUG_ENC_CDISP_CODE;
+ const char * GPGMEPLUG_ENC_CTENC_CODE;
+ const char * GPGMEPLUG_ENC_FLAT_PREFIX;
+ const char * GPGMEPLUG_ENC_FLAT_SEPARATOR;
+ const char * GPGMEPLUG_ENC_FLAT_POSTFIX;
+ int __GPGMEPLUG_ENCRYPTED_CODE_IS_BINARY;
+ // end-of(these must be set by subclasses)
+
+public:
+
+#define CRYPTPLUG_CERT_DOES_NEVER_EXPIRE 365000
+#define CRYPTPLUG_ERR_WRONG_KEY_USAGE 0x7070
+
+/*! \ingroup groupGeneral
+ \brief This function sets up all internal structures.
+
+ Plugins that need no initialization should provide an empty
+ implementation. The method returns \c true if the initialization was
+ successful and \c false otherwise. Before this function is called,
+ no other plugin functions should be called; the behavior is
+ undefined in this case.
+
+ \note This function <b>must</b> be implemented by each plug-in using
+ this API specification.
+*/
+bool initialize( void );
+
+/*! \ingroup groupGeneral
+ \brief This function frees all internal structures.
+
+ Plugins that do not keep any internal structures should provide an
+ empty implementation. After this function has been called,
+ no other plugin functions should be called; the behavior is
+ undefined in this case.
+
+ \note This function <b>must</b> be implemented by each plug-in using
+ this API specification.
+*/
+//void deinitialize( void );
+
+/*! \ingroup groupGeneral
+ \brief This function returns \c true if the
+ specified feature is available in the plugin, and
+ \c false otherwise.
+
+ Not all plugins will support all features; a complete Sphinx
+ implementation will support all features contained in the enum,
+ however.
+
+ \note This function <b>must</b> be implemented by each plug-in using
+ this API specification.
+*/
+bool hasFeature( ::Feature );
+
+/*! \ingroup groupSignCryptAct
+ \brief Information record returned by signing and by encrypting
+ functions - this record should be used together with a
+ corresponding \c free_StructuringInfo() function call.
+
+ Use this information to compose a MIME object containing signed
+ and/or encrypted content (or to build a text frame around your
+ flat non-MIME message body, resp.)
+
+ <b>If</b> value returned in \c makeMimeObject is <b>TRUE</b> the
+ text strings returned in \c contentTypeMain and \c contentDispMain
+ and \c contentTEncMain (and, if required, \c content[..]Version and
+ \c bodyTextVersion and \c content[..]Sig) should be used to compose
+ a respective MIME object.<br>
+ If <b>FALSE</b> the texts returned in \c flatTextPrefix and
+ \c flatTextSeparator and \c flatTextPostfix are to be used instead.<br>
+ Allways <b>either</b> the \c content[..] and \c bodyTextVersion
+ parameters <b>or</b> the \c flatText[..] parameters are holding
+ valid data - never both of them may be used simultaneously
+ as plugins will just ignore the parameters not matching their
+ \c makeMimeObject setting.
+
+ When creating your MIME object please observe these common rules:
+ \li Parameters named \c contentType[..] and \c contentDisp[..] and
+ \c contentTEnc[..] will return the values for the respective MIME
+ headers 'Content-Type' and 'Content-Disposition' and
+ 'Content-Transfer-Encoding'. The following applies to these parameters:
+ \li The relevant MIME part may <b>only</b> be created if the respective
+ \c contentType[..] parameter is holding a non-zero-length string. If the
+ \c contentType[..] parameter value is invalid or holding an empty string
+ the respective \c contentDisp[..] and \c contentTEnc[..] parameters
+ should be ignored.
+ \li If the respective \c contentDisp[..] or \c contentTEnc[..] parameter
+ is NULL or holding a zero-length string it is up to you whether you want
+ to add the relevant MIME header yourself, but since it in in the
+ responsibility of the plugin implementors to provide you with all
+ neccessary 'Content-[..]' header information you should <b>not need</b>
+ to define them if they are not returned by the signing or encrypting
+ function - otherwise this may be considered as a bug in the plugin and
+ you could report the missing MIME header information to the address
+ returned by the \c bugURL() function.
+
+ If \c makeMultiMime returns FALSE the \c contentTypeMain returned must
+ not be altered but used to specify a single part mime object holding the
+ code bloc, e.g. this is used for 'enveloped-data' single part MIME
+ objects. In this case you should ignore both the \c content[..]Version
+ and \c content[..]Code parameters.
+
+ If \c makeMultiMime returns TRUE also the following rules apply:
+ \li If \c includeCleartext is TRUE you should include the cleartext
+ as first part of our multipart MIME object, typically this is TRUE
+ when signing mails but FALSE when encrypting.
+ \li The \c contentTypeMain returned typically starts with
+ "multipart/" while providing a "protocol" and a "micalg" parameter: just
+ add an appropriate \c "; boundary=[your \c boundary \c string]" to get
+ the complete Content-Type value to be used for the MIME object embedding
+ both the signed part and the signature part (or - in case of
+ encrypting - the version part and the code part, resp.).
+ \li If \c contentTypeVersion is holding a non-zero-length string an
+ additional MIME part must added immediately before the code part, this
+ version part's MIME headers must have the unaltered values of
+ \c contentTypeVersion and (if they are holding non-zero-length strings)
+ \c contentDispVersion and \c contentTEncVersion, the unaltered contents
+ of \c bodyTextVersion must be it's body.
+ \li The value returned in \c contentTypeCode is specifying the complete
+ Content-Type to be used for this multipart MIME object's signature part
+ (or - in case of encrypting - for the code part following after the
+ version part, resp.), you should not add/change/remove anything here
+ but just use it's unaltered value for specifying the Content-Type header
+ of the respective MIME part.
+ \li The same applies to the \c contentDispCode value: just use it's
+ unaltered value to specify the Content-Disposition header entry of
+ the respective MIME part.
+ \li The same applies to the \c contentTEncCode value: just use it's
+ unaltered value to specify the Content-Transfer-Encoding header of
+ the respective MIME part.
+
+ <b>If</b> value returned in \c makeMimeObject is <b>FALSE</b> the
+ text strings returned in \c flatTextPrefix and \c flatTextPostfix
+ should be used to build a frame around the cleartext and the code
+ bloc holding the signature (or - in case of encrypting - the encoded
+ data bloc, resp.).<br>
+ If \c includeCleartext is TRUE this frame should also include the
+ cleartext as first bloc, this bloc should be divided from the code bloc
+ by the contents of \c flatTextSeparator - typically this is used for
+ signing but not when encrypting.<br>
+ If \c includeCleartext is FALSE you should ignore both the cleartext
+ and the \c flatTextSeparator parameter.
+
+ <b>How to use StructuringInfo data in your program:</b>
+ \li To compose a signed message please act as described below.
+ \li For constructing an encrypted message just replace the
+ \c signMessage() call by the respective \c encryptMessage() call
+ and then proceed exactly the same way.
+ \li In any case make <b>sure</b> to free your \c ciphertext <b>and</b>
+ to call \c free_StructuringInfo() when you are done with processing
+ the data returned by the signing (or encrypting, resp.) function.
+
+\verbatim
+
+ char* ciphertext;
+ StructuringInfo structInf;
+
+ if( ! signMessage( cleartext, &ciphertext, certificate,
+ &structuring ) ) {
+
+ myErrorDialog( "Error: could not sign the message!" );
+
+ } else {
+ if( structInf.makeMimeObject ) {
+
+ // Build the main MIME object.
+ // This is done by
+ // using the header values returned in
+ // structInf.contentTypeMain and in
+ // structInf.contentDispMain and in
+ // structInf.contentTEncMain.
+ ..
+
+ if( ! structInf.makeMultiMime ) {
+
+ // Build the main MIME object's body.
+ // This is done by
+ // using the code bloc returned in
+ // ciphertext.
+ ..
+
+ } else {
+
+ // Build the encapsulated MIME parts.
+ if( structInf.includeCleartext ) {
+
+ // Build a MIME part holding the cleartext.
+ // This is done by
+ // using the original cleartext's headers and by
+ // taking it's original body text.
+ ..
+
+ }
+ if( structInf.contentTypeVersion
+ && 0 < strlen( structInf.contentTypeVersion ) ) {
+
+ // Build a MIME part holding the version information.
+ // This is done by
+ // using the header values returned in
+ // structInf.contentTypeVersion and
+ // structInf.contentDispVersion and
+ // structInf.contentTEncVersion and by
+ // taking the body contents returned in
+ // structInf.bodyTextVersion.
+ ..
+
+ }
+ if( structInf.contentTypeCode
+ && 0 < strlen( structInf.contentTypeCode ) ) {
+
+ // Build a MIME part holding the code information.
+ // This is done by
+ // using the header values returned in
+ // structInf.contentTypeCode and
+ // structInf.contentDispCode and
+ // structInf.contentTEncCode and by
+ // taking the body contents returned in
+ // ciphertext.
+ ..
+
+ } else {
+
+ // Plugin error!
+ myErrorDialog( "Error: Cryptography plugin returned a main"
+ "Content-Type=Multipart/.. but did not "
+ "specify the code bloc's Content-Type header."
+ "\nYou may report this bug:"
+ "\n" + cryptplug.bugURL() );
+ }
+ }
+ } else {
+
+ // Build a plain message body
+ // based on the values returned in structInf.
+ // Note: We do _not_ insert line breaks between the parts since
+ // it is the plugin job to provide us with ready-to-use
+ // texts containing all neccessary line breaks.
+ strcpy( myMessageBody, structInf.plainTextPrefix );
+ if( structInf.includeCleartext ) {
+ strcat( myMessageBody, cleartext );
+ strcat( myMessageBody, structInf.plainTextSeparator );
+ }
+ strcat( myMessageBody, *ciphertext );
+ strcat( myMessageBody, structInf.plainTextPostfix );
+ }
+
+ // free the memory that was allocated
+ // for the ciphertext
+ free( ciphertext );
+
+ // free the memory that was allocated
+ // for our StructuringInfo's char* members
+ free_StructuringInfo( &structuring );
+ }
+
+\endverbatim
+
+ \note Make sure to call \c free_StructuringInfo() when you are done
+ with processing the StructuringInfo data!
+
+ \see free_StructuringInfo
+ \see signMessage, encryptMessage, encryptAndSignMessage
+*/
+struct StructuringInfo {
+ bool includeCleartext; /*!< specifies whether we should include the
+ cleartext as first part of our multipart
+ MIME object (or - for non-MIME
+ messages - as flat text to be set before
+ the ciphertext, resp.), typically this
+ is TRUE when signing mails but FALSE
+ when encrypting<br>
+ (this parameter is relevant no matter
+ whether \c makeMimeObject is TRUE or
+ FALSE) */
+ bool makeMimeObject; /*!< specifies whether we should create a MIME
+ object or a flat text message body */
+ /* the following are used for MIME messages only */
+ bool makeMultiMime; /*!< specifies whether we should create a
+ 'Multipart' MIME object or a single part
+ object, if FALSE only \c contentTypeMain,
+ \c contentDispMain and \c contentTEncMain
+ may be used and all other parameters have
+ to be ignored<br>
+ (ignore this parameter if \c makeMimeObject
+ is FALSE) */
+ char* contentTypeMain; /*!< value of the main 'Content-Type'
+ header<br>
+ (ignore this parameter if \c makeMimeObject
+ is FALSE) */
+ char* contentDispMain; /*!< value of the main 'Content-Disposition'
+ header<br>
+ (ignore this parameter if \c makeMimeObject
+ is FALSE) */
+ char* contentTEncMain; /*!< value of the main
+ 'Content-TransferEncoding' header<br>
+ (ignore this parameter if \c makeMimeObject
+ is FALSE) */
+ char* contentTypeVersion; /*!< 'Content-Type' of the additional version
+ part that might preceed the code part -
+ if NULL or zero length no version part
+ must be created<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE) */
+ char* contentDispVersion; /*!< 'Content-Disposition' of the additional
+ preceeding the code part (only valid if
+ \c contentTypeVersion holds a
+ non-zero-length string)<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE or if \c contentTypeVersion does
+ not return a non-zero-length string) */
+ char* contentTEncVersion; /*!< 'Content-Transfer-Encoding' of the
+ additional version part (only valid if
+ \c contentTypeVersion holds a
+ non-zero-length string)<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE or if \c contentTypeVersion does
+ not return a non-zero-length string) */
+ char* bodyTextVersion; /*!< body text of the additional version part
+ (only valid if \c contentTypeVersion
+ holds a non-zero-length string)<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE or if \c contentTypeVersion does
+ not return a non-zero-length string) */
+ char* contentTypeCode; /*!< 'Content-Type' of the code part holding
+ the signature code (or the encrypted
+ data, resp.)<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE) */
+ char* contentDispCode; /*!< 'Content-Disposition' of the code part<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE or if \c contentTypeCode does
+ not return a non-zero-length string) */
+ char* contentTEncCode; /*!< 'Content-Type' of the code part<br>
+ (ignore this parameter if either
+ \c makeMimeObject or \c makeMultiMime
+ is FALSE or if \c contentTypeCode does
+ not return a non-zero-length string) */
+ /* the following are used for flat non-MIME messages only */
+ char* flatTextPrefix; /*!< text to preceed the main text (or the
+ code bloc containing the encrypted main
+ text, resp.)<br>
+ (ignore this parameter if
+ \c makeMimeObject is TRUE) */
+ char* flatTextSeparator; /*!< text to be put between the main text and
+ the signature code bloc (not used when
+ encrypting)<br>
+ (ignore this parameter if
+ \c makeMimeObject is TRUE or if
+ \c includeCleartext is FALSE) */
+ char* flatTextPostfix; /*!< text to follow the signature code bloc
+ (or the encrypted data bloc, resp.)<br>
+ (ignore this parameter if
+ \c makeMimeObject is TRUE) */
+};
+
+
+/*! \ingroup groupAdUsoInterno
+ \brief If you are not planning to write your own cryptography
+ plugin <b>you should ignore this</b> function!
+
+ Usage of this function is depreciated for plugin users but highly
+ recommended for plugin implementors since this is an internal
+ function for initializing all char* members of a \c StructuringInfo
+ struct.<br>
+ This function <b>must</b> be called in <b>any</b> plugin's
+ implementations of the following functions:
+
+ \c signMessage() <br>
+ \c encryptMessage() <br>
+ \c encryptAndSignMessage()
+
+ Calling this function makes sure the corresponding
+ \c free_StructuringInfo() calls which will be embedded by
+ your plugin's users into their code will be able to
+ determine which of the char* members belonging to the
+ respective's StructuringInfo had been allocated memory
+ for during previous signing or encrypting actions.
+
+ \see free_StructuringInfo, StructuringInfo
+ \see signMessage, encryptMessage, encryptAndSignMessage
+*/
+ inline void init_StructuringInfo( struct StructuringInfo* s )
+ {
+ if( ! s ) return;
+
+ s->includeCleartext = false;
+
+ s->makeMimeObject = false;
+ s->makeMultiMime = false;
+
+ s->contentTypeMain = 0;
+ s->contentDispMain = 0;
+ s->contentTEncMain = 0;
+
+ s->contentTypeVersion = 0;
+ s->contentDispVersion = 0;
+ s->contentTEncVersion = 0;
+ s->bodyTextVersion = 0;
+
+ s->contentTypeCode = 0;
+ s->contentDispCode = 0;
+ s->contentTEncCode = 0;
+
+ s->flatTextPrefix = 0;
+ s->flatTextSeparator = 0;
+ s->flatTextPostfix = 0;
+ }
+
+/*! \ingroup groupSignCryptAct
+ \brief Important method for freeing all memory that was allocated
+ for the char* members of a \c StructuringInfo struct - use
+ this function after <b>each</b> signing or encrypting function
+ call.
+
+ \note Even when intending to call \c encryptMessage() immediately
+ after having called \c signMessage() you first <b>must</b> call
+ the \c free_StructuringInfo() function to make sure all memory is
+ set free that was allocated for your StructuringInfo's char* members
+ by the \c signMessage() function!
+
+ \see StructuringInfo
+*/
+ inline void free_StructuringInfo( struct StructuringInfo* s )
+ {
+ if( ! s ) return;
+ if( s->contentTypeMain ) free( s->contentTypeMain );
+ if( s->contentDispMain ) free( s->contentDispMain );
+ if( s->contentTEncMain ) free( s->contentTEncMain );
+ if( s->contentTypeVersion ) free( s->contentTypeVersion );
+ if( s->contentDispVersion ) free( s->contentDispVersion );
+ if( s->contentTEncVersion ) free( s->contentTEncVersion );
+ if( s->bodyTextVersion ) free( s->bodyTextVersion );
+ if( s->contentTypeCode ) free( s->contentTypeCode );
+ if( s->contentDispCode ) free( s->contentDispCode );
+ if( s->contentTEncCode ) free( s->contentTEncCode );
+ if( s->flatTextPrefix ) free( s->flatTextPrefix );
+ if( s->flatTextSeparator ) free( s->flatTextSeparator );
+ if( s->flatTextPostfix ) free( s->flatTextPostfix );
+ }
+
+
+/*! \ingroup groupSignAct
+ */
+struct SignatureMetaDataExtendedInfo
+{
+ struct tm* creation_time;
+ SigStatusFlags sigStatusFlags;
+ char* status_text;
+ char* keyid;
+ char* fingerprint;
+ char* algo;
+ char* userid;
+ char* name;
+ char* comment;
+ char** emailList;
+ int emailCount;
+ unsigned long algo_num;
+ unsigned long validity;
+ unsigned long userid_num;
+ unsigned long keylen;
+ unsigned long key_created;
+ unsigned long key_expires;
+};
+
+/*! \ingroup groupSignAct
+*/
+struct SignatureMetaData {
+ char* status;
+ struct SignatureMetaDataExtendedInfo* extended_info;
+ int extended_info_count;
+ int status_code;
+};
+
+/*! \ingroup groupSignAct
+ \brief Checks whether the signature of a message is
+ valid.
+
+ \c cleartext must never be 0 but be a valid pointer.
+
+ If \c *cleartext > 0 then **cleartext specifies the message text
+ that was signed and \c signaturetext is the signature itself.
+
+ If \c *cleartext == 0 is an empty string then \c signaturetext is
+ supposed to contain an opaque signed message part. After checking the
+ data and verifying the signature the cleartext of the message will be
+ returned in \c cleartext. The user must free the respective memory
+ ocupied by *cleartext.
+
+ Depending on the configuration, MUAs might not need to use this.
+ If \c sigmeta is non-null, the
+ \c SignatureMetaData object pointed to will
+ contain meta information about the signature after the
+ function call.
+*/
+bool checkMessageSignature( char** cleartext,
+ const char* signaturetext,
+ bool signatureIsBinary,
+ int signatureLen,
+ struct SignatureMetaData* sigmeta,
+ char** attrOrder,
+ const char* unknownAttrsHandling );
+
+
+/*! \ingroup groupCryptAct
+ \brief Tries to decrypt an email message
+ \c ciphertext and returns the decrypted
+ message in \c cleartext.
+
+ The \c certificate is used for decryption. If
+ the message could be decrypted, the function returns
+ \c true, otherwise
+ \c false.
+*/
+bool decryptMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ const char** cleartext,
+ const char* certificate,
+ int* errId,
+ char** errTxt );
+
+/*! \ingroup groupCryptAct
+ \brief Combines the functionality of
+ \c checkMessageSignature() and
+ \c decryptMessage().
+
+ If \c certificate is \c NULL,
+ the default certificate will be used.
+ If \c sigmeta is non-null, the \c SignatureMetaData
+ object pointed to will contain meta information about
+ the signature after the function call.
+*/
+bool decryptAndCheckMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ const char** cleartext,
+ const char* certificate,
+ bool* signatureFound,
+ struct SignatureMetaData* sigmeta,
+ int* errId,
+ char** errTxt,
+ char** attrOrder,
+ const char* unknownAttrsHandling );
+
+struct DnPair {
+ char *key;
+ char *value;
+};
+
+struct CertificateInfo {
+ char** userid;
+ char* userid_0_org;
+ char* serial;
+ char* fingerprint;
+
+ char* issuer_org;
+ char* issuer_reord;
+ char* chainid;
+
+ char* caps;
+
+ unsigned long created;
+ unsigned long expire;
+
+ int secret : 1;
+ int invalid : 1;
+ int expired : 1;
+ int disabled : 1;
+
+ struct DnPair *dnarray; /* parsed values from userid[0] */
+};
+
+ /*!
+ Import a certificate from memory.
+ */
+ GpgME::ImportResult importCertificateFromMem( const char* data, size_t length );
+}; // class CryptPlug
+
+class SMIMECryptPlug : public CryptPlug {
+public:
+ SMIMECryptPlug();
+};
+
+class OpenPGPCryptPlug : public CryptPlug {
+public:
+ OpenPGPCryptPlug();
+};
+
+#endif /*CRYPTPLUG_H*/
+
diff --git a/certmanager/lib/cryptplugfactory.cpp b/certmanager/lib/cryptplugfactory.cpp
new file mode 100644
index 000000000..7000d9a90
--- /dev/null
+++ b/certmanager/lib/cryptplugfactory.cpp
@@ -0,0 +1,119 @@
+/*
+ cryptplugfactory.cpp
+
+ This file is part of libkleopatra, the KDE key management library
+ Copyright (c) 2001,2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cryptplugfactory.h"
+#include "cryptplugwrapperlist.h"
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+
+#include <assert.h>
+
+KMail::CryptPlugFactory * KMail::CryptPlugFactory::mSelf = 0;
+
+//
+//
+// KMail::CryptPlugFactory: backwards compat stuff (ugly)
+//
+//
+
+
+KMail::CryptPlugFactory::CryptPlugFactory()
+ : Kleo::CryptoBackendFactory(),
+ mCryptPlugWrapperList( 0 )
+{
+ mSelf = this;
+
+ mCryptPlugWrapperList = new CryptPlugWrapperList();
+ mCryptPlugWrapperList->setAutoDelete( false );
+ updateCryptPlugWrapperList();
+}
+
+KMail::CryptPlugFactory::~CryptPlugFactory() {
+ mSelf = 0;
+ delete mCryptPlugWrapperList; mCryptPlugWrapperList = 0;
+}
+
+KMail::CryptPlugFactory * KMail::CryptPlugFactory::instance() {
+ if ( !mSelf )
+ mSelf = new CryptPlugFactory();
+ return mSelf;
+}
+
+CryptPlugWrapper * KMail::CryptPlugFactory::active() const {
+ if ( smime() && smime()->active() )
+ return smime();
+ if ( openpgp() && openpgp()->active() )
+ return openpgp();
+ return 0;
+}
+
+CryptPlugWrapper * KMail::CryptPlugFactory::createForProtocol( const QString & proto ) const {
+ QString p = proto.lower();
+ if ( p == "application/pkcs7-signature" || p == "application/x-pkcs7-signature" )
+ return smime();
+ if ( p == "application/pgp-signature" || p == "application/x-pgp-signature" )
+ return openpgp();
+ return 0;
+}
+
+CryptPlugWrapper * KMail::CryptPlugFactory::smime() const {
+ return mCryptPlugWrapperList->findForLibName( "smime" );
+}
+
+CryptPlugWrapper * KMail::CryptPlugFactory::openpgp() const {
+ return mCryptPlugWrapperList->findForLibName( "openpgp" );
+}
+
+void KMail::CryptPlugFactory::scanForBackends( QStringList * reason ) {
+ Kleo::CryptoBackendFactory::scanForBackends( reason );
+ updateCryptPlugWrapperList();
+}
+
+void KMail::CryptPlugFactory::updateCryptPlugWrapperList() {
+ mCryptPlugWrapperList->clear();
+ for ( std::vector<Kleo::CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
+ if ( CryptPlugWrapper * w = dynamic_cast<CryptPlugWrapper*>( (*it)->openpgp() ) )
+ mCryptPlugWrapperList->append( w );
+ if ( CryptPlugWrapper * w = dynamic_cast<CryptPlugWrapper*>( (*it)->smime() ) )
+ mCryptPlugWrapperList->append( w );
+ }
+}
+
+#include "cryptplugfactory.moc"
diff --git a/certmanager/lib/cryptplugfactory.h b/certmanager/lib/cryptplugfactory.h
new file mode 100644
index 000000000..a50c3909c
--- /dev/null
+++ b/certmanager/lib/cryptplugfactory.h
@@ -0,0 +1,83 @@
+/*
+ cryptplugfactory.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_CRYPTPLUGFACTORY_H__
+#define __KLEO_CRYPTPLUGFACTORY_H__
+
+#include "kleo/cryptobackendfactory.h"
+
+#include <kdepimmacros.h>
+
+#ifndef LIBKLEOPATRA_NO_COMPAT
+namespace Kleo {
+ //typedef CryptoBackendFactory CryptPlugFactory KDE_DEPRECATED;
+}
+
+class CryptPlugWrapper;
+class CryptPlugWrapperList;
+
+namespace KMail {
+
+ class KDE_EXPORT CryptPlugFactory : public Kleo::CryptoBackendFactory {
+ Q_OBJECT
+ protected:
+ CryptPlugFactory();
+ ~CryptPlugFactory();
+
+ public:
+ static CryptPlugFactory * instance();
+
+ CryptPlugWrapper * active() const;
+ CryptPlugWrapper * smime() const;
+ CryptPlugWrapper * openpgp() const;
+
+ CryptPlugWrapperList & list() const { return *mCryptPlugWrapperList; }
+
+ CryptPlugWrapper * createForProtocol( const QString & proto ) const;
+
+ void scanForBackends( QStringList * reason );
+
+ private:
+ void updateCryptPlugWrapperList();
+
+ private:
+ CryptPlugFactory( const CryptPlugFactory & );
+ void operator=( const CryptPlugFactory & );
+ CryptPlugWrapperList * mCryptPlugWrapperList;
+
+ static CryptPlugFactory * mSelf;
+ };
+
+}
+#endif
+
+#endif // __KLEO_CRYPTPLUGFACTORY_H__
diff --git a/certmanager/lib/cryptplugwrapper.cpp b/certmanager/lib/cryptplugwrapper.cpp
new file mode 100644
index 000000000..ce883d79f
--- /dev/null
+++ b/certmanager/lib/cryptplugwrapper.cpp
@@ -0,0 +1,850 @@
+/**
+ * cryptplugwrapper.cpp
+ *
+ * Copyright (c) 2001 Karl-Heinz Zimmer, Klaraelvdalens Datakonsult AB
+ *
+ * This CRYPTPLUG wrapper implementation is based on cryptplug.h by
+ * Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ * specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ * see file mua-integration.sgml located on Aegypten CVS:
+ * http://www.gnupg.org/aegypten/development.en.html
+ *
+ * purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ * for usage by KDE programs, e.g. KMail (or KMime, resp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cryptplugwrapper.h"
+#include "cryptplug.h"
+
+#include <backends/qgpgme/qgpgmekeylistjob.h>
+#include <backends/qgpgme/qgpgmeencryptjob.h>
+#include <backends/qgpgme/qgpgmedecryptjob.h>
+#include <backends/qgpgme/qgpgmesignjob.h>
+#include <backends/qgpgme/qgpgmeverifydetachedjob.h>
+#include <backends/qgpgme/qgpgmeverifyopaquejob.h>
+#include <backends/qgpgme/qgpgmekeygenerationjob.h>
+#include <backends/qgpgme/qgpgmeimportjob.h>
+#include <backends/qgpgme/qgpgmeexportjob.h>
+#include <backends/qgpgme/qgpgmesecretkeyexportjob.h>
+#include <backends/qgpgme/qgpgmedownloadjob.h>
+#include <backends/qgpgme/qgpgmedeletejob.h>
+#include <backends/qgpgme/qgpgmesignencryptjob.h>
+#include <backends/qgpgme/qgpgmedecryptverifyjob.h>
+#include <backends/qgpgme/qgpgmecryptoconfig.h>
+#include <backends/qgpgme/qgpgmerefreshkeysjob.h>
+
+// qgpgme
+#include <qgpgme/dataprovider.h>
+
+// gpgme++
+#include <gpgmepp/data.h>
+#include <gpgmepp/importresult.h>
+#include <gpgmepp/keygenerationresult.h>
+
+// kde
+#include <kdebug.h>
+#include <kapplication.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kconfig.h>
+
+// other
+#include <memory>
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+
+
+
+/*
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This file's source comments - as well as those in interface file *
+ * cryptplugwrapper.h - are optimized for processing by Doxygen. *
+ * *
+ * To obtain best results please get an updated version of Doxygen, *
+ * for sources and binaries goto http://www.doxygen.org/index.html *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
+ */
+
+
+
+/*! \file cryptplugwrapper.cpp
+ \brief C++ wrapper for the CRYPTPLUG library API.
+
+ This CRYPTPLUG wrapper implementation is based on cryptplug.h by
+ Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ see file mua-integration.sgml located on Aegypten CVS:
+ http://www.gnupg.org/aegypten/development.en.html
+
+ purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ for usage by KDE programs, e.g. KMail (or KMime, resp.)
+
+ CRYPTPLUG is an independent cryptography plug-in API
+ developed for Sphinx-enabeling KMail and Mutt.
+
+ CRYPTPLUG was designed for the Aegypten project, but it may
+ be used by 3rd party developers as well to design pluggable
+ crypto backends for the above mentioned MUAs.
+
+ \note All string parameters appearing in this API are to be
+ interpreted as UTF-8 encoded.
+
+ \see cryptplugwrapper.h
+*/
+
+
+// a little helper class for reordering of DN attributes
+class DNBeautifier {
+public:
+ enum UnknownAttrsHandling { unknownAttrsHide,
+ unknownAttrsPrefix,
+ unknownAttrsPostfix,
+ unknownAttrsInfix };
+ // infix: at the position of "_X_", if any, else Postfix
+
+ DNBeautifier()
+ {
+ // the attrOrder is defaulted to an empty string automatically
+ _unknownAttrsHandling = unknownAttrsInfix;
+ _unknownAttrsHandlingChar = "INFIX";
+ }
+ DNBeautifier( KConfig* config,
+ const QString& cfgGroup,
+ const QString& cfgAttributeOrderEntry,
+ const QString& cfgUnknownAttrsEntry,
+ const QStringList& fallbackAttrOrder = QStringList(),
+ UnknownAttrsHandling fallbackUnknowAttrsHandling = unknownAttrsInfix )
+ {
+ _unknownAttrsHandling = unknownAttrsInfix;
+ _unknownAttrsHandlingChar = "INFIX";
+ if( config ){
+ const QString oldGroup( config->group() );
+ config->setGroup( cfgGroup ); // e.g. "General"
+ _attrOrder =
+ config->readListEntry( cfgAttributeOrderEntry ); // e.g. "DNAttributeOrder"
+ _unknownAttrsHandlingChar =
+ config->readEntry( cfgUnknownAttrsEntry ).upper().latin1(); // e.g. "DNUnknownAttributes"
+ config->setGroup( oldGroup );
+ if( _unknownAttrsHandlingChar == "HIDE" )
+ _unknownAttrsHandling = unknownAttrsHide;
+ else if( _unknownAttrsHandlingChar == "PREFIX" )
+ _unknownAttrsHandling = unknownAttrsPrefix;
+ else if( _unknownAttrsHandlingChar == "POSTFIX" )
+ _unknownAttrsHandling = unknownAttrsPostfix;
+ else if( _unknownAttrsHandlingChar == "INFIX" )
+ _unknownAttrsHandling = unknownAttrsInfix;
+ else
+ _unknownAttrsHandlingChar = "INFIX";
+ }
+ if( _attrOrder.isEmpty() && ! fallbackAttrOrder.isEmpty() )
+ _attrOrder = fallbackAttrOrder;
+
+ if( _attrOrder.isEmpty() ){
+ _attrOrderChar = 0;
+ }else{
+ _attrOrderChar = new char*[ _attrOrder.count()+1 ];
+ int i=0;
+ for( QStringList::ConstIterator itOrder = _attrOrder.begin();
+ itOrder != _attrOrder.end();
+ ++itOrder ){
+ _attrOrderChar[ i ] = (char*)malloc( ((*itOrder).length()+1)*sizeof(char) );
+ strcpy( _attrOrderChar[ i ], (*itOrder).latin1() );
+ ++i;
+ }
+ _attrOrderChar[ i ] = NULL;
+ }
+ }
+ ~DNBeautifier()
+ {
+ int i=0;
+ for( QStringList::ConstIterator itOrder = _attrOrder.begin();
+ itOrder != _attrOrder.end();
+ ++itOrder ){
+ free( _attrOrderChar[ i ] );
+ ++i;
+ }
+ delete[] _attrOrderChar;
+ }
+
+ QStringList attrOrder() const
+ {
+ return _attrOrder;
+ }
+ char** attrOrderChar()
+ {
+ return _attrOrderChar;
+ }
+
+ UnknownAttrsHandling unknownAttrsHandling() const
+ {
+ return _unknownAttrsHandling;
+ }
+ const char* unknownAttrsHandlingChar() const
+ {
+ return _unknownAttrsHandlingChar;
+ }
+
+ QValueList< QPair<QString,QString> > reorder( const QValueList< QPair<QString,QString> > & dn ) const
+ {
+ return reorder( dn, _attrOrder, _unknownAttrsHandling );
+ }
+
+
+ static QValueList< QPair<QString,QString> > reorder(
+ const QValueList< QPair<QString,QString> > & dn,
+ QStringList attrOrder,
+ UnknownAttrsHandling unknownAttrsHandling )
+ {
+ if( !attrOrder.isEmpty() ){
+ QPtrList< QPair<QString,QString> > unknownEntries;
+ QValueList< QPair<QString,QString> > dnNew;
+
+ QPair<QString,QString>* unknownEntry;
+ QStringList::ConstIterator itOrder;
+ QValueList< QPair<QString,QString> >::ConstIterator itDN;
+ bool bFound;
+
+ if( unknownAttrsHandling != unknownAttrsHide ){
+ // find all unknown entries in their order of appearance
+ for( itDN = dn.begin(); itDN != dn.end(); ++itDN ){
+ bFound = false;
+ for( itOrder = attrOrder.begin(); itOrder != attrOrder.end(); ++itOrder ){
+ if( (*itOrder) == (*itDN).first ){
+ bFound = true;
+ break;
+ }
+ }
+ if( !bFound )
+ unknownEntries.append( &(*itDN) );
+ }
+ }
+
+ // prepend the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsPrefix ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+
+ // process the known attrs in the desired order
+ bool b_X_declared = false;
+ for( itOrder = attrOrder.begin(); itOrder != attrOrder.end(); ++itOrder ){
+ if( (*itOrder) == "_X_" ){
+ b_X_declared = true;
+ // insert the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsInfix ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+ }else{
+ for( itDN = dn.begin(); itDN != dn.end(); ++itDN ){
+ if( (*itOrder) == (*itDN).first ){
+ dnNew << *itDN;
+ //kdDebug(5150) << QString((*itDN).first) <<" = " << QString((*itDN).second) << endl;;
+ }
+ }
+ }
+ }
+
+ // append the unknown attrs (if desired)
+ if( unknownAttrsHandling == unknownAttrsPostfix ||
+ ( unknownAttrsHandling == unknownAttrsInfix && ! b_X_declared ) ){
+ for( unknownEntry = unknownEntries.first(); unknownEntry; unknownEntry = unknownEntries.next() ){
+ dnNew << *unknownEntry;
+ }
+ }
+
+ return dnNew;
+ }
+ return dn;
+ }
+
+private:
+ QStringList _attrOrder;
+ char** _attrOrderChar;
+ UnknownAttrsHandling _unknownAttrsHandling;
+ QCString _unknownAttrsHandlingChar;
+};
+
+
+
+/* special helper class to be used by signing/encrypting functions *******/
+
+
+
+StructuringInfoWrapper::StructuringInfoWrapper( CryptPlugWrapper* wrapper )
+ : _initDone( false ), _wrapper( wrapper )
+{
+ initMe();
+}
+StructuringInfoWrapper::~StructuringInfoWrapper()
+{
+ freeMe();
+}
+void StructuringInfoWrapper::reset()
+{
+ freeMe();
+ initMe();
+}
+void StructuringInfoWrapper::initMe()
+{
+ if ( _wrapper && _wrapper->cryptPlug() ) {
+ _wrapper->cryptPlug()->init_StructuringInfo( &data );
+ _initDone = true;
+ }
+}
+void StructuringInfoWrapper::freeMe()
+{
+ if( _wrapper && _wrapper->cryptPlug() && _initDone ) {
+ _wrapper->cryptPlug()->free_StructuringInfo( &data );
+ _initDone = false;
+ }
+}
+
+class CryptPlugWrapper::Config {
+public:
+ Config( gpgme_protocol_t proto );
+ ~Config();
+
+ const char* signatureKeyCertificate;
+ SignatureAlgorithm signatureAlgorithm;
+ SignatureCompoundMode signatureCompoundMode;
+ SendCertificates sendCertificates;
+ bool saveSentSignatures;
+ bool warnNoCertificate;
+ bool signatureUseCRLs;
+ EncryptionAlgorithm encryptionAlgorithm;
+ EncryptEmail encryptEmail;
+ bool saveMessagesEncrypted;
+ bool encryptionUseCRLs;
+ bool encryptionCRLExpiryNearWarning;
+ int encryptionCRLNearExpiryInterval;
+ CertificateSource certificateSource;
+ bool warnSendUnsigned;
+ bool signatureCertificateExpiryNearWarning;
+ int signatureCertificateExpiryNearInterval;
+ bool cACertificateExpiryNearWarning;
+ int cACertificateExpiryNearInterval;
+ bool rootCertificateExpiryNearWarning;
+ int rootCertificateExpiryNearInterval;
+ bool warnSendUnencrypted;
+ bool checkCertificatePath;
+ bool receiverCertificateExpiryNearWarning;
+ int receiverCertificateExpiryNearWarningInterval;
+ bool certificateInChainExpiryNearWarning;
+ int certificateInChainExpiryNearWarningInterval;
+ bool receiverEmailAddressNotInCertificateWarning;
+ const char* libVersion; /* a statically allocated string with the GPGME Version used */
+};
+
+static const int NEAR_EXPIRY = 14;
+
+CryptPlugWrapper::Config::Config( gpgme_protocol_t proto )
+{
+ signatureAlgorithm = SignAlg_SHA1;
+ if ( proto == GPGME_PROTOCOL_CMS )
+ signatureCompoundMode = SignatureCompoundMode_Opaque;
+ else
+ signatureCompoundMode = SignatureCompoundMode_Detached;
+ sendCertificates = SendCert_SendChainWithRoot;
+ saveSentSignatures = true;
+ warnNoCertificate = true;
+ signatureUseCRLs = true;
+ encryptionAlgorithm = EncryptAlg_RSA;
+ encryptEmail = EncryptEmail_Ask;
+ saveMessagesEncrypted = true;
+ encryptionUseCRLs = true;
+ encryptionCRLExpiryNearWarning = false;
+ encryptionCRLNearExpiryInterval = NEAR_EXPIRY;
+ certificateSource = CertSrc_Server;
+ warnSendUnsigned = true;
+ signatureCertificateExpiryNearWarning = true;
+ signatureCertificateExpiryNearInterval = NEAR_EXPIRY;
+ cACertificateExpiryNearWarning = true;
+ cACertificateExpiryNearInterval = NEAR_EXPIRY;
+ rootCertificateExpiryNearWarning = true;
+ rootCertificateExpiryNearInterval = NEAR_EXPIRY;
+ warnSendUnencrypted = false;
+ checkCertificatePath = true;
+ receiverCertificateExpiryNearWarning = true;
+ receiverCertificateExpiryNearWarningInterval = NEAR_EXPIRY;
+ certificateInChainExpiryNearWarning = true;
+ certificateInChainExpiryNearWarningInterval = NEAR_EXPIRY;
+ receiverEmailAddressNotInCertificateWarning = true;
+ libVersion = gpgme_check_version (NULL);
+}
+
+CryptPlugWrapper::Config::~Config() {
+}
+
+/* Some multi purpose functions ******************************************/
+
+QString CryptPlugWrapper::errorIdToText( int errId, bool & isPassphraseError ) {
+ const GpgME::Error err( errId );
+ isPassphraseError = err.isCanceled()
+ || gpgme_err_code( errId ) == GPG_ERR_NO_SECKEY ; // FIXME: more?
+ return QString::fromLocal8Bit( err.asString() );
+}
+
+/* some special functions ************************************************/
+
+
+CryptPlugWrapper::CryptPlugWrapper( const QString& name,
+ const QString& libName,
+ const QString& update,
+ bool active )
+ : Kleo::CryptoBackend::Protocol(),
+ _name( name ),
+ _libName( libName ),
+ _updateURL( update ),
+ _active( active ),
+ _initStatus( InitStatus_undef ),
+ _cp( 0 ),
+ _config( 0 ),
+ _cryptoConfig( 0 )
+{
+ const bool ok = initialize( 0, 0 );
+ assert( ok );
+}
+
+
+CryptPlugWrapper::~CryptPlugWrapper()
+{
+ deinitialize();
+}
+
+
+void CryptPlugWrapper::setActive( bool active )
+{
+ _active = active;
+}
+
+
+bool CryptPlugWrapper::active() const
+{
+ return _active;
+}
+
+
+
+bool CryptPlugWrapper::setLibName( const QString& libName )
+{
+ bool bOk = ! _cp; // Changing the lib name is only allowed
+ if( bOk ) // when either no initialization took
+ _libName = libName; // place or 'deinitialize()' has been
+ return bOk; // called afterwards.
+}
+
+QString CryptPlugWrapper::libName() const
+{
+ return _libName;
+}
+
+QString CryptPlugWrapper::protocol() const
+{
+ if ( _libName.contains( "smime" ) )
+ return "SMIME";
+ if ( _libName.contains( "openpgp" ) )
+ return "OpenPGP";
+ return QString::null;
+}
+
+void CryptPlugWrapper::setDisplayName( const QString& name )
+{
+ _name = name;
+}
+
+
+QString CryptPlugWrapper::displayName() const
+{
+ if ( !_name.isEmpty() )
+ return _name;
+ if ( _libName.contains( "smime" ) )
+ return "gpgsm";
+ if ( _libName.contains( "openpgp" ) )
+ return "gpg";
+ return i18n("(Unknown Protocol)");
+}
+
+bool CryptPlugWrapper::initialize( InitStatus* initStatus, QString* errorMsg )
+{
+ if ( _cp )
+ return true;
+
+ _initStatus = InitStatus_undef;
+ /* make sure we have a lib name */
+ if ( _libName.isEmpty() ) {
+ _initStatus = InitStatus_NoLibName;
+ kdDebug(5150) << "No library name was given.\n" << endl;
+ } else {
+ if ( _libName.contains( "smime" ) ) {
+ _cp = new SMIMECryptPlug();
+ _config = new Config( GPGME_PROTOCOL_CMS );
+ } else if ( _libName.contains( "openpgp" ) ) {
+ _cp = new OpenPGPCryptPlug();
+ _config = new Config( GPGME_PROTOCOL_OpenPGP );
+ } else {
+ _cp = 0;
+ _config = 0;
+ }
+
+ if ( !_cp ) {
+ _initStatus = InitStatus_LoadError;
+ kdDebug(5150) << "Couldn't create '" << _libName.latin1() << "'" << endl;
+ } else {
+ /* now call the init function */
+ if( !_cp->initialize() ) {
+ _initStatus = InitStatus_InitError;
+ kdDebug(5150) << "Error while executing function 'initialize' on plugin " << _libName << endl;
+ _lastError = i18n("Error while initializing plugin \"%1\"").arg( _libName );
+ if ( errorMsg )
+ *errorMsg = _lastError;
+ delete _cp; _cp = 0;
+ delete _config; _config = 0;
+ } else {
+ _initStatus = InitStatus_Ok;
+ }
+ }
+ }
+ if( initStatus )
+ *initStatus = _initStatus;
+ return _initStatus == InitStatus_Ok;
+}
+
+
+
+void CryptPlugWrapper::deinitialize()
+{
+ delete _cp; _cp = 0;
+ delete _config; _config = 0;
+ delete _cryptoConfig; _cryptoConfig = 0;
+}
+
+
+CryptPlugWrapper::InitStatus CryptPlugWrapper::initStatus( QString* errorMsg ) const
+{
+ if( errorMsg )
+ *errorMsg = _lastError;
+ return _initStatus;
+}
+
+
+bool CryptPlugWrapper::hasFeature( Feature flag )
+{
+ return _cp && _cp->hasFeature( flag );
+}
+
+
+/* normal functions ******************************************************/
+
+bool CryptPlugWrapper::checkMessageSignature( char** cleartext,
+ const char* signaturetext,
+ bool signatureIsBinary,
+ int signatureLen,
+ CryptPlug::SignatureMetaData* sigmeta )
+{
+ DNBeautifier dnBeautifier( kapp->config(),
+ "DN",
+ "AttributeOrder",
+ "UnknownAttributes" );
+ return _cp && _cp->checkMessageSignature( cleartext,
+ signaturetext,
+ signatureIsBinary,
+ signatureLen,
+ sigmeta,
+ dnBeautifier.attrOrderChar(),
+ dnBeautifier.unknownAttrsHandlingChar() );
+}
+
+
+bool CryptPlugWrapper::decryptMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ int* errId,
+ char** errTxt )
+{
+ return _cp && _cp->decryptMessage( ciphertext, cipherIsBinary, cipherLen,
+ (const char**)cleartext, certificate, errId, errTxt );
+}
+
+
+bool CryptPlugWrapper::decryptAndCheckMessage(
+ const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ bool* signatureFound,
+ CryptPlug::SignatureMetaData* sigmeta,
+ int* errId,
+ char** errTxt )
+{
+ DNBeautifier dnBeautifier( kapp->config(),
+ "DN",
+ "AttributeOrder",
+ "UnknownAttributes" );
+ return _cp && _cp->decryptAndCheckMessage( ciphertext,
+ cipherIsBinary,
+ cipherLen,
+ (const char**)cleartext,
+ certificate,
+ signatureFound,
+ sigmeta,
+ errId,
+ errTxt,
+ dnBeautifier.attrOrderChar(),
+ dnBeautifier.unknownAttrsHandlingChar() );
+}
+
+
+
+
+void CryptPlugWrapper::freeSignatureMetaData( CryptPlug::SignatureMetaData* sigmeta )
+{
+ if ( !sigmeta )
+ return;
+ free( sigmeta->status );
+ for( int i = 0; i < sigmeta->extended_info_count; ++i ) {
+ free( sigmeta->extended_info[i].creation_time );
+ free( (void*)sigmeta->extended_info[i].status_text );
+ free( (void*)sigmeta->extended_info[i].keyid );
+ free( (void*)sigmeta->extended_info[i].fingerprint );
+ free( (void*)sigmeta->extended_info[i].algo );
+ free( (void*)sigmeta->extended_info[i].userid );
+ free( (void*)sigmeta->extended_info[i].name );
+ free( (void*)sigmeta->extended_info[i].comment );
+ if( sigmeta->extended_info[i].emailCount ){
+ for( int j=0; j < sigmeta->extended_info[i].emailCount; ++j)
+ if( sigmeta->extended_info[i].emailList[j] )
+ free( (void*)sigmeta->extended_info[i].emailList[j] );
+ free( (void*)sigmeta->extended_info[i].emailList );
+ }
+ }
+ free( sigmeta->extended_info );
+}
+
+GpgME::ImportResult CryptPlugWrapper::importCertificate( const char* data, size_t length )
+{
+ if ( !_cp )
+ return GpgME::ImportResult();
+
+
+ return _cp->importCertificateFromMem( data, length );
+}
+
+Kleo::KeyListJob * CryptPlugWrapper::keyListJob( bool remote, bool includeSigs, bool validate ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ unsigned int mode = context->keyListMode();
+ if ( remote ) {
+ mode |= GpgME::Context::Extern;
+ mode &= ~GpgME::Context::Local;
+ } else {
+ mode |= GpgME::Context::Local;
+ mode &= ~GpgME::Context::Extern;
+ }
+ if ( includeSigs ) mode |= GpgME::Context::Signatures;
+ if ( validate ) mode |= GpgME::Context::Validate;
+ context->setKeyListMode( mode );
+ return new Kleo::QGpgMEKeyListJob( context );
+}
+
+Kleo::EncryptJob * CryptPlugWrapper::encryptJob( bool armor, bool textmode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textmode );
+ return new Kleo::QGpgMEEncryptJob( context );
+}
+
+Kleo::DecryptJob * CryptPlugWrapper::decryptJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEDecryptJob( context );
+}
+
+Kleo::SignJob * CryptPlugWrapper::signJob( bool armor, bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMESignJob( context );
+}
+
+Kleo::VerifyDetachedJob * CryptPlugWrapper::verifyDetachedJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEVerifyDetachedJob( context );
+}
+
+Kleo::VerifyOpaqueJob * CryptPlugWrapper::verifyOpaqueJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEVerifyOpaqueJob( context );
+}
+
+Kleo::KeyGenerationJob * CryptPlugWrapper::keyGenerationJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEKeyGenerationJob( context );
+}
+
+Kleo::ImportJob * CryptPlugWrapper::importJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEImportJob( context );
+}
+
+Kleo::ExportJob * CryptPlugWrapper::publicKeyExportJob( bool armor ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ return new Kleo::QGpgMEExportJob( context );
+}
+
+Kleo::ExportJob * CryptPlugWrapper::secretKeyExportJob( bool armor, const QString& charset ) const {
+ if ( !_cp || _cp->mProtocol != GpgME::Context::CMS ) // fixme: add support for gpg, too
+ return 0;
+
+ // this operation is not supported by gpgme, so we have to call gpgsm ourselves:
+ return new Kleo::QGpgMESecretKeyExportJob( armor, charset );
+}
+
+Kleo::RefreshKeysJob * CryptPlugWrapper::refreshKeysJob() const {
+ if ( !_cp || _cp->mProtocol != GpgME::Context::CMS ) // fixme: add support for gpg, too
+ return 0;
+
+ // this operation is not supported by gpgme, so we have to call gpgsm ourselves:
+ return new Kleo::QGpgMERefreshKeysJob();
+}
+
+Kleo::DownloadJob * CryptPlugWrapper::downloadJob( bool armor ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ // this is the hackish interface for downloading from keyserers currently:
+ context->setKeyListMode( GpgME::Context::Extern );
+
+ return new Kleo::QGpgMEDownloadJob( context );
+}
+
+Kleo::DeleteJob * CryptPlugWrapper::deleteJob() const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ return new Kleo::QGpgMEDeleteJob( context );
+}
+
+Kleo::SignEncryptJob * CryptPlugWrapper::signEncryptJob( bool armor, bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setArmor( armor );
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMESignEncryptJob( context );
+}
+
+Kleo::DecryptVerifyJob * CryptPlugWrapper::decryptVerifyJob( bool textMode ) const {
+ if ( !_cp )
+ return 0;
+
+ GpgME::Context * context = GpgME::Context::createForProtocol( _cp->mProtocol );
+ if ( !context )
+ return 0;
+
+ context->setTextMode( textMode );
+
+ return new Kleo::QGpgMEDecryptVerifyJob( context );
+}
diff --git a/certmanager/lib/cryptplugwrapper.h b/certmanager/lib/cryptplugwrapper.h
new file mode 100644
index 000000000..91cec75df
--- /dev/null
+++ b/certmanager/lib/cryptplugwrapper.h
@@ -0,0 +1,839 @@
+/**
+ * cryptplugwrapper.h
+ *
+ * Copyright (c) 2001 Karl-Heinz Zimmer, Klaraelvdalens Datakonsult AB
+ *
+ * This CRYPTPLUG wrapper interface is based on cryptplug.h by
+ * Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ * specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ * see file mua-integration.sgml located on Aegypten CVS:
+ * http://www.gnupg.org/aegypten/development.en.html
+ *
+ * purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ * for usage by KDE programs, e.g. KMail (or KMime, resp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef cryptplugwrapper_h
+#define cryptplugwrapper_h
+
+#include "cryptplug.h"
+
+#ifndef LIBKLEOPATRA_NO_COMPAT
+
+/*
+ *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * *
+ * This file's source comments are optimized for processing by Doxygen. *
+ * *
+ * To obtain best results please get an updated version of Doxygen, *
+ * for sources and binaries goto http://www.doxygen.org/index.html *
+ * *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+
+ *
+ */
+#include "kleo/cryptobackend.h"
+
+#include <qdatetime.h>
+
+#include <qvaluelist.h>
+#include <qpair.h>
+#include <qstringlist.h>
+#include <qstring.h>
+#include <kdepimmacros.h>
+
+
+class KConfigBase;
+class QGpgMECryptoConfig;
+
+namespace GpgME {
+ class ImportResult;
+ class KeyGenerationResult;
+}
+
+namespace Kleo {
+ class KeyListJob;
+ class EncryptJob;
+ class DecryptJob;
+ class SignJob;
+ class VerifyDetachedJob;
+ class VerifyOpaqueJob;
+ class KeyGenerationJob;
+ class ImportJob;
+ class ExportJob;
+ class DownloadJob;
+ class DeleteJob;
+ class SignEncryptJob;
+ class DecryptVerifyJob;
+ class CryptoConfig;
+ class RefreshKeysJob;
+ class SpecialJob;
+}
+
+/*! \file cryptplugwrapper.h
+ \brief C++ wrapper for the CRYPTPLUG library API.
+
+ This CRYPTPLUG wrapper interface is based on cryptplug.h by
+ Karl-Heinz Zimmer which is based on 'The Aegypten Plugin API' as
+ specified by Matthias Kalle Dalheimer, Klaraelvdalens Datakonsult AB,
+ see file mua-integration.sgml located on Aegypten CVS:
+ http://www.gnupg.org/aegypten/development.en.html
+
+ purpose: Wrap up all Aegypten Plugin API functions in one C++ class
+ for usage by KDE programs, e.g. KMail (or KMime, resp.)
+
+ CRYPTPLUG is an independent cryptography plug-in API
+ developed for Sphinx-enabeling KMail and Mutt.
+
+ CRYPTPLUG was designed for the Aegypten project, but it may
+ be used by 3rd party developers as well to design pluggable
+ crypto backends for the above mentioned MUAs.
+
+ \note All string parameters appearing in this API are to be
+ interpreted as UTF-8 encoded.
+
+ \see cryptplugwrapper.cpp
+*/
+
+/*! \defgroup groupAdmin Constructor, destructor and setting of 'active' flag
+
+ The functions in this section are used for general administration of
+ this CRYPTPLUG wrapper class and for maintaining a separate \c active flag
+ for environments using more than one CRYPTPLUG library simultaneously.
+*/
+
+/*! \defgroup groupGeneral Loading and Unloading the Plugin, General Functionality
+
+ The functions in this section are used for loading and
+ unloading the respective CRYPTPLUG library, for (re)setting
+ it's internal data structures and for retrieving information
+ on the implementation state of all functions covered by the CRYPTPLUG API.
+*/
+
+/*! \defgroup groupDisplay Graphical Display Functionality
+
+ The functions in this section return stationery that the
+ MUAs can use in order to display security functionality
+ graphically. This can be toolbar icons, shortcuts, tooltips,
+ etc. Not all MUAs will use all this functionality.
+*/
+
+/*! \defgroup groupConfig Configuration Support
+
+ The functions in this section provide the necessary
+ functionality to configure the security functionality as well
+ as to query configuration settings. Since all configuration
+ settings will not be saved with the plugin, but rather with
+ the MUA, there are also functions to set configuration
+ settings programmatically; these will be used on startup of
+ the plugin when the MUA transfers the configuration values it
+ has read into the plugin. Usually, the functions to query and
+ set the configuration values are not needed for anything but
+ saving to and restoring from configuration files.
+*/
+
+
+/*! \defgroup groupConfigSign Signature Configuration
+ \ingroup groupConfig
+
+ The functions in this section provide the functionality
+ to configure signature handling and set and query the
+ signature configuration.
+*/
+
+/*! \defgroup groupConfigCrypt Encryption Configuration
+ \ingroup groupConfig
+
+ The functions in this section provide the functionality
+ to configure encryption handling and set and query the
+ encryption configuration.
+
+ \note Whenever the term <b> encryption</b> is used here,
+ it is supposed to mean both encryption and decryption,
+ unless otherwise specified.
+*/
+
+/*! \defgroup groupConfigDir Directory Service Configuration
+ \ingroup groupConfig
+
+ This section contains messages for configuring the
+ directory service.
+*/
+
+
+/*! \defgroup groupCertHand Certificate Handling
+
+ The following methods are used to maintain and query certificates.
+*/
+
+
+/*! \defgroup groupSignCryptAct Signing and Encrypting Actions
+
+ This section describes methods and structures
+ used for signing and/or encrypting your mails.
+*/
+
+
+/*! \defgroup groupSignAct Signature Actions
+ \ingroup groupSignCryptAct
+
+ This section describes methods that are used for working
+ with signatures.
+*/
+
+/*! \defgroup groupCryptAct Encryption and Decryption
+ \ingroup groupSignCryptAct
+
+ The following methods are used to encrypt and decrypt
+ email messages.
+*/
+
+/*! \defgroup groupCertAct Certificate Handling Actions
+
+ The functions in this section provide local certificate management.
+*/
+
+/*! \defgroup groupCRLAct CRL Handling Actions
+
+ This section describes functions for managing CRLs.
+*/
+
+/*! \defgroup groupAdUsoInterno Important functions to be used by plugin implementors ONLY.
+
+ This section describes functions that have to be used by
+ plugin implementors but should not be used by plugin users
+ directly.
+
+ If you are not planning to write your own cryptography
+ plugin <b>you should ignore this</b> section!
+*/
+
+
+
+class CryptPlugWrapper;
+/*! \ingroup groupSignCryptAct
+ \brief This class provides C++ access to the StructuringInfo helper
+ struct that is specified in cryptplug.h to hold information
+ returned by signing and by encrypting functions.
+
+ Use this information to compose a MIME object containing signed
+ and/or encrypted content (or to build a text frame around your
+ flat non-MIME message body, resp.)
+
+ \note This class is different from the respective cryptplug.h class
+ because this one takes care for freeing the char** members' memory
+ automatically. You must <b>not</b> call the \c free function for
+ any of it's members - just ignore the advise given in the
+ cryptplug.h documentation!
+
+ <b>If</b> value returned in \c makeMimeObject is <b>TRUE</b> the
+ text strings returned in \c contentTypeMain and \c contentDispMain
+ and \c contentTEncMain (and, if required, \c content[..]Version and
+ \c bodyTextVersion and \c content[..]Sig) should be used to compose
+ a respective MIME object.<br>
+ If <b>FALSE</b> the texts returned in \c flatTextPrefix and
+ \c flatTextSeparator and \c flatTextPostfix are to be used instead.<br>
+ Always <b>either</b> the \c content[..] and \c bodyTextVersion
+ parameters <b>or</b> the \c flatText[..] parameters are holding
+ valid data - never both of them may be used simultaneously
+ as plugins will just ignore the parameters not matching their
+ \c makeMimeObject setting.
+
+ When creating your MIME object please observe these common rules:
+ \li Parameters named \c contentType[..] and \c contentDisp[..] and
+ \c contentTEnc[..] will return the values for the respective MIME
+ headers 'Content-Type' and 'Content-Disposition' and
+ 'Content-Transfer-Encoding'. The following applies to these parameters:
+ \li The relevant MIME part may <b>only</b> be created if the respective
+ \c contentType[..] parameter is holding a non-zero-length string. If the
+ \c contentType[..] parameter value is invalid or holding an empty string
+ the respective \c contentDisp[..] and \c contentTEnc[..] parameters
+ should be ignored.
+ \li If the respective \c contentDisp[..] or \c contentTEnc[..] parameter
+ is NULL or holding a zero-length string it is up to you whether you want
+ to add the relevant MIME header yourself, but since it in in the
+ responsibility of the plugin implementors to provide you with all
+ necessary 'Content-[..]' header information you should <b>not need</b>
+ to define them if they are not returned by the signing or encrypting
+ function - otherwise this may be considered as a bug in the plugin and
+ you could report the missing MIME header information to the address
+ returned by the \c bugURL() function.
+
+ If \c makeMultiMime returns FALSE the \c contentTypeMain returned must
+ not be altered but used to specify a single part mime object holding the
+ code bloc, e.g. this is used for 'enveloped-data' single part MIME
+ objects. In this case you should ignore both the \c content[..]Version
+ and \c content[..]Code parameters.
+
+ If \c makeMultiMime returns TRUE also the following rules apply:
+ \li If \c includeCleartext is TRUE you should include the cleartext
+ as first part of our multipart MIME object, typically this is TRUE
+ when signing mails but FALSE when encrypting.
+ \li The \c contentTypeMain returned typically starts with
+ "multipart/" while providing a "protocol" and a "micalg" parameter: just
+ add an appropriate \c "; boundary=[your \c boundary \c string]" to get
+ the complete Content-Type value to be used for the MIME object embedding
+ both the signed part and the signature part (or - in case of
+ encrypting - the version part and the code part, resp.).
+ \li If \c contentTypeVersion is holding a non-zero-length string an
+ additional MIME part must added immediately before the code part, this
+ version part's MIME headers must have the unaltered values of
+ \c contentTypeVersion and (if they are holding non-zero-length strings)
+ \c contentDispVersion and \c contentTEncVersion, the unaltered contents
+ of \c bodyTextVersion must be it's body.
+ \li The value returned in \c contentTypeCode is specifying the complete
+ Content-Type to be used for this multipart MIME object's signature part
+ (or - in case of encrypting - for the code part following after the
+ version part, resp.), you should not add/change/remove anything here
+ but just use it's unaltered value for specifying the Content-Type header
+ of the respective MIME part.
+ \li The same applies to the \c contentDispCode value: just use it's
+ unaltered value to specify the Content-Disposition header entry of
+ the respective MIME part.
+ \li The same applies to the \c contentTEncCode value: just use it's
+ unaltered value to specify the Content-Transfer-Encoding header of
+ the respective MIME part.
+
+ <b>If</b> value returned in \c makeMimeObject is <b>FALSE</b> the
+ text strings returned in \c flatTextPrefix and \c flatTextPostfix
+ should be used to build a frame around the cleartext and the code
+ bloc holding the signature (or - in case of encrypting - the encoded
+ data bloc, resp.).<br>
+ If \c includeCleartext is TRUE this frame should also include the
+ cleartext as first bloc, this bloc should be divided from the code bloc
+ by the contents of \c flatTextSeparator - typically this is used for
+ signing but not when encrypting.<br>
+ If \c includeCleartext is FALSE you should ignore both the cleartext
+ and the \c flatTextSeparator parameter.
+
+ <b>How to use StructuringInfoWrapper data in your program:</b>
+ \li To compose a signed message please act as described below.
+ \li For constructing an encrypted message just replace the
+ \c signMessage() call by the respective \c encryptMessage() call
+ and then proceed exactly the same way.
+ \li In any case make <b>sure</b> to free your \c ciphertext when
+ you are done with processing the data returned by the signing
+ (or encrypting, resp.) function.
+
+\verbatim
+
+ char* ciphertext;
+ StructuringInfoWrapper structInf;
+
+ if( ! signMessage( cleartext, &ciphertext, certificate,
+ structInf ) ) {
+
+ myErrorDialog( "Error: could not sign the message!" );
+
+ } else {
+ if( structInf.data.makeMimeObject ) {
+
+ // Build the main MIME object.
+ // This is done by
+ // using the header values returned in
+ // structInf.data.contentTypeMain and in
+ // structInf.data.contentDispMain and in
+ // structInf.data.contentTEncMain.
+ ..
+
+ if( ! structInf.data.makeMultiMime ) {
+
+ // Build the main MIME object's body.
+ // This is done by
+ // using the code bloc returned in
+ // ciphertext.
+ ..
+
+ } else {
+
+ // Build the encapsulated MIME parts.
+ if( structInf.data.includeCleartext ) {
+
+ // Build a MIME part holding the cleartext.
+ // This is done by
+ // using the original cleartext's headers and by
+ // taking it's original body text.
+ ..
+
+ }
+ if( structInf.data.contentTypeVersion
+ && 0 < strlen( structInf.data.contentTypeVersion ) ) {
+
+ // Build a MIME part holding the version information.
+ // This is done by
+ // using the header values returned in
+ // structInf.data.contentTypeVersion and
+ // structInf.data.contentDispVersion and
+ // structInf.data.contentTEncVersion and by
+ // taking the body contents returned in
+ // structInf.data.bodyTextVersion.
+ ..
+
+ }
+ if( structInf.data.contentTypeCode
+ && 0 < strlen( structInf.data.contentTypeCode ) ) {
+
+ // Build a MIME part holding the code information.
+ // This is done by
+ // using the header values returned in
+ // structInf.data.contentTypeCode and
+ // structInf.data.contentDispCode and
+ // structInf.data.contentTEncCode and by
+ // taking the body contents returned in
+ // ciphertext.
+ ..
+
+ } else {
+
+ // Plugin error!
+ myErrorDialog( "Error: Cryptography plugin returned a main"
+ "Content-Type=Multipart/.. but did not "
+ "specify the code bloc's Content-Type header."
+ "\nYou may report this bug:"
+ "\n" + cryptplug.bugURL() );
+ }
+ }
+ } else {
+
+ // Build a plain message body
+ // based on the values returned in structInf.
+ // Note: We do _not_ insert line breaks between the parts since
+ // it is the plugin job to provide us with ready-to-use
+ // texts containing all necessary line breaks.
+ strcpy( myMessageBody, structInf.data.plainTextPrefix );
+ if( structInf.data.includeCleartext ) {
+ strcat( myMessageBody, cleartext );
+ strcat( myMessageBody, structInf.data.plainTextSeparator );
+ }
+ strcat( myMessageBody, *ciphertext );
+ strcat( myMessageBody, structInf.data.plainTextPostfix );
+ }
+
+ // free the memory that was allocated
+ // for the ciphertext
+ free( ciphertext );
+ }
+
+\endverbatim
+
+ \see signMessage, encryptMessage, encryptAndSignMessage
+*/
+class StructuringInfoWrapper {
+public:
+ StructuringInfoWrapper( CryptPlugWrapper* wrapper );
+ ~StructuringInfoWrapper();
+ void reset();
+ CryptPlug::StructuringInfo data;
+private:
+ void initMe();
+ void freeMe();
+ bool _initDone;
+ CryptPlugWrapper* _wrapper;
+};
+
+
+
+/*!
+ \brief This class provides C++ access to the CRYPTPLUG API.
+*/
+class KDE_EXPORT CryptPlugWrapper : public Kleo::CryptoBackend::Protocol {
+public:
+ static QString errorIdToText( int errId, bool & isPassphraseError );
+
+ /*! \ingroup groupGeneral
+
+ \brief Current initialization state.
+
+ This flag holding status of previous call of initialize function.
+ If initialize was not called before return value will be
+ \c CryptPlugInit_undef.
+
+ \sa initStatus, initialize
+ */
+ typedef enum {
+ InitStatus_undef = 0,
+
+ InitStatus_Ok = 1,
+ InitStatus_NoLibName = 2,
+ InitStatus_LoadError = 0x1000,
+ InitStatus_InitError = 0x2000
+ } InitStatus;
+
+ /*! \ingroup groupSignAct
+ \brief Flags used to compose the SigStatusFlags value.
+
+ This status flags are used to compose the SigStatusFlags value
+ returned in \c SignatureMetaDataExtendedInfo after trying to
+ verify a signed message part's signature status.
+
+ The normal flags may <b>not</b> be used together with the
+ special SigStatus_NUMERICAL_CODE flag. When finding the special
+ SigStatus_NUMERICAL_CODE flag in a SigStatusFlags value you
+ can obtain the respective error code number by substracting
+ the SigStatusFlags value by SigStatus_NUMERICAL_CODE: this is
+ used to transport special status information NOT matching
+ any of the normal predefined status codes.
+
+ \note to PlugIn developers: Implementations of the CryptPlug API
+ should try to express their signature states by bit-wise OR'ing
+ the normal SigStatusFlags values. Using the SigStatus_NUMERICAL_CODE
+ flag should only be used as for exceptional situations where no
+ other flag(s) could be used. By using the normal status flags your
+ PlugIn's users will be told an understandable description of the
+ status - when using (SigStatus_NUMERICAL_CODE + internalCode) they
+ will only be shown the respective code number and have to look
+ into your PlugIn's manual to learn about it's meaning...
+ */
+ enum {
+ SigStatus_UNKNOWN = 0x0000,
+ SigStatus_VALID = SigStat_VALID,
+ SigStatus_GREEN = SigStat_GREEN,
+ SigStatus_RED = SigStat_RED,
+ SigStatus_KEY_REVOKED = SigStat_KEY_REVOKED,
+ SigStatus_KEY_EXPIRED = SigStat_KEY_EXPIRED,
+ SigStatus_SIG_EXPIRED = SigStat_SIG_EXPIRED,
+ SigStatus_KEY_MISSING = SigStat_KEY_MISSING,
+ SigStatus_CRL_MISSING = SigStat_CRL_MISSING,
+ SigStatus_CRL_TOO_OLD = SigStat_CRL_TOO_OLD,
+ SigStatus_BAD_POLICY = SigStat_BAD_POLICY,
+ SigStatus_SYS_ERROR = SigStat_SYS_ERROR,
+
+ SigStatus_NUMERICAL_CODE = 0x8000 /* An other error occurred. */
+ };
+ typedef unsigned long SigStatusFlags;
+
+
+ enum {
+ CertStatus_EXPIRES_NEVER = CRYPTPLUG_CERT_DOES_NEVER_EXPIRE
+ };
+
+
+ /*! \ingroup groupAdmin
+ \brief Constructor of CRYPTPLUG wrapper class.
+
+ This constructor does <b>not</b> call the initialize() method
+ but just stores some information for later use.
+
+ \note Since more than one crypto plug-in might be specified (using
+ multiple instances of the warpper class) it is necessary to
+ set \c active at least one them. Only wrappers that have been
+ activated may be initialized or configured or used to perform
+ crypto actions.
+
+ \param name The external name that is visible in lists, messages,
+ etc.
+ \param libName Complete path+name of CRYPTPLUG library that is to
+ be used by this instance of CryptPlugWrapper.
+ \param update the URL from where updates can be downloaded
+ \param active Specify whether the relative library is to be used
+ or not.
+
+ \sa ~CryptPlugWrapper, setActive, active, initialize, deinitialize
+ \sa initStatus
+ */
+ CryptPlugWrapper( const QString& name=QString::null,
+ const QString& libName=QString::null,
+ const QString& update=QString::null,
+ bool active = false );
+
+ /*! \ingroup groupAdmin
+ \brief Destructor of CRYPTPLUG wrapper class.
+
+ This destructor <b>does</b> call the deinitialize() method in case
+ this was not done by explicitly calling it before.
+
+ \sa deinitialize, initialize, CryptPlugWrapper(), setActive, active
+ \sa
+ */
+ ~CryptPlugWrapper();
+
+ QString protocol() const;
+
+ QString name() const {
+ return protocol();
+ }
+
+ /*! \ingroup groupAdmin
+ \brief Set this CRYPTPLUG wrapper's internal \c active flag.
+
+ Since more than one crypto plug-in might be specified (using
+ multiple instances of the warpper class) it is necessary to
+ set \c active at least one them. Only wrappers that have been
+ activated may be initialized or configured or used to perform
+ crypto actions.
+
+ This flag may be set in the constructor or by calling setActive().
+
+ \note Deactivating does <b>not</b> mean resetting the internal
+ structures - if just prevents the normal functions from
+ being called erroneously. When deactivated only the following
+ functions are operational: constructor , destructor ,
+ setActive , active, setLibName , libName , initStatus;
+ calling other functions will be ignored and their return
+ values will be undefined.
+
+ \param active Specify whether the relative library is to be used
+ or not.
+
+ \sa active, CryptPlugWrapper(), ~CryptPlugWrapper
+ \sa deinitialize, initialize, initStatus
+ */
+ void setActive( bool active );
+
+ /*! \ingroup groupAdmin
+ \brief Returns this CRYPTPLUG wrapper's internal \c active flag.
+
+ \return whether the relative library is to be used or not.
+
+ \sa setActive
+ */
+ bool active() const;
+
+
+ /*! \ingroup groupAdmin
+ \brief Set the CRYPTPLUG library name.
+
+ Complete path+name of CRYPTPLUG library that is to
+ be used by this instance of CryptPlugWrapper.
+
+ This name may be set in the constructor or by calling setLibName().
+
+ \note Setting/changing the library name may only be done when
+ the initStatus() is <b>not</b> \c InitStatus_Ok.
+ If you want to change the name of the library after
+ successfully having called initialize() please make
+ sure to unload it by calling the deinitialize() function.
+
+ \param libName libName Complete path+name of CRYPTPLUG library
+ that is to be used by this CryptPlugWrapper.
+
+ \return whether the library name could be changed; library name
+ can only be changed when library is not initialized - see
+ above 'note'.
+
+ \sa libName, CryptPlugWrapper(), ~CryptPlugWrapper
+ \sa deinitialize, initialize, initStatus
+ */
+ bool setLibName( const QString& libName );
+
+ /*! \ingroup groupAdmin
+ \brief Returns the CRYPTPLUG library name.
+
+ \return the complete path+name of CRYPTPLUG library that is to
+ be used by this instance of CryptPlugWrapper.
+
+ \sa setLibName
+ */
+ QString libName() const;
+
+
+ /*! \ingroup groupAdmin
+ \brief Specifies the external name that is visible in lists,
+ messages, etc.
+ */
+ void setDisplayName( const QString& name );
+
+
+ /*! \ingroup groupAdmin
+ \brief Returns the external name.
+ \return the external name used for display purposes
+ */
+ QString displayName() const;
+
+private:
+ /*! \ingroup groupGeneral
+ \brief This function does two things: (a) load the lib and (b) set up all internal structures.
+
+ The method tries to load the CRYPTPLUG library specified
+ in the constructor and returns \c true if the both <b>loading
+ and initializing</b> the internal data structures was successful
+ and \c false otherwise. Before this function is called,
+ no other plugin functions should be called; the behavior is
+ undefined in this case, this rule does not apply to the functions
+ \c setActive() and \c setLibName().
+
+ \param initStatus will receive the resulting InitStatus if not NULL
+ \param errorMsg will receive the system error message if not NULL
+
+ \sa initStatus, deinitialize, CryptPlugWrapper(), ~CryptPlugWrapper
+ \sa setActive, active
+ */
+ bool initialize( InitStatus* initStatus, QString* errorMsg );
+
+public:
+ /*! \ingroup groupGeneral
+ \brief This function unloads the lib and frees all internal structures.
+
+ After this function has been called, no other plugin functions
+ should be called; the behavior is undefined in this case.
+
+ \note Deinitializing sets the internal initStatus value back
+ to \c InitStatus_undef.
+
+ \sa initStatus, initialize, CryptPlugWrapper, ~CryptPlugWrapper
+ \sa setActive, active
+ */
+ void deinitialize();
+
+ /*! \ingroup groupGeneral
+ \brief Returns this CRYPTPLUG wrapper's initialization state.
+
+ \param errorMsg receives the last system error message, this value
+ should be ignored if InitStatus value equals \c InitStatus_Ok.
+
+ \return whether the relative library was loaded and initialized
+ correctly
+
+ \sa initialize, deinitialize, CryptPlugWrapper(), ~CryptPlugWrapper
+ \sa setActive, active
+ */
+ InitStatus initStatus( QString* errorMsg ) const;
+
+
+ /*! \ingroup groupGeneral
+ \brief This function returns \c true if the
+ specified feature is available in the plugin, and
+ \c false otherwise.
+
+ Not all plugins will support all features; a complete Sphinx
+ implementation will support all features contained in the enum,
+ however.
+
+ \note In case this function cannot be executed the system's error
+ message may be retrieved by calling initStatus( QString* ).
+
+ \return whether the relative feature is implemented or not
+ */
+ bool hasFeature( ::Feature );
+
+
+ /* \ingroup groupSignAct
+ * Frees the members of a signature meta data struct, but not the
+ * signature meta data struct itself as this could be allocated on
+ * the stack.
+ */
+ void freeSignatureMetaData( CryptPlug::SignatureMetaData* );
+
+ /*! \ingroup groupSignAct
+ \brief Checks whether the signature of a message is
+ valid.
+
+ \c cleartext must never be 0 but be a valid pointer.
+
+ If \c *cleartext > 0 then **cleartext specifies the message text
+ that was signed and \c signaturetext is the signature itself.
+
+ If \c *cleartext == 0 is an empty string then \c signaturetext is
+ supposed to contain an opaque signed message part. After checking the
+ data and verifying the signature the cleartext of the message will be
+ returned in \c cleartext. The user must free the respective memory
+ occupied by *cleartext.
+
+ Depending on the configuration, MUAs might not need to use this.
+ If \c sigmeta is non-null, the
+ \c SignatureMetaData object pointed to will
+ contain meta information about the signature after the
+ function call.
+ */
+ bool checkMessageSignature( char** cleartext,
+ const char* signaturetext,
+ bool signatureIsBinary,
+ int signatureLen,
+ CryptPlug::SignatureMetaData* sigmeta );
+
+ /*! \ingroup groupCryptAct
+ \brief Tries to decrypt an email message
+ \c ciphertext and returns the decrypted
+ message in \c cleartext.
+
+ The \c certificate is used for decryption. If
+ the message could be decrypted, the function returns
+ \c true, otherwise
+ \c false.
+ */
+ bool decryptMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ int* errId,
+ char** errTxt );
+
+ /*! \ingroup groupCryptAct
+ \brief Combines the functionality of
+ \c checkMessageSignature() and
+ \c decryptMessage().
+
+ If \c certificate is \c NULL,
+ the default certificate will be used. If
+ \c sigmeta is non-null, the
+ \c SignatureMetaData object pointed to will
+ contain meta information about the signature after the
+ function call.
+ */
+ bool decryptAndCheckMessage( const char* ciphertext,
+ bool cipherIsBinary,
+ int cipherLen,
+ char** cleartext,
+ const char* certificate,
+ bool* signatureFound,
+ CryptPlug::SignatureMetaData* sigmeta,
+ int* errId,
+ char** errTxt );
+
+ Kleo::KeyListJob * keyListJob( bool remote=false, bool includeSigs=false, bool validate=true ) const;
+ Kleo::EncryptJob * encryptJob( bool armor=false, bool textmode=false ) const;
+ Kleo::DecryptJob * decryptJob() const;
+ Kleo::SignJob * signJob( bool armor=false, bool textMode=false ) const;
+ Kleo::VerifyDetachedJob * verifyDetachedJob( bool textmode=false) const;
+ Kleo::VerifyOpaqueJob * verifyOpaqueJob( bool textmode=false ) const;
+ Kleo::KeyGenerationJob * keyGenerationJob() const;
+
+ Kleo::ImportJob * importJob() const;
+ Kleo::ExportJob * publicKeyExportJob( bool armor=false ) const;
+ Kleo::ExportJob * secretKeyExportJob( bool armor=false, const QString& charset = QString::null ) const;
+ Kleo::DownloadJob * downloadJob( bool armor=false ) const;
+ Kleo::DeleteJob * deleteJob() const;
+
+ Kleo::SignEncryptJob * signEncryptJob( bool armor=false, bool textmode=false ) const;
+ Kleo::DecryptVerifyJob * decryptVerifyJob( bool textmode=false ) const;
+ Kleo::RefreshKeysJob * refreshKeysJob() const;
+
+ Kleo::SpecialJob * specialJob( const char *, const QMap<QString,QVariant> & ) const { return 0; }
+
+ GpgME::ImportResult importCertificate( const char* data, size_t length );
+
+ CryptPlug * cryptPlug() const { return _cp; }
+
+private:
+ QString _name;
+ QString _libName;
+ QString _updateURL;
+ bool _active;
+ InitStatus _initStatus;
+ QString _lastError;
+ CryptPlug* _cp;
+ // local parameters without representation in cryptplug.h
+ bool mAlwaysEncryptToSelf;
+ class Config;
+ Config * _config;
+ QGpgMECryptoConfig * _cryptoConfig;
+};
+
+#endif // !LIBKLEOPATRA_NO_COMPAT
+
+#endif // cryptplugwrapper_h
diff --git a/certmanager/lib/cryptplugwrapperlist.cpp b/certmanager/lib/cryptplugwrapperlist.cpp
new file mode 100644
index 000000000..3ff38ddd8
--- /dev/null
+++ b/certmanager/lib/cryptplugwrapperlist.cpp
@@ -0,0 +1,34 @@
+/* -*- c++ -*-
+
+ CRYPTPLUG - an independent cryptography plug-in
+ API. CryptPlugWrapperList holds any number of crypto plug-ins.
+
+ Copyright (C) 2001 by Klarälvdalens Datakonsult AB
+
+ CRYPTPLUG is free software; you can redistribute it and/or modify
+ it under the terms of GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ CRYPTPLUG is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cryptplugwrapperlist.h"
+
+CryptPlugWrapper * CryptPlugWrapperList::findForLibName( const QString & libName ) const
+{
+ for ( QPtrListIterator<CryptPlugWrapper> it( *this ) ; it.current() ; ++it )
+ if ( (*it)->libName().find( libName, 0, false ) >= 0 )
+ return *it;
+ return 0;
+}
diff --git a/certmanager/lib/cryptplugwrapperlist.h b/certmanager/lib/cryptplugwrapperlist.h
new file mode 100644
index 000000000..3fab5799c
--- /dev/null
+++ b/certmanager/lib/cryptplugwrapperlist.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++ -*-
+
+ CRYPTPLUG - an independent cryptography plug-in
+ API. CryptPlugWrapperList holds any number of crypto plug-ins.
+
+ Copyright (C) 2001,2004 by Klarälvdalens Datakonsult AB
+
+ CRYPTPLUG is free software; you can redistribute it and/or modify
+ it under the terms of GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ CRYPTPLUG is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef __CRYPTPLUGWRAPPERLIST_H__
+#define __CRYPTPLUGWRAPPERLIST_H__
+
+#include "cryptplugwrapper.h"
+
+#include <qptrlist.h>
+
+class CryptPlugWrapperList : public QPtrList<CryptPlugWrapper>
+{
+public:
+ CryptPlugWrapper * findForLibName( const QString & libName ) const;
+};
+
+typedef QPtrListIterator<CryptPlugWrapper> CryptPlugWrapperListIterator;
+
+#endif
diff --git a/certmanager/lib/kleo/Makefile.am b/certmanager/lib/kleo/Makefile.am
new file mode 100644
index 000000000..0465bb2da
--- /dev/null
+++ b/certmanager/lib/kleo/Makefile.am
@@ -0,0 +1,37 @@
+INCLUDES = -I$(top_srcdir)/libkdenetwork \
+ -I$(top_srcdir)/certmanager/lib \
+ $(GPGME_CFLAGS) $(all_includes)
+
+noinst_LTLIBRARIES = libkleopatra_core.la
+
+libkleopatra_core_la_SOURCES = \
+ cryptobackend.cpp \
+ cryptobackendfactory.cpp \
+ enum.cpp \
+ dn.cpp \
+ job.cpp \
+ \
+ multideletejob.cpp \
+ hierarchicalkeylistjob.cpp \
+ \
+ kconfigbasedkeyfilter.cpp \
+ keyfiltermanager.cpp
+
+kleodir = $(includedir)/kleo
+kleo_HEADERS = \
+ enum.h \
+ cryptobackend.h \
+ cryptobackendfactory.h \
+ cryptoconfig.h \
+ dn.h \
+ job.h \
+ keylistjob.h keygenerationjob.h importjob.h exportjob.h downloadjob.h deletejob.h \
+ encryptjob.h decryptjob.h signjob.h verifydetachedjob.h verifyopaquejob.h \
+ decryptverifyjob.h signencryptjob.h refreshkeysjob.h \
+ multideletejob.h \
+ hierarchicalkeylistjob.h \
+ \
+ keyfilter.h \
+ keyfiltermanager.h
+
+METASOURCES = AUTO
diff --git a/certmanager/lib/kleo/cryptobackend.cpp b/certmanager/lib/kleo/cryptobackend.cpp
new file mode 100644
index 000000000..7a779c8ed
--- /dev/null
+++ b/certmanager/lib/kleo/cryptobackend.cpp
@@ -0,0 +1,36 @@
+/*
+ kleo/cryptobackend.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "cryptobackend.h"
+
+const char Kleo::CryptoBackend::OpenPGP[] = "OpenPGP";
+const char Kleo::CryptoBackend::SMIME[] = "SMIME";
diff --git a/certmanager/lib/kleo/cryptobackend.h b/certmanager/lib/kleo/cryptobackend.h
new file mode 100644
index 000000000..a94e1ae3a
--- /dev/null
+++ b/certmanager/lib/kleo/cryptobackend.h
@@ -0,0 +1,122 @@
+/*
+ kleo/cryptobackend.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_CRYPTOBACKEND_H__
+#define __KLEO_CRYPTOBACKEND_H__
+
+#include <qstring.h>
+
+namespace Kleo {
+ class CryptoConfig;
+ class KeyListJob;
+ class KeyGenerationJob;
+ class ImportJob;
+ class ExportJob;
+ class DownloadJob;
+ class DeleteJob;
+ class EncryptJob;
+ class DecryptJob;
+ class SignJob;
+ class VerifyDetachedJob;
+ class VerifyOpaqueJob;
+ class SignEncryptJob;
+ class DecryptVerifyJob;
+ class RefreshKeysJob;
+ class SpecialJob;
+}
+
+class QString;
+class QVariant;
+template <typename T_Key, typename T_Value> class QMap;
+
+namespace Kleo {
+
+ class CryptoBackend {
+ public:
+ class Protocol;
+
+ static const char OpenPGP[];
+ static const char SMIME[];
+
+ virtual ~CryptoBackend() {}
+
+ virtual QString name() const = 0;
+ virtual QString displayName() const = 0;
+
+ virtual bool checkForOpenPGP( QString * reason=0 ) const = 0;
+ virtual bool checkForSMIME( QString * reason=0 ) const = 0;
+ virtual bool checkForProtocol( const char * name, QString * reason=0 ) const = 0;
+
+ virtual bool supportsOpenPGP() const = 0;
+ virtual bool supportsSMIME() const = 0;
+ virtual bool supportsProtocol( const char * name ) const = 0;
+
+ virtual CryptoConfig * config() const = 0;
+
+ virtual Protocol * openpgp() const = 0;
+ virtual Protocol * smime() const = 0;
+ virtual Protocol * protocol( const char * name ) const = 0;
+
+ virtual const char * enumerateProtocols( int i ) const = 0;
+ };
+
+ class CryptoBackend::Protocol {
+ public:
+ virtual ~Protocol() {}
+
+ virtual QString name() const = 0;
+
+ virtual QString displayName() const = 0;
+
+ virtual KeyListJob * keyListJob( bool remote=false, bool includeSigs=false, bool validate=false ) const = 0;
+ virtual EncryptJob * encryptJob( bool armor=false, bool textmode=false ) const = 0;
+ virtual DecryptJob * decryptJob() const = 0;
+ virtual SignJob * signJob( bool armor=false, bool textMode=false ) const = 0;
+ virtual VerifyDetachedJob * verifyDetachedJob( bool textmode=false) const = 0;
+ virtual VerifyOpaqueJob * verifyOpaqueJob( bool textmode=false ) const = 0;
+ virtual KeyGenerationJob * keyGenerationJob() const = 0;
+ virtual ImportJob * importJob() const = 0;
+ virtual ExportJob * publicKeyExportJob( bool armor=false ) const = 0;
+ // @param charset the encoding of the passphrase in the exported file
+ virtual ExportJob * secretKeyExportJob( bool armor=false, const QString& charset = QString::null ) const = 0;
+ virtual DownloadJob * downloadJob( bool armor=false ) const = 0;
+ virtual DeleteJob * deleteJob() const = 0;
+ virtual SignEncryptJob * signEncryptJob( bool armor=false, bool textMode=false ) const = 0;
+ virtual DecryptVerifyJob * decryptVerifyJob( bool textmode=false ) const = 0;
+ virtual RefreshKeysJob * refreshKeysJob() const = 0;
+
+ virtual SpecialJob * specialJob( const char * type, const QMap<QString,QVariant> & args ) const = 0;
+ };
+
+}
+
+#endif // __KLEO_CRYPTOBACKEND_H__
diff --git a/certmanager/lib/kleo/cryptobackendfactory.cpp b/certmanager/lib/kleo/cryptobackendfactory.cpp
new file mode 100644
index 000000000..c56a7096f
--- /dev/null
+++ b/certmanager/lib/kleo/cryptobackendfactory.cpp
@@ -0,0 +1,275 @@
+/*
+ cryptobackendfactory.cpp
+
+ This file is part of libkleopatra, the KDE key management library
+ Copyright (c) 2001,2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "cryptobackendfactory.h"
+
+#include <backends/qgpgme/qgpgmebackend.h>
+#if 0 // disabled for kde-3.3
+#include <backends/kpgp/pgp2backend.h>
+#include <backends/kpgp/pgp5backend.h>
+#include <backends/kpgp/pgp6backend.h>
+#include <backends/kpgp/gpg1backend.h>
+#endif
+#include <backends/chiasmus/chiasmusbackend.h>
+#include <ui/backendconfigwidget.h>
+
+#include <kconfig.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+
+#include <iterator>
+#include <algorithm>
+
+#include <cassert>
+
+Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::mSelf = 0;
+
+static const char * availableProtocols[] = {
+ "Chiasmus",
+ "OpenPGP", "SMIME",
+};
+static const unsigned int numAvailableProtocols = sizeof availableProtocols / sizeof *availableProtocols;
+
+Kleo::CryptoBackendFactory::CryptoBackendFactory()
+ : QObject( qApp, "CryptoBackendFactory::instance()" ),
+ mConfigObject( 0 ),
+ mAvailableProtocols( availableProtocols, availableProtocols + numAvailableProtocols )
+{
+ mBackendList.push_back( new QGpgMEBackend() );
+#if 0 // disabled for kde-3.3
+ mBackendList.push_back( new PGP2Backend() );
+ mBackendList.push_back( new PGP5Backend() );
+ mBackendList.push_back( new PGP6Backend() );
+ mBackendList.push_back( new GPG1Backend() );
+#endif
+ mBackendList.push_back( new ChiasmusBackend() );
+ scanForBackends();
+ readConfig();
+
+ mSelf = this; // last!
+}
+
+Kleo::CryptoBackendFactory::~CryptoBackendFactory() {
+ mSelf = 0; // first!
+
+ for ( std::vector<CryptoBackend*>::iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
+ delete *it;
+ *it = 0;
+ }
+ delete mConfigObject;
+ mConfigObject = 0;
+}
+
+Kleo::CryptoBackendFactory * Kleo::CryptoBackendFactory::instance() {
+ if ( !mSelf )
+ mSelf = new CryptoBackendFactory();
+ return mSelf;
+}
+
+
+// const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::smimeBackend() const {
+// return mSMIMEBackend;
+// }
+
+// const Kleo::CryptoBackend* Kleo::CryptoBackendFactory::openpgpBackend() const {
+// return mOpenPGPBackend;
+// }
+
+const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::smime() const {
+ const BackendMap::const_iterator it = mBackends.find( "SMIME" );
+ if ( it == mBackends.end() )
+ return 0;
+ if ( !it->second )
+ return 0;
+ return it->second->smime();
+}
+
+const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::openpgp() const {
+ const BackendMap::const_iterator it = mBackends.find( "OpenPGP" );
+ if ( it == mBackends.end() )
+ return 0;
+ if ( !it->second )
+ return 0;
+ return it->second->openpgp();
+}
+
+const Kleo::CryptoBackend::Protocol * Kleo::CryptoBackendFactory::protocol( const char * name ) const {
+ const BackendMap::const_iterator it = mBackends.find( name );
+ if ( it == mBackends.end() )
+ return 0;
+ if ( !it->second )
+ return 0;
+ return it->second->protocol( name );
+}
+
+Kleo::CryptoConfig * Kleo::CryptoBackendFactory::config() const {
+ // ## should we use mSMIMEBackend? mOpenPGPBackend? backend(0) i.e. always qgpgme?
+ return backend( 0 ) ? backend( 0 )->config() : 0;
+}
+
+bool Kleo::CryptoBackendFactory::hasBackends() const {
+ return !mBackendList.empty();
+}
+
+void Kleo::CryptoBackendFactory::scanForBackends( QStringList * reasons ) {
+ for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
+ assert( *it );
+ for ( int i = 0 ; const char * protocol = (*it)->enumerateProtocols( i ) ; ++i ) {
+ QString reason;
+ if ( (*it)->supportsProtocol( protocol ) && !(*it)->checkForProtocol( protocol, &reason ) ) {
+ if ( reasons ) {
+ reasons->push_back( i18n("While scanning for %1 support in backend %2:")
+ .arg( protocol, (*it)->displayName() ) );
+ reasons->push_back( " " + reason );
+ }
+ }
+ }
+ }
+}
+
+const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backend( unsigned int idx ) const {
+ return ( idx < mBackendList.size() ) ? mBackendList[idx] : 0 ;
+}
+
+const Kleo::CryptoBackend * Kleo::CryptoBackendFactory::backendByName( const QString& name ) const {
+ for ( std::vector<CryptoBackend*>::const_iterator it = mBackendList.begin() ; it != mBackendList.end() ; ++it ) {
+ if ( (*it)->name() == name )
+ return *it;
+ }
+ return 0;
+}
+
+Kleo::BackendConfigWidget * Kleo::CryptoBackendFactory::configWidget( QWidget * parent, const char * name ) const {
+ return new Kleo::BackendConfigWidget( mSelf, parent, name );
+}
+
+KConfig* Kleo::CryptoBackendFactory::configObject() const {
+ if ( !mConfigObject )
+ // this is unsafe. We're a lib, used by concurrent apps.
+ mConfigObject = new KConfig( "libkleopatrarc" );
+ return mConfigObject;
+}
+
+void Kleo::CryptoBackendFactory::setSMIMEBackend( const CryptoBackend* backend ) {
+ setProtocolBackend( "SMIME", backend );
+}
+
+void Kleo::CryptoBackendFactory::setOpenPGPBackend( const CryptoBackend* backend ) {
+ setProtocolBackend( "OpenPGP", backend );
+}
+
+void Kleo::CryptoBackendFactory::setProtocolBackend( const char * protocol, const CryptoBackend * backend ) {
+ const QString name = backend ? backend->name() : QString::null ;
+ KConfigGroup group( configObject(), "Backends" );
+ group.writeEntry( protocol, name );
+ configObject()->sync();
+ mBackends[protocol] = backend;
+}
+
+static const char * defaultBackend( const char * proto ) {
+ static const struct {
+ const char * proto;
+ const char * backend;
+ } defaults[] = {
+ { "OpenPGP", "gpgme" },
+ { "SMIME", "gpgme" },
+ { "Chiasmus", "chiasmus" },
+ };
+ for ( unsigned int i = 0 ; i < sizeof defaults / sizeof *defaults ; ++i )
+ if ( qstricmp( proto, defaults[i].proto ) == 0 )
+ return defaults[i].backend;
+ return 0;
+}
+
+void Kleo::CryptoBackendFactory::readConfig() {
+ mBackends.clear();
+ const KConfigGroup group( configObject(), "Backends" );
+ for ( ProtocolSet::const_iterator it = mAvailableProtocols.begin(), end = mAvailableProtocols.end() ; it != end ; ++it ) {
+ const QString backend = group.readEntry( *it, defaultBackend( *it ) );
+ mBackends[*it] = backendByName( backend );
+ }
+}
+
+const char * Kleo::CryptoBackendFactory::enumerateProtocols( int i ) const {
+ if ( i < 0 || static_cast<unsigned int>( i ) >= mAvailableProtocols.size() )
+ return 0;
+ return mAvailableProtocols[i];
+}
+
+namespace {
+ class CaseInsensitiveString {
+ const char * m;
+ public:
+ CaseInsensitiveString( const char * s ) : m( s ) {}
+#define make_operator( op ) \
+ bool operator op( const CaseInsensitiveString & other ) const { \
+ return qstricmp( m, other.m ) op 0; \
+ } \
+ bool operator op( const char * other ) const { \
+ return qstricmp( m, other ) op 0; \
+ }
+ make_operator( == )
+ make_operator( != )
+ make_operator( < )
+ make_operator( > )
+ make_operator( <= )
+ make_operator( >= )
+#undef make_operator
+ operator const char *() const { return m; }
+ };
+#define make_ext_operator( op, inv_op ) \
+ inline bool operator op( const char * lhs, const CaseInsensitiveString & rhs ) { \
+ return rhs.operator inv_op( lhs ); \
+ }
+ make_ext_operator( ==, == )
+ make_ext_operator( !=, != )
+ make_ext_operator( <, > )
+ make_ext_operator( >, < )
+ make_ext_operator( <=, >= )
+ make_ext_operator( >=, <= )
+#undef make_ext_operator
+
+}
+
+bool Kleo::CryptoBackendFactory::knowsAboutProtocol( const char * name ) const {
+ return std::find( mAvailableProtocols.begin(), mAvailableProtocols.end(),
+ CaseInsensitiveString( name ) ) != mAvailableProtocols.end();
+}
+
+#include "cryptobackendfactory.moc"
+
diff --git a/certmanager/lib/kleo/cryptobackendfactory.h b/certmanager/lib/kleo/cryptobackendfactory.h
new file mode 100644
index 000000000..7a54e9fd1
--- /dev/null
+++ b/certmanager/lib/kleo/cryptobackendfactory.h
@@ -0,0 +1,117 @@
+/*
+ kleo/cryptobackendfactory.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_CRYPTOBACKENDFACTORY_H__
+#define __KLEO_CRYPTOBACKENDFACTORY_H__
+
+#include <qobject.h>
+
+#include "cryptobackend.h"
+#include <kdepimmacros.h>
+
+#include <vector>
+#include <map>
+
+namespace Kleo {
+ class BackendConfigWidget;
+}
+
+class QString;
+class KConfig;
+
+namespace Kleo {
+
+ struct lt_i_str {
+ bool operator()( const char * one, const char * two ) const {
+ return qstricmp( one, two ) < 0;
+ }
+ };
+
+ class KDE_EXPORT CryptoBackendFactory : public QObject {
+ Q_OBJECT
+ protected:
+ CryptoBackendFactory();
+ ~CryptoBackendFactory();
+ public:
+ static CryptoBackendFactory * instance();
+
+ const CryptoBackend::Protocol * smime() const;
+ const CryptoBackend::Protocol * openpgp() const;
+ const CryptoBackend::Protocol * protocol( const char * name ) const;
+ CryptoConfig * config() const;
+
+ const CryptoBackend * backend( unsigned int idx ) const;
+
+ bool hasBackends() const;
+
+ Kleo::BackendConfigWidget * configWidget( QWidget * parent=0, const char * name=0 ) const;
+
+ KConfig* configObject() const;
+
+ // The preferred backend for smime (can be 0) - currently unused
+ //const CryptoBackend* smimeBackend() const;
+ // The preferred backend for openpgp (can be 0) - currently unused
+ //const CryptoBackend* openpgpBackend() const;
+
+ // For BackendConfigWidget to save the configuration
+ // 0 means no backend selected.
+ void setSMIMEBackend( const CryptoBackend* backend );
+ void setOpenPGPBackend( const CryptoBackend* backend );
+ void setProtocolBackend( const char * name, const CryptoBackend * backend );
+
+ void scanForBackends( QStringList * reasons=0 );
+
+ const char * enumerateProtocols( int i ) const;
+
+ bool knowsAboutProtocol( const char * name ) const;
+
+ protected:
+ std::vector<CryptoBackend*> mBackendList;
+ mutable KConfig* mConfigObject;
+ typedef std::map<const char *, const CryptoBackend*, lt_i_str> BackendMap;
+ BackendMap mBackends;
+ typedef std::vector<const char *> ProtocolSet;
+ ProtocolSet mAvailableProtocols;
+
+ private:
+ const CryptoBackend * backendByName( const QString& name ) const;
+ void readConfig();
+ CryptoBackendFactory( const CryptoBackendFactory & );
+ void operator=( const CryptoBackendFactory & );
+
+ static CryptoBackendFactory * mSelf;
+ };
+
+
+}
+
+#endif // __KLEO_CRYPTOBACKENDFACTORY_H__
diff --git a/certmanager/lib/kleo/cryptoconfig.h b/certmanager/lib/kleo/cryptoconfig.h
new file mode 100644
index 000000000..da16ca5b5
--- /dev/null
+++ b/certmanager/lib/kleo/cryptoconfig.h
@@ -0,0 +1,387 @@
+/*
+ cryptoconfig.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CRYPTOCONFIG_H
+#define CRYPTOCONFIG_H
+
+#ifdef __cplusplus
+/* we read this file from a C compiler, and are only interested in the
+ * enums... */
+
+#include <kurl.h>
+
+/* Start reading this file from the bottom up :) */
+
+namespace Kleo {
+
+ /**
+ * Description of a single option
+ */
+ class CryptoConfigEntry {
+
+ public:
+#endif /* __cplusplus */
+ /**
+ @li basic This option should always be offered to the user.
+ @li advanced This option may be offered to advanced users.
+ @li expert This option should only be offered to expert users.
+ */
+ enum Level { Level_Basic = 0,
+ Level_Advanced = 1,
+ Level_Expert = 2 };
+
+ /**
+ Type of the argument
+ @li ArgType_None The option is set or not set, but no argument.
+ @li ArgType_String An unformatted string.
+ @li ArgType_Int A signed integer number.
+ @li ArgType_UInt An unsigned integer number.
+ @li ArgType_Path A string that describes the pathname of a file.
+ The file does not necessarily need to exist.
+ Separated from string so that e.g. a KURLRequester can be used.
+ @li ArgType_DirPath A string that describes the pathname of a directory.
+ The directory does not necessarily need to exist.
+ Separated from path so that e.g. a KURLRequester can be used which only
+ allows directories to be selected.
+ @li ArgType_URL A URL
+ @li ArgType_LDAPURL A LDAP URL
+ Separated from URL so that a more specific widget can be shown, hiding the url syntax
+ */
+ enum ArgType { ArgType_None = 0,
+ ArgType_String = 1,
+ ArgType_Int = 2,
+ ArgType_UInt = 3,
+ ArgType_Path = 4,
+ ArgType_URL = 5,
+ ArgType_LDAPURL = 6,
+ ArgType_DirPath = 7 };
+
+#ifdef __cplusplus
+ virtual ~CryptoConfigEntry() {}
+
+ /**
+ * Return the internal name of this entry
+ */
+ virtual QString name() const = 0;
+
+ /**
+ * @return user-visible description of this entry
+ */
+ virtual QString description() const = 0;
+
+ /**
+ * @return true if the argument is optional
+ */
+ virtual bool isOptional() const = 0;
+
+ /**
+ * @return true if the entry is readonly
+ */
+ virtual bool isReadOnly() const = 0;
+
+ /**
+ * @return true if the argument can be given multiple times
+ */
+ virtual bool isList() const = 0;
+
+ /**
+ * @return true if the argument can be changed at runtime
+ */
+ virtual bool isRuntime() const = 0;
+
+ /**
+ * User level
+ */
+ virtual Level level() const = 0;
+
+ /**
+ * Argument type
+ */
+ virtual ArgType argType() const = 0;
+
+ /**
+ * Return true if the option is set, i.e. different from default
+ */
+ virtual bool isSet() const = 0;
+
+ /**
+ * Return value as a bool (only allowed for ArgType_None)
+ */
+ virtual bool boolValue() const = 0;
+
+ /**
+ * Return value as a string (available for all argtypes)
+ * The returned string can be empty (explicitely set to empty) or null (not set).
+ */
+ virtual QString stringValue() const = 0;
+
+ /**
+ * Return value as a signed int
+ */
+ virtual int intValue() const = 0;
+
+ /**
+ * Return value as an unsigned int
+ */
+ virtual unsigned int uintValue() const = 0;
+
+ /**
+ * Return value as a URL (only meaningful for Path and URL argtypes)
+ */
+ virtual KURL urlValue() const = 0;
+
+ /**
+ * Return number of times the option is set (only valid for ArgType_None, if isList())
+ */
+ virtual unsigned int numberOfTimesSet() const = 0;
+
+ /**
+ * Return value as a list of strings (mostly meaningful for String, Path and URL argtypes, if isList())
+ */
+ virtual QStringList stringValueList() const = 0;
+
+ /**
+ * Return value as a list of signed ints
+ */
+ virtual QValueList<int> intValueList() const = 0;
+
+ /**
+ * Return value as a list of unsigned ints
+ */
+ virtual QValueList<unsigned int> uintValueList() const = 0;
+
+ /**
+ * Return value as a list of URLs (only meaningful for Path and URL argtypes, if isList())
+ */
+ virtual KURL::List urlValueList() const = 0;
+
+ /**
+ * Reset an option to its default value
+ */
+ virtual void resetToDefault() = 0;
+
+ /**
+ * Define whether the option is set or not (only allowed for ArgType_None)
+ * #### TODO: and for options with optional args
+ */
+ virtual void setBoolValue( bool ) = 0;
+
+ /**
+ * Set string value (allowed for all argtypes)
+ */
+ virtual void setStringValue( const QString& ) = 0;
+
+ /**
+ * Set a new signed int value
+ */
+ virtual void setIntValue( int ) = 0;
+
+ /**
+ * Set a new unsigned int value
+ */
+ virtual void setUIntValue( unsigned int ) = 0;
+
+ /**
+ * Set value as a URL (only meaningful for Path (if local) and URL argtypes)
+ */
+ virtual void setURLValue( const KURL& ) = 0;
+
+ /**
+ * Set the number of times the option is set (only valid for ArgType_None, if isList())
+ */
+ virtual void setNumberOfTimesSet( unsigned int ) = 0;
+
+ /**
+ * Set a new string-list value (only allowed for String, Path and URL argtypes, if isList())
+ */
+ virtual void setStringValueList( const QStringList& ) = 0;
+
+ /**
+ * Set a new list of signed int values
+ */
+ virtual void setIntValueList( const QValueList<int>& ) = 0;
+
+ /**
+ * Set a new list of unsigned int values
+ */
+ virtual void setUIntValueList( const QValueList<unsigned int>& ) = 0;
+
+ /**
+ * Set value as a URL list (only meaningful for Path (if all URLs are local) and URL argtypes, if isList())
+ */
+ virtual void setURLValueList( const KURL::List& ) = 0;
+
+ /**
+ * @return true if the value was changed
+ */
+ virtual bool isDirty() const = 0;
+ };
+
+ /**
+ * Group containing a set of config options
+ */
+ class CryptoConfigGroup {
+
+ public:
+ virtual ~CryptoConfigGroup() {}
+
+ /**
+ * Return the internal name of this group
+ */
+ virtual QString name() const = 0;
+
+ /**
+ * Return the name of the icon for this group
+ */
+ virtual QString iconName() const = 0;
+
+ /**
+ * @return user-visible description of this group
+ */
+ virtual QString description() const = 0;
+
+ /**
+ * User level
+ */
+ virtual CryptoConfigEntry::Level level() const = 0;
+
+ /**
+ * Returns the list of entries that are known by this group.
+ *
+ * @return list of group entry names.
+ **/
+ virtual QStringList entryList() const = 0;
+
+ /**
+ * @return the configuration object for a given entry in this group
+ * The object is owned by CryptoConfigGroup, don't delete it.
+ * Groups cannot be nested, so all entries returned here are pure entries, no groups.
+ */
+ virtual CryptoConfigEntry* entry( const QString& name ) const = 0;
+ };
+
+ /**
+ * Crypto config for one component (e.g. gpg-agent, dirmngr etc.)
+ */
+ class CryptoConfigComponent {
+
+ public:
+ virtual ~CryptoConfigComponent() {}
+
+ /**
+ * Return the internal name of this component
+ */
+ virtual QString name() const = 0;
+
+ /**
+ * Return the name of the icon for this component
+ */
+ virtual QString iconName() const = 0;
+
+ /**
+ * Return user-visible description of this component
+ */
+ virtual QString description() const = 0;
+
+ /**
+ * Returns the list of groups that are known about.
+ *
+ * @return list of group names. One of them can be "<nogroup>", which is the group where all
+ * "toplevel" options (belonging to no group) are.
+ */
+ virtual QStringList groupList() const = 0;
+
+ /**
+ * @return the configuration object for a given group
+ * The object is owned by CryptoConfigComponent, don't delete it.
+ */
+ virtual CryptoConfigGroup* group( const QString& name ) const = 0;
+
+ };
+
+ /**
+ * Main interface to crypto configuration.
+ */
+ class CryptoConfig {
+
+ public:
+ virtual ~CryptoConfig() {}
+
+ /**
+ * Returns the list of known components (e.g. "gpg-agent", "dirmngr" etc.).
+ * Use @ref component() to retrieve more information about each one.
+ * @return list of component names.
+ **/
+ virtual QStringList componentList() const = 0;
+
+ /**
+ * @return the configuration object for a given component
+ * The object is owned by CryptoConfig, don't delete it.
+ */
+ virtual CryptoConfigComponent* component( const QString& name ) const = 0;
+
+ /**
+ * Convenience method to get hold of a single configuration entry when
+ * its component, group and name are known. This can be used to read
+ * the value and/or to set a value to it.
+ *
+ * @return the configuration object for a single configuration entry, 0 if not found.
+ * The object is owned by CryptoConfig, don't delete it.
+ */
+ CryptoConfigEntry* entry( const QString& componentName, const QString& groupName, const QString& entryName ) const {
+ const Kleo::CryptoConfigComponent* comp = component( componentName );
+ const Kleo::CryptoConfigGroup* group = comp ? comp->group( groupName ) : 0;
+ return group ? group->entry( entryName ) : 0;
+ }
+
+ /**
+ * Write back changes
+ *
+ * @param runtime If this option is set, the changes will take effect at run-time, as
+ * far as this is possible. Otherwise, they will take effect at the next
+ * start of the respective backend programs.
+ */
+ virtual void sync( bool runtime ) = 0;
+
+ /**
+ * Tells the CryptoConfig to discard any cached information, including
+ * all components, groups and entries.
+ * Call this to free some memory when you won't be using the object
+ * for some time.
+ * DON'T call this if you're holding pointers to components, groups or entries.
+ */
+ virtual void clear() = 0;
+ };
+
+}
+#endif /* __cplusplus */
+#endif /* CRYPTOCONFIG_H */
diff --git a/certmanager/lib/kleo/decryptjob.h b/certmanager/lib/kleo/decryptjob.h
new file mode 100644
index 000000000..e882152a0
--- /dev/null
+++ b/certmanager/lib/kleo/decryptjob.h
@@ -0,0 +1,84 @@
+/*
+ decryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_DECRYPTJOB_H__
+#define __KLEO_DECRYPTJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class DecryptionResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous decrypters
+
+ To use a DecryptJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the decryption with a
+ call to start(). This call might fail, in which case the
+ DecryptJob instance will have scheduled it's own destruction with
+ a call to QObject::deleteLater().
+
+ After result() is emitted, the DecryptJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class DecryptJob : public Job {
+ Q_OBJECT
+ protected:
+ DecryptJob( QObject * parent, const char * name );
+ public:
+ ~DecryptJob();
+
+ /**
+ Starts the decryption operation. \a cipherText is the data to
+ decrypt.
+ */
+ virtual GpgME::Error start( const QByteArray & cipherText ) = 0;
+
+ virtual GpgME::DecryptionResult exec( const QByteArray & cipherText,
+ QByteArray & plainText ) = 0;
+
+ signals:
+ void result( const GpgME::DecryptionResult & result, const QByteArray & plainText );
+ };
+
+}
+
+#endif // __KLEO_DECRYPTJOB_H__
diff --git a/certmanager/lib/kleo/decryptverifyjob.h b/certmanager/lib/kleo/decryptverifyjob.h
new file mode 100644
index 000000000..f7cdb81a1
--- /dev/null
+++ b/certmanager/lib/kleo/decryptverifyjob.h
@@ -0,0 +1,90 @@
+/*
+ decryptverifyjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_DECRYPTVERIFYJOB_H__
+#define __KLEO_DECRYPTVERIFYJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+#include <utility>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class DecryptionResult;
+ class VerificationResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous combined decrypters and verifiers
+
+ To use a DecryptVerifyJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the operation with a
+ call to start(). This call might fail, in which case the
+ DecryptVerifyJob instance will have scheduled it's own destruction with
+ a call to QObject::deleteLater().
+
+ After result() is emitted, the DecryptVerifyJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class DecryptVerifyJob : public Job {
+ Q_OBJECT
+ protected:
+ DecryptVerifyJob( QObject * parent, const char * name );
+ public:
+ ~DecryptVerifyJob();
+
+ /**
+ Starts the combined decryption and verification operation.
+ \a cipherText is the data to decrypt and later verify.
+ */
+ virtual GpgME::Error start( const QByteArray & cipherText ) = 0;
+
+ /** Synchronous equivalent of start() */
+ virtual std::pair<GpgME::DecryptionResult,GpgME::VerificationResult>
+ exec( const QByteArray & cipherText, QByteArray & plainText ) = 0;
+
+ signals:
+ void result( const GpgME::DecryptionResult & decryptionresult,
+ const GpgME::VerificationResult & verificationresult,
+ const QByteArray & plainText );
+ };
+
+}
+
+#endif // __KLEO_DECRYPTVERIFYJOB_H__
diff --git a/certmanager/lib/kleo/deletejob.h b/certmanager/lib/kleo/deletejob.h
new file mode 100644
index 000000000..fd70ec513
--- /dev/null
+++ b/certmanager/lib/kleo/deletejob.h
@@ -0,0 +1,78 @@
+/*
+ deletejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_DELETEJOB_H__
+#define __KLEO_DELETEJOB_H__
+
+#include "job.h"
+
+namespace GpgME {
+ class Error;
+ class Key;
+}
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous deleters
+
+ To use a DeleteJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the delete with a call
+ to start(). This call might fail, in which case the DeleteJob
+ instance will have scheduled it's own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the DeleteJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class DeleteJob : public Job {
+ Q_OBJECT
+ protected:
+ DeleteJob( QObject * parent, const char * name );
+ public:
+ ~DeleteJob();
+
+ /**
+ Starts the delete operation. \a key represents the key to
+ delete, \a allowSecretKeyDeletion specifies if a key may also
+ be deleted if the secret key part is available, too.
+ */
+ virtual GpgME::Error start( const GpgME::Key & key, bool allowSecretKeyDeletion=false ) = 0;
+
+ signals:
+ void result( const GpgME::Error & result );
+ };
+
+}
+
+#endif // __KLEO_DELETEJOB_H__
diff --git a/certmanager/lib/kleo/dn.cpp b/certmanager/lib/kleo/dn.cpp
new file mode 100644
index 000000000..9ba2209fb
--- /dev/null
+++ b/certmanager/lib/kleo/dn.cpp
@@ -0,0 +1,538 @@
+/*
+ dn.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ DN parsing:
+ Copyright (c) 2002 g10 Code GmbH
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "dn.h"
+
+#include "oidmap.h"
+#include "ui/dnattributeorderconfigwidget.h"
+
+#include <kapplication.h>
+#include <kconfig.h>
+#include <klocale.h>
+
+#include <qstringlist.h>
+#include <qvaluevector.h>
+
+#include <iostream>
+#include <iterator>
+#include <algorithm>
+#include <map>
+
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+
+struct Kleo::DN::Private {
+ Private() : mRefCount( 0 ) {}
+ Private( const Private & other )
+ : attributes( other.attributes ),
+ reorderedAttributes( other.reorderedAttributes ),
+ mRefCount( 0 )
+ {
+
+ }
+
+ int ref() {
+ return ++mRefCount;
+ }
+
+ int unref() {
+ if ( --mRefCount <= 0 ) {
+ delete this;
+ return 0;
+ } else
+ return mRefCount;
+ }
+
+ int refCount() const { return mRefCount; }
+
+ DN::Attribute::List attributes;
+ DN::Attribute::List reorderedAttributes;
+private:
+ int mRefCount;
+};
+
+namespace {
+ struct DnPair {
+ char * key;
+ char * value;
+ };
+}
+
+// copied from CryptPlug and adapted to work on DN::Attribute::List:
+
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+static char *
+trim_trailing_spaces( char *string )
+{
+ char *p, *mark;
+
+ for( mark = NULL, p = string; *p; p++ ) {
+ if( isspace( *p ) ) {
+ if( !mark )
+ mark = p;
+ }
+ else
+ mark = NULL;
+ }
+ if( mark )
+ *mark = '\0' ;
+
+ return string ;
+}
+
+/* Parse a DN and return an array-ized one. This is not a validating
+ parser and it does not support any old-stylish syntax; gpgme is
+ expected to return only rfc2253 compatible strings. */
+static const unsigned char *
+parse_dn_part (DnPair *array, const unsigned char *string)
+{
+ const unsigned char *s, *s1;
+ size_t n;
+ char *p;
+
+ /* parse attributeType */
+ for (s = string+1; *s && *s != '='; s++)
+ ;
+ if (!*s)
+ return NULL; /* error */
+ n = s - string;
+ if (!n)
+ return NULL; /* empty key */
+ p = (char*)malloc (n+1);
+
+
+ memcpy (p, string, n);
+ p[n] = 0;
+ trim_trailing_spaces ((char*)p);
+ // map OIDs to their names:
+ for ( unsigned int i = 0 ; i < numOidMaps ; ++i )
+ if ( !strcasecmp ((char*)p, oidmap[i].oid) ) {
+ free( p );
+ p = strdup( oidmap[i].name );
+ break;
+ }
+ array->key = p;
+ string = s + 1;
+
+ if (*string == '#')
+ { /* hexstring */
+ string++;
+ for (s=string; hexdigitp (s); s++)
+ s++;
+ n = s - string;
+ if (!n || (n & 1))
+ return NULL; /* empty or odd number of digits */
+ n /= 2;
+ array->value = p = (char*)malloc (n+1);
+
+
+ for (s1=string; n; s1 += 2, n--)
+ *p++ = xtoi_2 (s1);
+ *p = 0;
+ }
+ else
+ { /* regular v3 quoted string */
+ for (n=0, s=string; *s; s++)
+ {
+ if (*s == '\\')
+ { /* pair */
+ s++;
+ if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';'
+ || *s == '\\' || *s == '\"' || *s == ' ')
+ n++;
+ else if (hexdigitp (s) && hexdigitp (s+1))
+ {
+ s++;
+ n++;
+ }
+ else
+ return NULL; /* invalid escape sequence */
+ }
+ else if (*s == '\"')
+ return NULL; /* invalid encoding */
+ else if (*s == ',' || *s == '=' || *s == '+'
+ || *s == '<' || *s == '>' || *s == '#' || *s == ';' )
+ break;
+ else
+ n++;
+ }
+
+ array->value = p = (char*)malloc (n+1);
+
+
+ for (s=string; n; s++, n--)
+ {
+ if (*s == '\\')
+ {
+ s++;
+ if (hexdigitp (s))
+ {
+ *p++ = xtoi_2 (s);
+ s++;
+ }
+ else
+ *p++ = *s;
+ }
+ else
+ *p++ = *s;
+ }
+ *p = 0;
+ }
+ return s;
+}
+
+
+/* Parse a DN and return an array-ized one. This is not a validating
+ parser and it does not support any old-stylish syntax; gpgme is
+ expected to return only rfc2253 compatible strings. */
+static Kleo::DN::Attribute::List
+parse_dn( const unsigned char * string ) {
+ if ( !string )
+ return QValueVector<Kleo::DN::Attribute>();
+
+ QValueVector<Kleo::DN::Attribute> result;
+ while (*string)
+ {
+ while (*string == ' ')
+ string++;
+ if (!*string)
+ break; /* ready */
+
+ DnPair pair = { 0, 0 };
+ string = parse_dn_part (&pair, string);
+ if (!string)
+ goto failure;
+ if ( pair.key && pair.value )
+ result.push_back( Kleo::DN::Attribute( QString::fromUtf8( pair.key ),
+ QString::fromUtf8( pair.value ) ) );
+ free( pair.key );
+ free( pair.value );
+
+ while (*string == ' ')
+ string++;
+ if (*string && *string != ',' && *string != ';' && *string != '+')
+ goto failure; /* invalid delimiter */
+ if (*string)
+ string++;
+ }
+ return result;
+
+failure:
+ return QValueVector<Kleo::DN::Attribute>();
+}
+
+static QValueVector<Kleo::DN::Attribute>
+parse_dn( const QString & dn ) {
+ return parse_dn( (const unsigned char*)dn.utf8().data() );
+}
+
+static QString dn_escape( const QString & s ) {
+ QString result;
+ for ( unsigned int i = 0, end = s.length() ; i != end ; ++i ) {
+ const QChar ch = s[i];
+ switch ( ch.unicode() ) {
+ case ',':
+ case '+':
+ case '"':
+ case '\\':
+ case '<':
+ case '>':
+ case ';':
+ result += '\\';
+ // fall through
+ default:
+ result += ch;
+ }
+ }
+ return result;
+}
+
+static QString
+serialise( const QValueVector<Kleo::DN::Attribute> & dn ) {
+ QStringList result;
+ for ( QValueVector<Kleo::DN::Attribute>::const_iterator it = dn.begin() ; it != dn.end() ; ++it )
+ if ( !(*it).name().isEmpty() && !(*it).value().isEmpty() )
+ result.push_back( (*it).name().stripWhiteSpace() + '=' + dn_escape( (*it).value().stripWhiteSpace() ) );
+ return result.join( "," );
+}
+
+static Kleo::DN::Attribute::List
+reorder_dn( const Kleo::DN::Attribute::List & dn ) {
+ const QStringList & attrOrder = Kleo::DNAttributeMapper::instance()->attributeOrder();
+
+ Kleo::DN::Attribute::List unknownEntries;
+ Kleo::DN::Attribute::List result;
+ unknownEntries.reserve( dn.size() );
+ result.reserve( dn.size() );
+
+ // find all unknown entries in their order of appearance
+ for ( Kleo::DN::const_iterator it = dn.begin(); it != dn.end(); ++it )
+ if ( attrOrder.find( (*it).name() ) == attrOrder.end() )
+ unknownEntries.push_back( *it );
+
+ // process the known attrs in the desired order
+ for ( QStringList::const_iterator oit = attrOrder.begin() ; oit != attrOrder.end() ; ++oit )
+ if ( *oit == "_X_" ) {
+ // insert the unknown attrs
+ std::copy( unknownEntries.begin(), unknownEntries.end(),
+ std::back_inserter( result ) );
+ unknownEntries.clear(); // don't produce dup's
+ } else {
+ for ( Kleo::DN::const_iterator dnit = dn.begin() ; dnit != dn.end() ; ++dnit )
+ if ( (*dnit).name() == *oit )
+ result.push_back( *dnit );
+ }
+
+ return result;
+}
+
+//
+//
+// class DN
+//
+//
+
+Kleo::DN::DN() {
+ d = new Private();
+ d->ref();
+}
+
+Kleo::DN::DN( const QString & dn ) {
+ d = new Private();
+ d->ref();
+ d->attributes = parse_dn( dn );
+}
+
+Kleo::DN::DN( const char * utf8DN ) {
+ d = new Private();
+ d->ref();
+ if ( utf8DN )
+ d->attributes = parse_dn( (const unsigned char*)utf8DN );
+}
+
+Kleo::DN::DN( const DN & other )
+ : d( other.d )
+{
+ if ( d ) d->ref();
+}
+
+Kleo::DN::~DN() {
+ if ( d ) d->unref();
+}
+
+const Kleo::DN & Kleo::DN::operator=( const DN & that ) {
+ if ( this->d == that.d )
+ return *this;
+
+ if ( that.d )
+ that.d->ref();
+ if ( this->d )
+ this->d->unref();
+
+ this->d = that.d;
+
+ return *this;
+}
+
+QString Kleo::DN::prettyDN() const {
+ if ( !d )
+ return QString::null;
+ if ( d->reorderedAttributes.empty() )
+ d->reorderedAttributes = reorder_dn( d->attributes );
+ return serialise( d->reorderedAttributes );
+}
+
+QString Kleo::DN::dn() const {
+ return d ? serialise( d->attributes ) : QString::null ;
+}
+
+// static
+QString Kleo::DN::escape( const QString & value ) {
+ return dn_escape( value );
+}
+
+void Kleo::DN::detach() {
+ if ( !d ) {
+ d = new Kleo::DN::Private();
+ d->ref();
+ } else if ( d->refCount() > 1 ) {
+ Kleo::DN::Private * d_save = d;
+ d = new Kleo::DN::Private( *d );
+ d->ref();
+ d_save->unref();
+ }
+}
+
+void Kleo::DN::append( const Attribute & attr ) {
+ detach();
+ d->attributes.push_back( attr );
+ d->reorderedAttributes.clear();
+}
+
+QString Kleo::DN::operator[]( const QString & attr ) const {
+ if ( !d )
+ return QString::null;
+ const QString attrUpper = attr.upper();
+ for ( QValueVector<Attribute>::const_iterator it = d->attributes.begin() ;
+ it != d->attributes.end() ; ++it )
+ if ( (*it).name() == attrUpper )
+ return (*it).value();
+ return QString::null;
+}
+
+static QValueVector<Kleo::DN::Attribute> empty;
+
+Kleo::DN::const_iterator Kleo::DN::begin() const {
+ return d ? d->attributes.begin() : empty.begin() ;
+}
+
+Kleo::DN::const_iterator Kleo::DN::end() const {
+ return d ? d->attributes.end() : empty.end() ;
+}
+
+
+/////////////////////
+
+namespace {
+ struct ltstr {
+ bool operator()( const char * s1, const char * s2 ) const {
+ return qstrcmp( s1, s2 ) < 0 ;
+ }
+ };
+}
+
+static const char * defaultOrder[] = {
+ "CN", "L", "_X_", "OU", "O", "C"
+};
+
+std::pair<const char*,const char*> attributeLabels[] = {
+#define MAKE_PAIR(x,y) std::pair<const char*,const char*>( x, y )
+ MAKE_PAIR( "CN", I18N_NOOP("Common name") ),
+ MAKE_PAIR( "SN", I18N_NOOP("Surname") ),
+ MAKE_PAIR( "GN", I18N_NOOP("Given name") ),
+ MAKE_PAIR( "L", I18N_NOOP("Location") ),
+ MAKE_PAIR( "T", I18N_NOOP("Title") ),
+ MAKE_PAIR( "OU", I18N_NOOP("Organizational unit") ),
+ MAKE_PAIR( "O", I18N_NOOP("Organization") ),
+ MAKE_PAIR( "PC", I18N_NOOP("Postal code") ),
+ MAKE_PAIR( "C", I18N_NOOP("Country code") ),
+ MAKE_PAIR( "SP", I18N_NOOP("State or province") ),
+ MAKE_PAIR( "DC", I18N_NOOP("Domain component") ),
+ MAKE_PAIR( "BC", I18N_NOOP("Business category") ),
+ MAKE_PAIR( "EMAIL", I18N_NOOP("Email address") ),
+ MAKE_PAIR( "MAIL", I18N_NOOP("Mail address") ),
+ MAKE_PAIR( "MOBILE", I18N_NOOP("Mobile phone number") ),
+ MAKE_PAIR( "TEL", I18N_NOOP("Telephone number") ),
+ MAKE_PAIR( "FAX", I18N_NOOP("Fax number") ),
+ MAKE_PAIR( "STREET", I18N_NOOP("Street address") ),
+ MAKE_PAIR( "UID", I18N_NOOP("Unique ID") )
+#undef MAKE_PAIR
+};
+static const unsigned int numAttributeLabels = sizeof attributeLabels / sizeof *attributeLabels ;
+
+class Kleo::DNAttributeMapper::Private {
+public:
+ Private();
+ std::map<const char*,const char*,ltstr> map;
+ QStringList attributeOrder;
+};
+
+Kleo::DNAttributeMapper::Private::Private()
+ : map( attributeLabels, attributeLabels + numAttributeLabels ) {}
+
+Kleo::DNAttributeMapper::DNAttributeMapper() {
+ d = new Private();
+ const KConfigGroup config( kapp->config(), "DN" );
+ d->attributeOrder = config.readListEntry( "AttributeOrder" );
+ if ( d->attributeOrder.empty() )
+ std::copy( defaultOrder, defaultOrder + sizeof defaultOrder / sizeof *defaultOrder,
+ std::back_inserter( d->attributeOrder ) );
+ mSelf = this;
+}
+
+Kleo::DNAttributeMapper::~DNAttributeMapper() {
+ mSelf = 0;
+ delete d; d = 0;
+}
+
+Kleo::DNAttributeMapper * Kleo::DNAttributeMapper::mSelf = 0;
+
+const Kleo::DNAttributeMapper * Kleo::DNAttributeMapper::instance() {
+ if ( !mSelf )
+ (void)new DNAttributeMapper();
+ return mSelf;
+}
+
+QString Kleo::DNAttributeMapper::name2label( const QString & s ) const {
+ const std::map<const char*,const char*,ltstr>::const_iterator it
+ = d->map.find( s.stripWhiteSpace().upper().latin1() );
+ if ( it == d->map.end() )
+ return QString::null;
+ return i18n( it->second );
+}
+
+QStringList Kleo::DNAttributeMapper::names() const {
+ QStringList result;
+ for ( std::map<const char*,const char*,ltstr>::const_iterator it = d->map.begin() ; it != d->map.end() ; ++it )
+ result.push_back( it->first );
+ return result;
+}
+
+const QStringList & Kleo::DNAttributeMapper::attributeOrder() const {
+ return d->attributeOrder;
+}
+
+void Kleo::DNAttributeMapper::setAttributeOrder( const QStringList & order ) {
+ d->attributeOrder = order;
+ if ( order.empty() )
+ std::copy( defaultOrder, defaultOrder + sizeof defaultOrder / sizeof *defaultOrder,
+ std::back_inserter( d->attributeOrder ) );
+ KConfigGroup config( kapp->config(), "DN" );
+ config.writeEntry( "AttributeOrder", order );
+}
+
+Kleo::DNAttributeOrderConfigWidget * Kleo::DNAttributeMapper::configWidget( QWidget * parent, const char * name ) const {
+ return new DNAttributeOrderConfigWidget( mSelf, parent, name );
+}
diff --git a/certmanager/lib/kleo/dn.h b/certmanager/lib/kleo/dn.h
new file mode 100644
index 000000000..12bf9dc03
--- /dev/null
+++ b/certmanager/lib/kleo/dn.h
@@ -0,0 +1,142 @@
+/*
+ dn.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_DN_H__
+#define __KLEO_DN_H__
+
+#include <qstring.h>
+#include <qvaluevector.h>
+#include <kdepimmacros.h>
+
+class QStringList;
+class QWidget;
+
+namespace Kleo {
+ class DNAttributeOrderConfigWidget;
+}
+
+namespace Kleo {
+
+ /**
+ @short DN Attribute mapper
+ */
+ class KDE_EXPORT DNAttributeMapper {
+ DNAttributeMapper();
+ ~DNAttributeMapper();
+ public:
+ static const DNAttributeMapper * instance();
+
+ QString name2label( const QString & s ) const;
+ QStringList names() const;
+
+ const QStringList & attributeOrder() const;
+
+ void setAttributeOrder( const QStringList & order );
+
+ DNAttributeOrderConfigWidget * configWidget( QWidget * parent=0, const char * name=0 ) const;
+
+ private:
+ class Private;
+ Private * d;
+ static DNAttributeMapper * mSelf;
+ };
+
+ /**
+ @short DN parser and reorderer
+ */
+ class KDE_EXPORT DN {
+ public:
+ class Attribute;
+ typedef QValueVector<Attribute> AttributeList;
+ typedef AttributeList::const_iterator const_iterator;
+
+ DN();
+ DN( const QString & dn );
+ DN( const char * utf8DN );
+ DN( const DN & other );
+ ~DN();
+
+ const DN & operator=( const DN & other );
+
+ /** @return the value in rfc-2253-escaped form */
+ static QString escape( const QString & value );
+
+ /** @return the DN in a reordered form, according to the settings in
+ the [DN] group of the application's config file */
+ QString prettyDN() const;
+ /** @return the DN in the original form */
+ QString dn() const;
+
+ QString operator[]( const QString & attr ) const;
+
+ void append( const Attribute & attr );
+
+ const_iterator begin() const;
+ const_iterator end() const;
+
+ private:
+ void detach();
+ private:
+ class Private;
+ Private * d;
+ };
+
+ class KDE_EXPORT DN::Attribute {
+ public:
+ typedef DN::AttributeList List;
+
+ Attribute( const QString & name=QString::null, const QString & value=QString::null )
+ : mName( name.upper() ), mValue( value ) {}
+ Attribute( const Attribute & other )
+ : mName( other.name() ), mValue( other.value() ) {}
+
+ const Attribute & operator=( const Attribute & other ) {
+ if ( this != &other ) {
+ mName = other.name();
+ mValue = other.value();
+ }
+ return *this;
+ }
+
+ const QString & name() const { return mName; }
+ const QString & value() const { return mValue; }
+
+ void setValue( const QString & value ) { mValue = value; }
+
+ private:
+ QString mName;
+ QString mValue;
+ };
+
+}
+
+#endif // __KLEO_DN_H__
diff --git a/certmanager/lib/kleo/downloadjob.h b/certmanager/lib/kleo/downloadjob.h
new file mode 100644
index 000000000..006ab8ebd
--- /dev/null
+++ b/certmanager/lib/kleo/downloadjob.h
@@ -0,0 +1,83 @@
+/*
+ downloadjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_DOWNLOADJOB_H__
+#define __KLEO_DOWNLOADJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+}
+
+class QStringList;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous downloaders
+
+ To use a DownloadJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the download with a call
+ to start(). This call might fail, in which case the DownloadJob
+ instance will have scheduled it's own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the DownloadJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class DownloadJob : public Job {
+ Q_OBJECT
+ protected:
+ DownloadJob( QObject * parent, const char * name );
+ public:
+ ~DownloadJob();
+
+ /**
+ Starts the download operation. \a fingerprints is a list of
+ fingerprints used to specify the list of keys downloaded. Empty
+ patterns are ignored. If \a fingerprints is empty, contains
+ only empty strings or anything other than fingerprints, the
+ result is undefined.
+ */
+ virtual GpgME::Error start( const QStringList & fingerprints ) = 0;
+
+ signals:
+ void result( const GpgME::Error & result, const QByteArray & keyData );
+ };
+
+}
+
+#endif // __KLEO_DOWNLOADJOB_H__
diff --git a/certmanager/lib/kleo/encryptjob.h b/certmanager/lib/kleo/encryptjob.h
new file mode 100644
index 000000000..02144656f
--- /dev/null
+++ b/certmanager/lib/kleo/encryptjob.h
@@ -0,0 +1,92 @@
+/*
+ encryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_ENCRYPTJOB_H__
+#define __KLEO_ENCRYPTJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+#include <vector>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class EncryptionResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous encrypters
+
+ To use a EncryptJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the encryption with a
+ call to start(). This call might fail, in which case the
+ EncryptJob instance will have scheduled it's own destruction with
+ a call to QObject::deleteLater().
+
+ After result() is emitted, the EncryptJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class EncryptJob : public Job {
+ Q_OBJECT
+ protected:
+ EncryptJob( QObject * parent, const char * name );
+ public:
+ ~EncryptJob();
+
+ /**
+ Starts the encryption operation. \a recipients is the a list of
+ keys to encrypt \a plainText to. Empty (null) keys are ignored.
+
+ If \a alwaysTrust is true, validity checking for the keys will
+ not be performed, but full validity assumed for all keys
+ without further checks.
+ */
+ virtual GpgME::Error start( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText, bool alwaysTrust=false ) = 0;
+
+ virtual GpgME::EncryptionResult exec( const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText,
+ bool alwaysTrust, QByteArray & cipherText ) = 0;
+
+ signals:
+ void result( const GpgME::EncryptionResult & result, const QByteArray & cipherText );
+ };
+
+}
+
+#endif // __KLEO_ENCRYPTJOB_H__
diff --git a/certmanager/lib/kleo/enum.cpp b/certmanager/lib/kleo/enum.cpp
new file mode 100644
index 000000000..efa4cfaa3
--- /dev/null
+++ b/certmanager/lib/kleo/enum.cpp
@@ -0,0 +1,206 @@
+/*
+ kleo/enum.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "enum.h"
+
+#include <klocale.h>
+
+#include <qstring.h>
+#include <qstringlist.h>
+
+static const struct {
+ Kleo::CryptoMessageFormat format;
+ const char * displayName;
+ const char * configName;
+} cryptoMessageFormats[] = {
+ { Kleo::InlineOpenPGPFormat,
+ I18N_NOOP("Inline OpenPGP (deprecated)"),
+ "inline openpgp" },
+ { Kleo::OpenPGPMIMEFormat,
+ I18N_NOOP("OpenPGP/MIME"),
+ "openpgp/mime" },
+ { Kleo::SMIMEFormat,
+ I18N_NOOP("S/MIME"),
+ "s/mime" },
+ { Kleo::SMIMEOpaqueFormat,
+ I18N_NOOP("S/MIME Opaque"),
+ "s/mime opaque" },
+};
+static const unsigned int numCryptoMessageFormats
+ = sizeof cryptoMessageFormats / sizeof *cryptoMessageFormats ;
+
+const char * Kleo::cryptoMessageFormatToString( Kleo::CryptoMessageFormat f ) {
+ if ( f == AutoFormat )
+ return "auto";
+ for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i )
+ if ( f == cryptoMessageFormats[i].format )
+ return cryptoMessageFormats[i].configName;
+ return 0;
+}
+
+QStringList Kleo::cryptoMessageFormatsToStringList( unsigned int f ) {
+ QStringList result;
+ for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i )
+ if ( f & cryptoMessageFormats[i].format )
+ result.push_back( cryptoMessageFormats[i].configName );
+ return result;
+}
+
+QString Kleo::cryptoMessageFormatToLabel( Kleo::CryptoMessageFormat f ) {
+ if ( f == AutoFormat )
+ return i18n("Any");
+ for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i )
+ if ( f == cryptoMessageFormats[i].format )
+ return i18n( cryptoMessageFormats[i].displayName );
+ return QString::null;
+}
+
+Kleo::CryptoMessageFormat Kleo::stringToCryptoMessageFormat( const QString & s ) {
+ const QString t = s.lower();
+ for ( unsigned int i = 0 ; i < numCryptoMessageFormats ; ++i )
+ if ( t == cryptoMessageFormats[i].configName )
+ return cryptoMessageFormats[i].format;
+ return AutoFormat;
+}
+
+unsigned int Kleo::stringListToCryptoMessageFormats( const QStringList & sl ) {
+ unsigned int result = 0;
+ for ( QStringList::const_iterator it = sl.begin() ; it != sl.end() ; ++it )
+ result |= stringToCryptoMessageFormat( *it );
+ return result;
+}
+
+// For the config values used below, see also kaddressbook/editors/cryptowidget.cpp
+
+const char* Kleo::encryptionPreferenceToString( EncryptionPreference pref )
+{
+ switch( pref ) {
+ case UnknownPreference:
+ return 0;
+ case NeverEncrypt:
+ return "never";
+ case AlwaysEncrypt:
+ return "always";
+ case AlwaysEncryptIfPossible:
+ return "alwaysIfPossible";
+ case AlwaysAskForEncryption:
+ return "askAlways";
+ case AskWheneverPossible:
+ return "askWhenPossible";
+ }
+ return 0; // keep the compiler happy
+}
+
+Kleo::EncryptionPreference Kleo::stringToEncryptionPreference( const QString& str )
+{
+ if ( str == "never" )
+ return NeverEncrypt;
+ if ( str == "always" )
+ return AlwaysEncrypt;
+ if ( str == "alwaysIfPossible" )
+ return AlwaysEncryptIfPossible;
+ if ( str == "askAlways" )
+ return AlwaysAskForEncryption;
+ if ( str == "askWhenPossible" )
+ return AskWheneverPossible;
+ return UnknownPreference;
+}
+
+QString Kleo::encryptionPreferenceToLabel( EncryptionPreference pref )
+{
+ switch( pref ) {
+ case NeverEncrypt:
+ return i18n( "Never Encrypt" );
+ case AlwaysEncrypt:
+ return i18n( "Always Encrypt" );
+ case AlwaysEncryptIfPossible:
+ return i18n( "Always Encrypt If Possible" );
+ case AlwaysAskForEncryption:
+ return i18n( "Ask" );
+ case AskWheneverPossible:
+ return i18n( "Ask Whenever Possible" );
+ default:
+ return i18n( "no specific preference", "<none>" );
+ }
+}
+
+const char* Kleo::signingPreferenceToString( SigningPreference pref )
+{
+ switch( pref ) {
+ case UnknownSigningPreference:
+ return 0;
+ case NeverSign:
+ return "never";
+ case AlwaysSign:
+ return "always";
+ case AlwaysSignIfPossible:
+ return "alwaysIfPossible";
+ case AlwaysAskForSigning:
+ return "askAlways";
+ case AskSigningWheneverPossible:
+ return "askWhenPossible";
+ }
+ return 0; // keep the compiler happy
+}
+
+Kleo::SigningPreference Kleo::stringToSigningPreference( const QString& str )
+{
+ if ( str == "never" )
+ return NeverSign;
+ if ( str == "always" )
+ return AlwaysSign;
+ if ( str == "alwaysIfPossible" )
+ return AlwaysSignIfPossible;
+ if ( str == "askAlways" )
+ return AlwaysAskForSigning;
+ if ( str == "askWhenPossible" )
+ return AskSigningWheneverPossible;
+ return UnknownSigningPreference;
+}
+
+QString Kleo::signingPreferenceToLabel( SigningPreference pref )
+{
+ switch( pref ) {
+ case NeverSign:
+ return i18n( "Never Sign" );
+ case AlwaysSign:
+ return i18n( "Always Sign" );
+ case AlwaysSignIfPossible:
+ return i18n( "Always Sign If Possible" );
+ case AlwaysAskForSigning:
+ return i18n( "Ask" );
+ case AskSigningWheneverPossible:
+ return i18n( "Ask Whenever Possible" );
+ default:
+ return i18n( "no specific preference", "<none>" );
+ }
+}
diff --git a/certmanager/lib/kleo/enum.h b/certmanager/lib/kleo/enum.h
new file mode 100644
index 000000000..29f8e2a66
--- /dev/null
+++ b/certmanager/lib/kleo/enum.h
@@ -0,0 +1,93 @@
+/*
+ kleo/enum.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_ENUM_H__
+#define __KLEO_ENUM_H__
+
+#include <kdepimmacros.h>
+
+class QString;
+class QStringList;
+
+namespace Kleo {
+
+ enum CryptoMessageFormat {
+ InlineOpenPGPFormat = 1,
+ OpenPGPMIMEFormat = 2,
+ SMIMEFormat = 4,
+ SMIMEOpaqueFormat = 8,
+ AnyOpenPGP = InlineOpenPGPFormat|OpenPGPMIMEFormat,
+ AnySMIME = SMIMEOpaqueFormat|SMIMEFormat,
+ AutoFormat = AnyOpenPGP|AnySMIME
+ };
+
+ KDE_EXPORT QString cryptoMessageFormatToLabel( CryptoMessageFormat f );
+
+ KDE_EXPORT const char * cryptoMessageFormatToString( CryptoMessageFormat f );
+ KDE_EXPORT QStringList cryptoMessageFormatsToStringList( unsigned int f );
+ KDE_EXPORT CryptoMessageFormat stringToCryptoMessageFormat( const QString & s );
+ KDE_EXPORT unsigned int stringListToCryptoMessageFormats( const QStringList & sl );
+
+ enum Action {
+ Conflict, DoIt, DontDoIt, Ask, AskOpportunistic, Impossible
+ };
+
+ enum EncryptionPreference {
+ UnknownPreference = 0,
+ NeverEncrypt = 1,
+ AlwaysEncrypt = 2,
+ AlwaysEncryptIfPossible = 3,
+ AlwaysAskForEncryption = 4,
+ AskWheneverPossible = 5,
+ MaxEncryptionPreference = AskWheneverPossible
+ };
+
+ KDE_EXPORT QString encryptionPreferenceToLabel( EncryptionPreference pref );
+ KDE_EXPORT const char* encryptionPreferenceToString( EncryptionPreference pref );
+ KDE_EXPORT EncryptionPreference stringToEncryptionPreference( const QString& str );
+
+ enum SigningPreference {
+ UnknownSigningPreference = 0,
+ NeverSign = 1,
+ AlwaysSign = 2,
+ AlwaysSignIfPossible = 3,
+ AlwaysAskForSigning = 4,
+ AskSigningWheneverPossible = 5,
+ MaxSigningPreference = AskSigningWheneverPossible
+ };
+
+ KDE_EXPORT QString signingPreferenceToLabel( SigningPreference pref ) KDE_EXPORT;
+ KDE_EXPORT const char* signingPreferenceToString( SigningPreference pref ) KDE_EXPORT;
+ KDE_EXPORT SigningPreference stringToSigningPreference( const QString& str );
+}
+
+#endif // __KLEO_CRYPTOBACKEND_H__
diff --git a/certmanager/lib/kleo/exportjob.h b/certmanager/lib/kleo/exportjob.h
new file mode 100644
index 000000000..d6a0db185
--- /dev/null
+++ b/certmanager/lib/kleo/exportjob.h
@@ -0,0 +1,82 @@
+/*
+ exportjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_EXPORTJOB_H__
+#define __KLEO_EXPORTJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+}
+
+class QStringList;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous exporters
+
+ To use a ExportJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the export with a call
+ to start(). This call might fail, in which case the ExportJob
+ instance will have scheduled it's own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the ExportJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class ExportJob : public Job {
+ Q_OBJECT
+ protected:
+ ExportJob( QObject * parent, const char * name );
+ public:
+ ~ExportJob();
+
+ /**
+ Starts the export operation. \a patterns is a list of patterns
+ used to restrict the list of keys exported. Empty patterns are
+ ignored. If \a patterns is empty or contains only empty
+ strings, all available keys are exported.
+ */
+ virtual GpgME::Error start( const QStringList & patterns ) = 0;
+
+ signals:
+ void result( const GpgME::Error & result, const QByteArray & keyData );
+ };
+
+}
+
+#endif // __KLEO_EXPORTJOB_H__
diff --git a/certmanager/lib/kleo/hierarchicalkeylistjob.cpp b/certmanager/lib/kleo/hierarchicalkeylistjob.cpp
new file mode 100644
index 000000000..a7a66b2fe
--- /dev/null
+++ b/certmanager/lib/kleo/hierarchicalkeylistjob.cpp
@@ -0,0 +1,158 @@
+/*
+ hierarchicalkeylistjob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "hierarchicalkeylistjob.h"
+#include "cryptobackend.h"
+#include "keylistjob.h"
+
+#include <klocale.h>
+
+#include <qstringlist.h>
+#include <qtl.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <gpg-error.h>
+
+#include <iterator>
+#include <algorithm>
+
+#include <assert.h>
+
+Kleo::HierarchicalKeyListJob::HierarchicalKeyListJob( const CryptoBackend::Protocol * protocol,
+ bool remote, bool includeSigs, bool validating )
+ : KeyListJob( 0, "Kleo::HierarchicalKeyListJob" ),
+ mProtocol( protocol ),
+ mRemote( remote ),
+ mIncludeSigs( includeSigs ),
+ mValidating( validating ),
+ mTruncated( false ),
+ mIntermediateResult(),
+ mJob( 0 )
+{
+ assert( protocol );
+}
+
+Kleo::HierarchicalKeyListJob::~HierarchicalKeyListJob() {
+
+}
+
+GpgME::Error Kleo::HierarchicalKeyListJob::start( const QStringList & patterns, bool secretOnly ) {
+ if ( secretOnly || patterns.empty() )
+ return gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION );
+ qCopy( patterns.begin(), patterns.end(),
+ std::inserter( mNextSet, mNextSet.begin() ) );
+ const GpgME::Error err = startAJob();
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+GpgME::KeyListResult Kleo::HierarchicalKeyListJob::exec( const QStringList &, bool,
+ std::vector<GpgME::Key> & keys ) {
+ keys.clear();
+ return GpgME::KeyListResult( gpg_err_make( GPG_ERR_SOURCE_GPGME, GPG_ERR_UNSUPPORTED_OPERATION ) );
+}
+
+void Kleo::HierarchicalKeyListJob::slotNextKey( const GpgME::Key & key ) {
+ if ( const char * chain_id = key.chainID() )
+ mNextSet.insert( chain_id );
+ if ( const char * fpr = key.primaryFingerprint() )
+ if ( mSentSet.find( fpr ) == mSentSet.end() ) {
+ mSentSet.insert( fpr );
+ emit nextKey( key );
+ }
+}
+
+void Kleo::HierarchicalKeyListJob::slotCancel() {
+ if ( mJob ) mJob->slotCancel();
+ mNextSet.clear();
+}
+
+void Kleo::HierarchicalKeyListJob::slotResult( const GpgME::KeyListResult & res ) {
+ mJob = 0;
+ mIntermediateResult.mergeWith( res );
+ std::set<QString> tmp;
+ std::set_difference( mNextSet.begin(), mNextSet.end(),
+ mScheduledSet.begin(), mScheduledSet.end(),
+ std::inserter( tmp, tmp.begin() ) );
+ mNextSet.clear();
+ std::set_difference( tmp.begin(), tmp.end(),
+ mSentSet.begin(), mSentSet.end(),
+ std::inserter( mNextSet, mNextSet.begin() ) );
+ if ( mIntermediateResult.error() || mNextSet.empty() ) {
+ emit done();
+ emit result( mIntermediateResult );
+ deleteLater();
+ return;
+ }
+ if ( const GpgME::Error error = startAJob() ) { // error starting the job for next keys
+ mIntermediateResult.mergeWith( GpgME::KeyListResult( error ) );
+ emit done();
+ emit result( mIntermediateResult );
+ deleteLater();
+ return;
+ }
+#if 0 // FIXME
+ const int current = mIt - mKeys.begin();
+ const int total = mKeys.size();
+ emit progress( i18n("progress info: \"%1 of %2\"","%1/%2").arg( current ).arg( total ), current, total );
+#endif
+}
+
+GpgME::Error Kleo::HierarchicalKeyListJob::startAJob() {
+ if ( mNextSet.empty() )
+ return 0;
+ mJob = mProtocol->keyListJob( mRemote, mIncludeSigs, mValidating );
+ assert( mJob ); // FIXME: we need a way to generate errors ourselves,
+ // but I don't like the dependency on gpg-error :/
+
+ connect( mJob, SIGNAL(nextKey(const GpgME::Key&)), SLOT(slotNextKey(const GpgME::Key&)) );
+ connect( mJob, SIGNAL(result(const GpgME::KeyListResult&)), SLOT(slotResult(const GpgME::KeyListResult&)) );
+
+ QStringList patterns;
+ for ( std::set<QString>::const_iterator it = mNextSet.begin() ; it != mNextSet.end() ; ++it )
+ patterns.push_back( *it );
+
+ mScheduledSet.insert( mNextSet.begin(), mNextSet.end() );
+ mNextSet.clear();
+
+ return mJob->start( patterns, false );
+}
+
+#include "hierarchicalkeylistjob.moc"
diff --git a/certmanager/lib/kleo/hierarchicalkeylistjob.h b/certmanager/lib/kleo/hierarchicalkeylistjob.h
new file mode 100644
index 000000000..a91ff6dc0
--- /dev/null
+++ b/certmanager/lib/kleo/hierarchicalkeylistjob.h
@@ -0,0 +1,116 @@
+/*
+ hierarchicalkeylistjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_HIERARCHICALKEYLISTJOB_H__
+#define __KLEO_HIERARCHICALKEYLISTJOB_H__
+
+#include <kleo/keylistjob.h>
+#include <kleo/cryptobackend.h>
+#include <kdepimmacros.h>
+
+#include <gpgmepp/keylistresult.h>
+
+#include <qcstring.h>
+#include <qguardedptr.h>
+
+#include <set>
+
+namespace GpgME {
+ class Error;
+ class Key;
+}
+
+namespace Kleo {
+ class KeyListJob;
+}
+
+namespace Kleo {
+
+ /**
+ @short A convenience job that additionally fetches all available issuers.
+
+ To use a HierarchicalKeyListJob, pass it a CryptoBackend
+ implementation, connect the progress() and result() signals to
+ suitable slots and then start the keylisting with a call to
+ start(). This call might fail, in which case the
+ HierarchicalKeyListJob instance will have scheduled it's own
+ destruction with a call to QObject::deleteLater().
+
+ After result() is emitted, the HierarchicalKeyListJob will
+ schedule its own destruction by calling QObject::deleteLater().
+ */
+ class KDE_EXPORT HierarchicalKeyListJob : public KeyListJob {
+ Q_OBJECT
+ public:
+ HierarchicalKeyListJob( const CryptoBackend::Protocol * protocol,
+ bool remote=false, bool includeSigs=false, bool validating=false );
+ ~HierarchicalKeyListJob();
+
+ /**
+ Starts the keylist operation. \a patterns is a list of patterns
+ used to restrict the list of keys returned. Empty patterns are
+ ignored. \a patterns must not be empty or contain only empty
+ patterns; use the normal KeyListJob for a full listing.
+
+ The \a secretOnly parameter is ignored by
+ HierarchicalKeyListJob and must be set to false.
+ */
+ GpgME::Error start( const QStringList & patterns, bool secretOnly=false );
+
+ GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly,
+ std::vector<GpgME::Key> & keys );
+
+ private slots:
+ void slotResult( const GpgME::KeyListResult & );
+ void slotNextKey( const GpgME::Key & key );
+ /*! \reimp from Job */
+ void slotCancel();
+
+ private:
+ GpgME::Error startAJob();
+
+ private:
+ const CryptoBackend::Protocol * const mProtocol;
+ const bool mRemote;
+ const bool mIncludeSigs;
+ const bool mValidating;
+ bool mTruncated;
+ std::set<QString> mSentSet; // keys already sent (prevent duplicates even if the backend should return them)
+ std::set<QString> mScheduledSet; // keys already scheduled (by starting a job for them)
+ std::set<QString> mNextSet; // keys to schedule for the next iteraton
+ GpgME::KeyListResult mIntermediateResult;
+ QGuardedPtr<KeyListJob> mJob;
+ };
+
+}
+
+#endif // __KLEO_HIERARCHICALKEYLISTJOB_H__
diff --git a/certmanager/lib/kleo/importjob.h b/certmanager/lib/kleo/importjob.h
new file mode 100644
index 000000000..10aa90383
--- /dev/null
+++ b/certmanager/lib/kleo/importjob.h
@@ -0,0 +1,83 @@
+/*
+ importjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_IMPORTJOB_H__
+#define __KLEO_IMPORTJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class ImportResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous importers
+
+ To use a ImportJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the import with a call
+ to start(). This call might fail, in which case the ImportJob
+ instance will have scheduled it's own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the ImportJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class ImportJob : public Job {
+ Q_OBJECT
+ protected:
+ ImportJob( QObject * parent, const char * name );
+ public:
+ ~ImportJob();
+
+ /**
+ Starts the importing operation. \a keyData contains the data to
+ import from.
+ */
+ virtual GpgME::Error start( const QByteArray & keyData ) = 0;
+
+ virtual GpgME::ImportResult exec( const QByteArray & keyData ) = 0;
+
+ signals:
+ void result( const GpgME::ImportResult & result );
+ };
+
+}
+
+#endif // __KLEO_IMPORTJOB_H__
diff --git a/certmanager/lib/kleo/job.cpp b/certmanager/lib/kleo/job.cpp
new file mode 100644
index 000000000..77881d737
--- /dev/null
+++ b/certmanager/lib/kleo/job.cpp
@@ -0,0 +1,116 @@
+/*
+ job.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "job.h"
+
+#include "keylistjob.h"
+#include "encryptjob.h"
+#include "decryptjob.h"
+#include "decryptverifyjob.h"
+#include "signjob.h"
+#include "signencryptjob.h"
+#include "verifydetachedjob.h"
+#include "verifyopaquejob.h"
+#include "keygenerationjob.h"
+#include "importjob.h"
+#include "exportjob.h"
+#include "downloadjob.h"
+#include "deletejob.h"
+#include "refreshkeysjob.h"
+#include "specialjob.h"
+
+#include <qapplication.h>
+#include <kdebug.h>
+
+Kleo::Job::Job( QObject * parent, const char * name )
+ : QObject( parent, name )
+{
+ if ( qApp )
+ connect( qApp, SIGNAL(aboutToQuit()), SLOT(slotCancel()) );
+}
+
+Kleo::Job::~Job() {
+
+}
+
+void Kleo::Job::showErrorDialog( QWidget *, const QString & ) const {
+ kdDebug() << "Kleo::Job::showErrorDialog() should be reimplemented in Kleo::Job subclasses!" << endl;
+}
+
+QString Kleo::Job::auditLogAsHtml() const {
+ kdDebug() << "Kleo::Job::auditLogAsHtml() should be reimplemented in Kleo::Job subclasses!" << endl;
+ return QString();
+}
+
+#define make_job_subclass(x) \
+ Kleo::x::x( QObject * parent, const char * name ) : Job( parent, name ) {} \
+ Kleo::x::~x() {}
+
+make_job_subclass(KeyListJob)
+make_job_subclass(EncryptJob)
+make_job_subclass(DecryptJob)
+make_job_subclass(DecryptVerifyJob)
+make_job_subclass(SignJob)
+make_job_subclass(SignEncryptJob)
+make_job_subclass(VerifyDetachedJob)
+make_job_subclass(VerifyOpaqueJob)
+make_job_subclass(KeyGenerationJob)
+make_job_subclass(ImportJob)
+make_job_subclass(ExportJob)
+make_job_subclass(DownloadJob)
+make_job_subclass(DeleteJob)
+make_job_subclass(RefreshKeysJob)
+make_job_subclass(SpecialJob)
+
+#undef make_job_subclass
+
+#include "job.moc"
+
+#include "keylistjob.moc"
+#include "encryptjob.moc"
+#include "decryptjob.moc"
+#include "decryptverifyjob.moc"
+#include "signjob.moc"
+#include "signencryptjob.moc"
+#include "verifydetachedjob.moc"
+#include "verifyopaquejob.moc"
+#include "keygenerationjob.moc"
+#include "importjob.moc"
+#include "exportjob.moc"
+#include "downloadjob.moc"
+#include "deletejob.moc"
+#include "refreshkeysjob.moc"
+#include "specialjob.moc"
diff --git a/certmanager/lib/kleo/job.h b/certmanager/lib/kleo/job.h
new file mode 100644
index 000000000..ae65008b0
--- /dev/null
+++ b/certmanager/lib/kleo/job.h
@@ -0,0 +1,81 @@
+/*
+ job.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_JOB_H__
+#define __KLEO_JOB_H__
+
+#include <qobject.h>
+#include <qstring.h>
+
+class QWidget;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous crypto operations
+
+ During the operation, you might receive progress updates through
+ the progress() signal as they arrive, but an implementation is
+ free to not send progress information. You should show a busy
+ progressbar until the first progress() signal is received.
+
+ The done() signal is emitted _before_ the result() signals of
+ subclasses and should be used to hide and/or reset progress bars,
+ not to learn of the end of the operation. Use the result()
+ signals for that.
+
+ To cancel the operation, simply call slotCancel(). The result()
+ signal of subclasses will still be emitted, though, and will
+ carry the information that the operation was canceled.
+ */
+ class Job : public QObject {
+ Q_OBJECT
+ protected:
+ Job( QObject * parent, const char * name );
+ public:
+ ~Job();
+
+ virtual void showErrorDialog( QWidget * parent=0, const QString & caption=QString::null ) const;
+
+ virtual QString auditLogAsHtml() const;
+
+ public slots:
+ virtual void slotCancel() = 0;
+
+ signals:
+ void progress( const QString & what, int current, int total );
+ void done();
+ };
+
+}
+
+#endif // __KLEO_JOB_H__
diff --git a/certmanager/lib/kleo/kconfigbasedkeyfilter.cpp b/certmanager/lib/kleo/kconfigbasedkeyfilter.cpp
new file mode 100644
index 000000000..89d18e799
--- /dev/null
+++ b/certmanager/lib/kleo/kconfigbasedkeyfilter.cpp
@@ -0,0 +1,251 @@
+/*
+ kconfigbasedkeyfilter.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "kconfigbasedkeyfilter.h"
+
+#include <kconfigbase.h>
+#include <klocale.h>
+
+static const struct {
+ const char * name;
+ GpgME::Key::OwnerTrust trust;
+ GpgME::UserID::Validity validity;
+} ownerTrustAndValidityMap[] = {
+ { "unknown", GpgME::Key::Unknown, GpgME::UserID::Unknown },
+ { "undefined", GpgME::Key::Undefined, GpgME::UserID::Undefined },
+ { "never", GpgME::Key::Never, GpgME::UserID::Never },
+ { "marginal", GpgME::Key::Marginal, GpgME::UserID::Marginal },
+ { "full", GpgME::Key::Full, GpgME::UserID::Full },
+ { "ultimate", GpgME::Key::Ultimate, GpgME::UserID::Ultimate },
+};
+
+static GpgME::Key::OwnerTrust map2OwnerTrust( const QString & s ) {
+ for ( unsigned int i = 0 ; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap ; ++i )
+ if ( s.lower() == ownerTrustAndValidityMap[i].name )
+ return ownerTrustAndValidityMap[i].trust;
+ return ownerTrustAndValidityMap[0].trust;
+}
+
+static GpgME::UserID::Validity map2Validity( const QString & s ) {
+ for ( unsigned int i = 0 ; i < sizeof ownerTrustAndValidityMap / sizeof *ownerTrustAndValidityMap ; ++i )
+ if ( s.lower() == ownerTrustAndValidityMap[i].name )
+ return ownerTrustAndValidityMap[i].validity;
+ return ownerTrustAndValidityMap[0].validity;
+}
+
+
+Kleo::KConfigBasedKeyFilter::KConfigBasedKeyFilter( const KConfigBase & config )
+ : KeyFilter(),
+ mSpecificity( 0 ),
+ mItalic( false ),
+ mBold( false ),
+ mStrikeOut( false ),
+ mUseFullFont( false ),
+ mRevoked( DoesNotMatter ),
+ mExpired( DoesNotMatter ),
+ mDisabled( DoesNotMatter ),
+ mRoot( DoesNotMatter ),
+ mCanEncrypt( DoesNotMatter ),
+ mCanSign( DoesNotMatter ),
+ mCanCertify( DoesNotMatter ),
+ mCanAuthenticate( DoesNotMatter ),
+ mHasSecret( DoesNotMatter ),
+ mIsOpenPGP( DoesNotMatter ),
+ mWasValidated( DoesNotMatter ),
+ mOwnerTrust( LevelDoesNotMatter ),
+ mOwnerTrustReferenceLevel( GpgME::Key::Unknown ),
+ mValidity( LevelDoesNotMatter ),
+ mValidityReferenceLevel( GpgME::UserID::Unknown )
+{
+ mFgColor = config.readColorEntry( "foreground-color" );
+ mBgColor = config.readColorEntry( "background-color" );
+ mName = config.readEntry( "name", i18n("<unnamed>") );
+ mIcon = config.readEntry( "icon" );
+ if ( config.hasKey( "font" ) ) {
+ mUseFullFont = true;
+ mFont = config.readFontEntry( "font" );
+ } else {
+ mItalic = config.readBoolEntry( "font-italic", false );
+ mBold = config.readBoolEntry( "font-bold", false );
+ }
+ mStrikeOut = config.readBoolEntry( "font-strikeout", false );
+#ifdef SET
+#undef SET
+#endif
+#define SET(member,key) \
+ if ( config.hasKey( key ) ) { \
+ member = config.readBoolEntry( key ) ? Set : NotSet ; \
+ ++mSpecificity; \
+ }
+ SET( mRevoked, "is-revoked" );
+ SET( mExpired, "is-expired" );
+ SET( mDisabled, "is-disabled" );
+ SET( mRoot, "is-root-certificate" );
+ SET( mCanEncrypt, "can-encrypt" );
+ SET( mCanSign, "can-sign" );
+ SET( mCanCertify, "can-certify" );
+ SET( mCanAuthenticate, "can-authenticate" );
+ SET( mHasSecret, "has-secret-key" );
+ SET( mIsOpenPGP, "is-openpgp-key" );
+ SET( mWasValidated, "was-validated" );
+#undef SET
+ static const struct {
+ const char * prefix;
+ LevelState state;
+ } prefixMap[] = {
+ { "is-", Is },
+ { "is-not-", IsNot },
+ { "is-at-least-", IsAtLeast },
+ { "is-at-most-", IsAtMost },
+ };
+ for ( unsigned int i = 0 ; i < sizeof prefixMap / sizeof *prefixMap ; ++i ) {
+ const QString key = QString( prefixMap[i].prefix ) + "ownertrust";
+ if ( config.hasKey( key ) ) {
+ mOwnerTrust = prefixMap[i].state;
+ mOwnerTrustReferenceLevel = map2OwnerTrust( config.readEntry( key ) );
+ ++mSpecificity;
+ break;
+ }
+ }
+ for ( unsigned int i = 0 ; i < sizeof prefixMap / sizeof *prefixMap ; ++i ) {
+ const QString key = QString( prefixMap[i].prefix ) + "validity";
+ if ( config.hasKey( key ) ) {
+ mValidity = prefixMap[i].state;
+ mValidityReferenceLevel = map2Validity( config.readEntry( key ) );
+ ++mSpecificity;
+ break;
+ }
+ }
+}
+
+Kleo::KConfigBasedKeyFilter::~KConfigBasedKeyFilter() {
+
+}
+
+bool Kleo::KConfigBasedKeyFilter::matches( const GpgME::Key & key ) const {
+#ifdef MATCH
+#undef MATCH
+#endif
+#define MATCH(member,method) \
+ if ( member != DoesNotMatter && key.method() != bool( member == Set ) ) \
+ return false
+#define IS_MATCH(what) MATCH( m##what, is##what )
+#define CAN_MATCH(what) MATCH( mCan##what, can##what )
+ IS_MATCH( Revoked );
+ IS_MATCH( Expired );
+ IS_MATCH( Disabled );
+ IS_MATCH( Root );
+ CAN_MATCH( Encrypt );
+ CAN_MATCH( Sign );
+ CAN_MATCH( Certify );
+ CAN_MATCH( Authenticate );
+ MATCH( mHasSecret, isSecret );
+#undef MATCH
+ if ( mIsOpenPGP != DoesNotMatter &&
+ bool( key.protocol() == GpgME::Context::OpenPGP ) != bool( mIsOpenPGP == Set ) )
+ return false;
+ if ( mWasValidated != DoesNotMatter &&
+ bool( key.keyListMode() & GpgME::Context::Validate ) != bool( mWasValidated == Set ) )
+ return false;
+ switch ( mOwnerTrust ) {
+ default:
+ case LevelDoesNotMatter:
+ break;
+ case Is:
+ if ( key.ownerTrust() != mOwnerTrustReferenceLevel )
+ return false;
+ break;
+ case IsNot:
+ if ( key.ownerTrust() == mOwnerTrustReferenceLevel )
+ return false;
+ break;
+ case IsAtLeast:
+ if ( (int)key.ownerTrust() < (int)mOwnerTrustReferenceLevel )
+ return false;
+ break;
+ case IsAtMost:
+ if ( (int)key.ownerTrust() > (int)mOwnerTrustReferenceLevel )
+ return false;
+ break;
+ }
+ const GpgME::UserID uid = key.userID(0);
+ switch ( mValidity ) {
+ default:
+ case LevelDoesNotMatter:
+ break;
+ case Is:
+ if ( uid.validity() != mValidityReferenceLevel )
+ return false;
+ break;
+ case IsNot:
+ if ( uid.validity() == mValidityReferenceLevel )
+ return false;
+ break;
+ case IsAtLeast:
+ if ( (int)uid.validity() < (int)mValidityReferenceLevel )
+ return false;
+ break;
+ case IsAtMost:
+ if ( (int)uid.validity() > (int)mValidityReferenceLevel )
+ return false;
+ break;
+ }
+ return true;
+}
+
+static inline QFont resizedFont( QFont font, int pointSize, bool strike ) {
+ font.setPointSize( pointSize );
+ if ( strike )
+ font.setStrikeOut( true );
+ return font;
+}
+
+static inline QFont adapt( QFont font, bool it, bool b, bool strike ) {
+ if ( it )
+ font.setItalic( true );
+ if ( b )
+ font.setBold( true );
+ if ( strike )
+ font.setStrikeOut( true );
+ return font;
+}
+
+QFont Kleo::KConfigBasedKeyFilter::font( const QFont & f ) const {
+ if ( mUseFullFont )
+ return resizedFont( mFont, f.pointSize(), mStrikeOut );
+ else
+ return adapt( f, mItalic, mBold, mStrikeOut );
+}
diff --git a/certmanager/lib/kleo/kconfigbasedkeyfilter.h b/certmanager/lib/kleo/kconfigbasedkeyfilter.h
new file mode 100644
index 000000000..42c083080
--- /dev/null
+++ b/certmanager/lib/kleo/kconfigbasedkeyfilter.h
@@ -0,0 +1,104 @@
+/*
+ kconfigbasedkeyfilter.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KCONFIGBASEDKEYFILTER_H__
+#define __KLEO_KCONFIGBASEDKEYFILTER_H__
+
+#include "keyfilter.h"
+
+#include <qfont.h>
+#include <qstring.h>
+#include <qcolor.h>
+
+#include <gpgmepp/key.h>
+
+class KConfigBase;
+
+namespace Kleo {
+
+ class KConfigBasedKeyFilter : public KeyFilter {
+ public:
+ explicit KConfigBasedKeyFilter( const KConfigBase & config );
+ ~KConfigBasedKeyFilter();
+ bool matches( const GpgME::Key & key ) const;
+
+ unsigned int specificity() const { return mSpecificity; }
+
+ QColor fgColor() const { return mFgColor; }
+ QColor bgColor() const { return mBgColor; }
+ QFont font( const QFont & ) const;
+ QString name() const { return mName; }
+ QString icon() const { return mIcon; }
+
+ private:
+ QColor mFgColor, mBgColor;
+ QString mName;
+ QString mIcon;
+ unsigned int mSpecificity;
+ bool mItalic;
+ bool mBold;
+ bool mStrikeOut;
+ bool mUseFullFont;
+ QFont mFont;
+
+ enum TriState {
+ DoesNotMatter = 0,
+ Set = 1,
+ NotSet = 2
+ };
+ TriState mRevoked;
+ TriState mExpired;
+ TriState mDisabled;
+ TriState mRoot;
+ TriState mCanEncrypt;
+ TriState mCanSign;
+ TriState mCanCertify;
+ TriState mCanAuthenticate;
+ TriState mHasSecret;
+ TriState mIsOpenPGP;
+ TriState mWasValidated;
+ enum LevelState {
+ LevelDoesNotMatter = 0,
+ Is = 1,
+ IsNot = 2,
+ IsAtLeast = 3,
+ IsAtMost = 4
+ };
+ LevelState mOwnerTrust;
+ GpgME::Key::OwnerTrust mOwnerTrustReferenceLevel;
+ LevelState mValidity;
+ GpgME::UserID::Validity mValidityReferenceLevel;
+ };
+
+}
+
+#endif // __KLEO_KCONFIGBASEDKEYFILTER_H__
diff --git a/certmanager/lib/kleo/keyfilter.h b/certmanager/lib/kleo/keyfilter.h
new file mode 100644
index 000000000..f10fba9bf
--- /dev/null
+++ b/certmanager/lib/kleo/keyfilter.h
@@ -0,0 +1,68 @@
+/*
+ keyfilter.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYFILTER_H__
+#define __KLEO_KEYFILTER_H__
+
+namespace GpgME {
+ class Key;
+}
+
+class QFont;
+class QColor;
+class QString;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class key filters
+
+ */
+ class KeyFilter {
+ public:
+ virtual ~KeyFilter() {}
+ virtual bool matches( const GpgME::Key & key ) const = 0;
+
+ virtual unsigned int specificity() const = 0;
+
+ // not sure if we want these here, but for the time being, it's
+ // the easiest way:
+ virtual QColor fgColor() const = 0;
+ virtual QColor bgColor() const = 0;
+ virtual QFont font( const QFont & ) const = 0;
+ virtual QString name() const = 0;
+ virtual QString icon() const = 0;
+ };
+
+}
+
+#endif // __KLEO_KEYFILTER_H__
diff --git a/certmanager/lib/kleo/keyfiltermanager.cpp b/certmanager/lib/kleo/keyfiltermanager.cpp
new file mode 100644
index 000000000..14932801c
--- /dev/null
+++ b/certmanager/lib/kleo/keyfiltermanager.cpp
@@ -0,0 +1,118 @@
+/*
+ keyfiltermanager.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "keyfiltermanager.h"
+#include "kconfigbasedkeyfilter.h"
+
+#include "cryptobackendfactory.h"
+
+#include <kconfig.h>
+
+#include <qapplication.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qvaluevector.h>
+
+#include <algorithm>
+
+namespace {
+ template <typename T>
+ struct Delete {
+ void operator()( T * item ) { delete item; }
+ };
+}
+
+struct Kleo::KeyFilterManager::Private {
+ void clear() {
+ std::for_each( filters.begin(), filters.end(), Delete<KeyFilter>() );
+ filters.clear();
+ }
+
+ QValueVector<KeyFilter*> filters;
+};
+
+Kleo::KeyFilterManager * Kleo::KeyFilterManager::mSelf = 0;
+
+Kleo::KeyFilterManager::KeyFilterManager( QObject * parent, const char * name )
+ : QObject( parent, name ), d( 0 )
+{
+ mSelf = this;
+ d = new Private();
+ // ### DF: doesn't a KStaticDeleter work more reliably?
+ if ( qApp )
+ connect( qApp, SIGNAL(aboutToQuit()), SLOT(deleteLater()) );
+ reload();
+}
+
+Kleo::KeyFilterManager::~KeyFilterManager() {
+ mSelf = 0;
+ if ( d )
+ d->clear();
+ delete d; d = 0;
+}
+
+Kleo::KeyFilterManager * Kleo::KeyFilterManager::instance() {
+ if ( !mSelf )
+ mSelf = new Kleo::KeyFilterManager();
+ return mSelf;
+}
+
+const Kleo::KeyFilter * Kleo::KeyFilterManager::filterMatching( const GpgME::Key & key ) const {
+ for ( QValueVector<KeyFilter*>::const_iterator it = d->filters.begin() ; it != d->filters.end() ; ++it )
+ if ( (*it)->matches( key ) )
+ return *it;
+ return 0;
+}
+
+static inline bool by_increasing_specificity( const Kleo::KeyFilter * left, const Kleo::KeyFilter * right ) {
+ return left->specificity() > right->specificity();
+}
+
+void Kleo::KeyFilterManager::reload() {
+ d->clear();
+
+ KConfig * config = Kleo::CryptoBackendFactory::instance()->configObject();
+ if ( !config )
+ return;
+ const QStringList groups = config->groupList().grep( QRegExp( "^Key Filter #\\d+$" ) );
+ for ( QStringList::const_iterator it = groups.begin() ; it != groups.end() ; ++it ) {
+ const KConfigGroup cfg( config, *it );
+ d->filters.push_back( new KConfigBasedKeyFilter( cfg ) );
+ }
+ std::stable_sort( d->filters.begin(), d->filters.end(), by_increasing_specificity );
+}
+
+#include "keyfiltermanager.moc"
diff --git a/certmanager/lib/kleo/keyfiltermanager.h b/certmanager/lib/kleo/keyfiltermanager.h
new file mode 100644
index 000000000..25353d71a
--- /dev/null
+++ b/certmanager/lib/kleo/keyfiltermanager.h
@@ -0,0 +1,69 @@
+/*
+ keyfiltermanager.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYFILTERMANAGER_H__
+#define __KLEO_KEYFILTERMANAGER_H__
+
+#include <qobject.h>
+#include <kdepimmacros.h>
+namespace GpgME {
+ class Key;
+}
+
+namespace Kleo {
+ class KeyFilter;
+}
+
+namespace Kleo {
+
+ class KDE_EXPORT KeyFilterManager : public QObject {
+ Q_OBJECT
+ protected:
+ KeyFilterManager( QObject * parent=0, const char * name=0 );
+ ~KeyFilterManager();
+
+ public:
+ static KeyFilterManager * instance();
+
+ const KeyFilter * filterMatching( const GpgME::Key & key ) const;
+
+ void reload();
+
+ private:
+ class Private;
+ Private * d;
+ static KeyFilterManager * mSelf;
+ };
+
+}
+
+#endif // __KLEO_KEYFILTERMANAGER_H__
diff --git a/certmanager/lib/kleo/keygenerationjob.h b/certmanager/lib/kleo/keygenerationjob.h
new file mode 100644
index 000000000..f78152c5c
--- /dev/null
+++ b/certmanager/lib/kleo/keygenerationjob.h
@@ -0,0 +1,81 @@
+/*
+ keygenerationjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYGENERATIONJOB_H__
+#define __KLEO_KEYGENERATIONJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class KeyGenerationResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous key generation
+
+ To use a KeyGenerationJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the key generation with
+ a call to start(). This call might fail, in which case the
+ KeyGenerationJob instance will have scheduled it's own
+ destruction with a call to QObject::deleteLater().
+
+ After result() is emitted, the KeyGenerationJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class KeyGenerationJob : public Job {
+ Q_OBJECT
+ protected:
+ KeyGenerationJob( QObject * parent, const char * name );
+ public:
+ ~KeyGenerationJob();
+
+ /**
+ Starts the key generation operation. \a parameters is a
+ backend-specific string containing the paramaters of the key to
+ create (length, capabilities, etc).
+ */
+ virtual GpgME::Error start( const QString & parameters ) = 0;
+
+ signals:
+ void result( const GpgME::KeyGenerationResult & result, const QByteArray & pubKeyData );
+ };
+
+}
+
+#endif // __KLEO_KEYGENERATIONJOB_H__
diff --git a/certmanager/lib/kleo/keylistjob.h b/certmanager/lib/kleo/keylistjob.h
new file mode 100644
index 000000000..c419ad47d
--- /dev/null
+++ b/certmanager/lib/kleo/keylistjob.h
@@ -0,0 +1,96 @@
+/*
+ keylistjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYLISTJOB_H__
+#define __KLEO_KEYLISTJOB_H__
+
+#include "job.h"
+
+#include <vector>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class KeyListResult;
+}
+
+class QStringList;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous key listers
+
+ To use a KeyListJob, first obtain an instance from the
+ CryptoBackend implementation, connect the nextKey(), progress()
+ and result() signals to suitable slots and then start the key
+ listing with a call to start(). This call might fail, in which
+ case the KeylistJob instance will have schedules it's own
+ destruction with a call to QObject::deleteLater().
+
+ During keylisting, you will receive new key objects through the
+ nextKey() signal as they arrive. After result() is emitted, the
+ KeyListJob will schedule it's own destruction by calling
+ QObject::deleteLater().
+ */
+ class KeyListJob : public Job {
+ Q_OBJECT
+ protected:
+ KeyListJob( QObject * parent, const char * name );
+
+ public:
+ ~KeyListJob();
+
+ /**
+ Starts the keylist operation. \a pattern is a list of patterns
+ used to restrict the list of keys returned. Empty patterns are
+ ignored. If \a pattern is empty or contains only empty strings,
+ all keys are returned (however, the backend is free to truncate
+ the result and should do so; when this happens, it will be
+ reported by the reult object).
+
+ If \a secretOnly is true, only keys for which the secret key is
+ also available are returned. Use this if you need to select a
+ key for signing.
+ */
+ virtual GpgME::Error start( const QStringList & patterns, bool secretOnly=false ) = 0;
+
+ virtual GpgME::KeyListResult exec( const QStringList & patterns, bool secretOnly, std::vector<GpgME::Key> & keys ) = 0;
+
+ signals:
+ void nextKey( const GpgME::Key & key );
+ void result( const GpgME::KeyListResult & result );
+ };
+
+}
+
+#endif // __KLEO_KEYLISTJOB_H__
diff --git a/certmanager/lib/kleo/multideletejob.cpp b/certmanager/lib/kleo/multideletejob.cpp
new file mode 100644
index 000000000..32596e78f
--- /dev/null
+++ b/certmanager/lib/kleo/multideletejob.cpp
@@ -0,0 +1,110 @@
+/*
+ multideletejob.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "multideletejob.h"
+#include "cryptobackend.h"
+#include "deletejob.h"
+
+#include <klocale.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/context.h>
+#include <gpgmepp/data.h>
+
+#include <iterator>
+
+#include <assert.h>
+
+Kleo::MultiDeleteJob::MultiDeleteJob( const CryptoBackend::Protocol * protocol )
+ : Job( 0, "Kleo::MultiDeleteJob" ),
+ mProtocol( protocol ),
+ mJob( 0 )
+{
+ assert( protocol );
+}
+
+Kleo::MultiDeleteJob::~MultiDeleteJob() {
+
+}
+
+GpgME::Error Kleo::MultiDeleteJob::start( const std::vector<GpgME::Key> & keys, bool allowSecretKeyDeletion ) {
+ mKeys = keys;
+ mAllowSecretKeyDeletion = allowSecretKeyDeletion;
+ mIt = mKeys.begin();
+
+ const GpgME::Error err = startAJob();
+
+ if ( err )
+ deleteLater();
+ return err;
+}
+
+void Kleo::MultiDeleteJob::slotCancel() {
+ if ( mJob ) mJob->slotCancel();
+ mIt = mKeys.end();
+}
+
+void Kleo::MultiDeleteJob::slotResult( const GpgME::Error & err ) {
+ mJob = 0;
+ GpgME::Error error = err;
+ if ( error || // error in last op
+ mIt == mKeys.end() || // (shouldn't happen)
+ ++mIt == mKeys.end() || // was the last key
+ (error = startAJob()) ) { // error starting the job for the new key
+ emit done();
+ emit result( error, error && mIt != mKeys.end() ? *mIt : GpgME::Key::null );
+ deleteLater();
+ return;
+ }
+
+ const int current = mIt - mKeys.begin();
+ const int total = mKeys.size();
+ emit progress( i18n("progress info: \"%1 of %2\"","%1/%2").arg( current ).arg( total ), current, total );
+}
+
+GpgME::Error Kleo::MultiDeleteJob::startAJob() {
+ if ( mIt == mKeys.end() )
+ return 0;
+ mJob = mProtocol->deleteJob();
+ assert( mJob ); // FIXME: we need a way to generate errors ourselves,
+ // but I don't like the dependency on gpg-error :/
+
+ connect( mJob, SIGNAL(result(const GpgME::Error&)), SLOT(slotResult(const GpgME::Error&)) );
+
+ return mJob->start( *mIt, mAllowSecretKeyDeletion );
+}
+
+#include "multideletejob.moc"
diff --git a/certmanager/lib/kleo/multideletejob.h b/certmanager/lib/kleo/multideletejob.h
new file mode 100644
index 000000000..5b995adaf
--- /dev/null
+++ b/certmanager/lib/kleo/multideletejob.h
@@ -0,0 +1,101 @@
+/*
+ multideletejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_MULTIDELETEJOB_H__
+#define __KLEO_MULTIDELETEJOB_H__
+
+#include <kleo/job.h>
+#include <kleo/cryptobackend.h>
+
+#include <kdepimmacros.h>
+#include <qguardedptr.h>
+
+#include <vector>
+
+namespace GpgME {
+ class Error;
+ class Key;
+}
+
+namespace Kleo {
+ class DeleteJob;
+}
+
+namespace Kleo {
+
+ /**
+ @short A convenience class bundling together multiple DeleteJobs.
+
+ To use a MultiDeleteJob, pass it a CryptoBackend implementation,
+ connect the progress() and result() signals to suitable slots and
+ then start the delete with a call to start(). This call might
+ fail, in which case the MultiDeleteJob instance will have scheduled
+ it's own destruction with a call to QObject::deleteLater().
+
+ After result() is emitted, the MultiDeleteJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class KDE_EXPORT MultiDeleteJob : public Job {
+ Q_OBJECT
+ public:
+ MultiDeleteJob( const CryptoBackend::Protocol * protocol );
+ ~MultiDeleteJob();
+
+ /**
+ Starts the delete operation. \a keys is the list of keys to
+ delete, \a allowSecretKeyDeletion specifies if a key may also
+ be deleted if the secret key part is available, too.
+ */
+ GpgME::Error start( const std::vector<GpgME::Key> & keys, bool allowSecretKeyDeletion=false );
+
+ signals:
+ void result( const GpgME::Error & result, const GpgME::Key & errorKey );
+
+ private slots:
+ void slotResult( const GpgME::Error & );
+ /*! \reimp from Job */
+ void slotCancel();
+
+ private:
+ GpgME::Error startAJob();
+
+ private:
+ const CryptoBackend::Protocol * mProtocol;
+ QGuardedPtr<DeleteJob> mJob;
+ std::vector<GpgME::Key> mKeys;
+ std::vector<GpgME::Key>::const_iterator mIt;
+ bool mAllowSecretKeyDeletion;
+ };
+
+}
+
+#endif // __KLEO_MULTIDELETEJOB_H__
diff --git a/certmanager/lib/kleo/oidmap.h b/certmanager/lib/kleo/oidmap.h
new file mode 100644
index 000000000..596296332
--- /dev/null
+++ b/certmanager/lib/kleo/oidmap.h
@@ -0,0 +1,57 @@
+/*
+ oidmap.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_OIDMAP_H__
+#define __KLEO_OIDMAP_H__
+
+static struct {
+ const char * name;
+ const char * oid;
+} oidmap[] = {
+ // keep them ordered by oid:
+ { "SP", "ST" }, // hack to show the Sphinx-required/desired SP for
+ // StateOrProvince, otherwise known as ST or even S
+ { "NameDistinguisher", "0.2.262.1.10.7.20" },
+ { "EMAIL", "1.2.840.113549.1.9.1" },
+ { "SN", "2.5.4.4" },
+ { "SerialNumber", "2.5.4.5" },
+ { "T", "2.5.4.12" },
+ { "D", "2.5.4.13" },
+ { "BC", "2.5.4.15" },
+ { "ADDR", "2.5.4.16" },
+ { "PC", "2.5.4.17" },
+ { "GN", "2.5.4.42" },
+ { "Pseudo", "2.5.4.65" },
+};
+static const unsigned int numOidMaps = sizeof oidmap / sizeof *oidmap;
+
+#endif // __KLEO_OIDMAP_H__
diff --git a/certmanager/lib/kleo/refreshkeysjob.h b/certmanager/lib/kleo/refreshkeysjob.h
new file mode 100644
index 000000000..dcf9cd516
--- /dev/null
+++ b/certmanager/lib/kleo/refreshkeysjob.h
@@ -0,0 +1,90 @@
+/*
+ refreshkeysjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_REFRESHKEYSJOB_H__
+#define __KLEO_REFRESHKEYSJOB_H__
+
+#include "job.h"
+
+#include <vector>
+
+namespace GpgME {
+ class Error;
+ class Key;
+}
+
+class QStringList;
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous key refreshers.
+
+ To use a RefreshKeysJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the key refresh with a
+ call to start(). This call might fail, in which case the
+ RefreshKeysJob instance will have scheduled its own destruction
+ with a call to QObject::deleteLater().
+
+ After result() is emitted, the KeyListJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class RefreshKeysJob : public Job {
+ Q_OBJECT
+ protected:
+ RefreshKeysJob( QObject * parent, const char * name );
+
+ public:
+ ~RefreshKeysJob();
+
+ /**
+ Starts the keylist operation. \a pattern is a list of patterns
+ used to restrict the list of keys returned. Empty patterns are
+ ignored. If \a pattern is empty or contains only empty strings,
+ all keys are returned (however, the backend is free to truncate
+ the result and should do so; when this happens, it will be
+ reported by the reult object).
+
+ If \a secretOnly is true, only keys for which the secret key is
+ also available are returned. Use this if you need to select a
+ key for signing.
+ */
+ virtual GpgME::Error start( const QStringList & patterns ) = 0;
+
+ signals:
+ void result( const GpgME::Error & error );
+ };
+
+}
+
+#endif // __KLEO_REFRESHKEYSJOB_H__
diff --git a/certmanager/lib/kleo/signencryptjob.h b/certmanager/lib/kleo/signencryptjob.h
new file mode 100644
index 000000000..42d3a179f
--- /dev/null
+++ b/certmanager/lib/kleo/signencryptjob.h
@@ -0,0 +1,103 @@
+/*
+ signencryptjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_SIGNENCRYPTJOB_H__
+#define __KLEO_SIGNENCRYPTJOB_H__
+
+#include <gpgmepp/context.h> // for Context::SignatureMode (or should
+ // we roll our own enum here?)
+#include "job.h"
+#include <qcstring.h>
+
+#include <vector>
+#include <utility>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class SigningResult;
+ class EncryptionResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous combined signing and encrypting
+
+ To use a SignEncryptJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the operation with a
+ call to start(). This call might fail, in which case the
+ SignEncryptJob instance will have scheduled it's own destruction
+ with a call to QObject::deleteLater().
+
+ After result() is emitted, the SignEncryptJob will schedule it's
+ own destruction by calling QObject::deleteLater().
+ */
+ class SignEncryptJob : public Job {
+ Q_OBJECT
+ protected:
+ SignEncryptJob( QObject * parent, const char * name );
+ public:
+ ~SignEncryptJob();
+
+ /**
+ Starts the combined signing and encrypting operation. \a signers
+ is the list of keys to sign \a plainText with. \a recipients is
+ a list of keys to encrypt the signed \a plainText to. In both
+ lists, empty (null) keys are ignored.
+
+ If \a alwaysTrust is true, validity checking for the
+ \em recipient keys will not be performed, but full validity
+ assumed for all \em recipient keys without further checks.
+ */
+ virtual GpgME::Error start( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText,
+ bool alwaysTrust=false ) = 0;
+
+ virtual std::pair<GpgME::SigningResult,GpgME::EncryptionResult>
+ exec( const std::vector<GpgME::Key> & signers,
+ const std::vector<GpgME::Key> & recipients,
+ const QByteArray & plainText,
+ bool alwaysTrust, QByteArray & cipherText ) = 0;
+
+ signals:
+ void result( const GpgME::SigningResult & signingresult,
+ const GpgME::EncryptionResult & encryptionresult,
+ const QByteArray & cipherText );
+ };
+
+}
+
+#endif // __KLEO_SIGNENCRYPTJOB_H__
diff --git a/certmanager/lib/kleo/signjob.h b/certmanager/lib/kleo/signjob.h
new file mode 100644
index 000000000..17ea3d947
--- /dev/null
+++ b/certmanager/lib/kleo/signjob.h
@@ -0,0 +1,90 @@
+/*
+ signjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_SIGNJOB_H__
+#define __KLEO_SIGNJOB_H__
+
+#include <gpgmepp/context.h> // for Context::SignatureMode (or should
+ // we roll our own enum here?)
+#include "job.h"
+#include <qcstring.h>
+
+#include <vector>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class SigningResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous signing
+
+ To use a SignJob, first obtain an instance from the CryptoBackend
+ implementation, connect the progress() and result() signals to
+ suitable slots and then start the signing with a call to
+ start(). This call might fail, in which case the SignJob instance
+ will have scheduled it's own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the SignJob will schedule it's own
+ destruction by calling QObject::deleteLater().
+ */
+ class SignJob : public Job {
+ Q_OBJECT
+ protected:
+ SignJob( QObject * parent, const char * name );
+ public:
+ ~SignJob();
+
+ /**
+ Starts the signing operation. \a signers is the list of keys to
+ sign \a plainText with. Empty (null) keys are ignored.
+ */
+ virtual GpgME::Error start( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode ) = 0;
+ virtual GpgME::SigningResult exec( const std::vector<GpgME::Key> & signers,
+ const QByteArray & plainText,
+ GpgME::Context::SignatureMode mode,
+ QByteArray & signature ) = 0;
+
+ signals:
+ void result( const GpgME::SigningResult & result, const QByteArray & signature );
+ };
+
+}
+
+#endif // __KLEO_SIGNJOB_H__
diff --git a/certmanager/lib/kleo/specialjob.h b/certmanager/lib/kleo/specialjob.h
new file mode 100644
index 000000000..e7280b0a5
--- /dev/null
+++ b/certmanager/lib/kleo/specialjob.h
@@ -0,0 +1,86 @@
+/*
+ specialjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_SPECIALJOB_H__
+#define __KLEO_SPECIALJOB_H__
+
+#include "job.h"
+
+namespace GpgME {
+ class Error;
+}
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for protocol-specific jobs
+
+ To use a SpecialJob, first obtain an instance from the
+ CryptoBackend implementation, connect progress() and result()
+ signals to suitable slots and then start the job with a call to
+ start(). This call might fail, in which case the SpecialJob
+ instance will have schedules its own destruction with a call to
+ QObject::deleteLater().
+
+ After result() is emitted, the SpecialJob will schedule its own
+ destruction by calling QObject::deleteLater().
+
+ Parameters are set using the Qt property system. More general, or
+ constructor parameters are given in the call to
+ Kleo::CryptoBackend::Protocol::specialJob().
+
+ The result is made available through the result signal, and
+ through the read-only result property, the latter of which needs
+ to be defined in each SpecialJob subclass.
+ */
+ class SpecialJob : public Job {
+ Q_OBJECT
+ protected:
+ SpecialJob( QObject * parent, const char * name );
+
+ public:
+ ~SpecialJob();
+
+ /**
+ Starts the special operation.
+ */
+ virtual GpgME::Error start() = 0;
+
+ virtual GpgME::Error exec() = 0;
+
+ signals:
+ void result( const GpgME::Error & result, const QVariant & data );
+ };
+
+}
+
+#endif // __KLEO_SPECIALJOB_H__
diff --git a/certmanager/lib/kleo/verifydetachedjob.h b/certmanager/lib/kleo/verifydetachedjob.h
new file mode 100644
index 000000000..f50fda546
--- /dev/null
+++ b/certmanager/lib/kleo/verifydetachedjob.h
@@ -0,0 +1,86 @@
+/*
+ verifydetachedjob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_VERIFYDETACHEDJOB_H__
+#define __KLEO_VERIFYDETACHEDJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class VerificationResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous verification of detached signatures
+
+ To use a VerifyDetachedJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the verification with a
+ call to start(). This call might fail, in which case the
+ VerifyDetachedJob instance will have scheduled it's own
+ destruction with a call to QObject::deleteLater().
+
+ After result() is emitted, the VerifyDetachedJob will schedule
+ it's own destruction by calling QObject::deleteLater().
+ */
+ class VerifyDetachedJob : public Job {
+ Q_OBJECT
+ protected:
+ VerifyDetachedJob( QObject * parent, const char * name );
+ public:
+ ~VerifyDetachedJob();
+
+ /**
+ Starts the verification operation. \a signature contains the
+ signature data, while \a signedData contains the data over
+ which the signature was made.
+ */
+ virtual GpgME::Error start( const QByteArray & signature,
+ const QByteArray & signedData ) = 0;
+
+ virtual GpgME::VerificationResult exec( const QByteArray & signature,
+ const QByteArray & signedData ) = 0;
+
+ signals:
+ void result( const GpgME::VerificationResult & result );
+ };
+
+}
+
+#endif // __KLEO_VERIFYDETACHEDJOB_H__
diff --git a/certmanager/lib/kleo/verifyopaquejob.h b/certmanager/lib/kleo/verifyopaquejob.h
new file mode 100644
index 000000000..b38b18de1
--- /dev/null
+++ b/certmanager/lib/kleo/verifyopaquejob.h
@@ -0,0 +1,85 @@
+/*
+ verifyopaquejob.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_VERIFYOPAQUEJOB_H__
+#define __KLEO_VERIFYOPAQUEJOB_H__
+
+#include "job.h"
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class Key;
+ class VerificationResult;
+}
+
+
+namespace Kleo {
+
+ /**
+ @short An abstract base class for asynchronous verification of opaque signatures
+
+ To use a VerifyOpaqueJob, first obtain an instance from the
+ CryptoBackend implementation, connect the progress() and result()
+ signals to suitable slots and then start the verification with a
+ call to start(). This call might fail, in which case the
+ VerifyOpaqueJob instance will have scheduled it's own
+ destruction with a call to QObject::deleteLater().
+
+ After result() is emitted, the VerifyOpaqueJob will schedule
+ it's own destruction by calling QObject::deleteLater().
+ */
+ class VerifyOpaqueJob : public Job {
+ Q_OBJECT
+ protected:
+ VerifyOpaqueJob( QObject * parent, const char * name );
+ public:
+ ~VerifyOpaqueJob();
+
+ /**
+ Starts the verification operation. \a signature contains the
+ signature data, while \a signedData contains the data over
+ which the signature was made.
+ */
+ virtual GpgME::Error start( const QByteArray & signedData ) = 0;
+
+ /** Synchronous version of @ref start */
+ virtual GpgME::VerificationResult exec( const QByteArray & signedData, QByteArray & plainText ) = 0;
+
+ signals:
+ void result( const GpgME::VerificationResult & result, const QByteArray & plainText );
+ };
+
+}
+
+#endif // __KLEO_VERIFYOPAQUEJOB_H__
diff --git a/certmanager/lib/libkleopatrarc.desktop b/certmanager/lib/libkleopatrarc.desktop
new file mode 100644
index 000000000..3af8feaf0
--- /dev/null
+++ b/certmanager/lib/libkleopatrarc.desktop
@@ -0,0 +1,323 @@
+[Key Filter #0]
+was-validated=false
+Name=Not Validated Key
+Name[af]=Sleutel nie bevestig nie
+Name[bg]=Ðепроверен ключ
+Name[ca]=Clau no validada
+Name[cs]=Nevalidovaný klíÄ
+Name[da]=Ikke godkendt nøgle
+Name[de]=Ungeprüfter Schlüssel
+Name[el]=Μη επικυÏωμένο κλειδί
+Name[eo]=Åœlosilo Ne Validigita
+Name[es]=Clave no validada
+Name[et]=Võtme ehtsus kontrollimatu
+Name[eu]=Balidatu gabeko gakoa
+Name[fa]=کلید بدون اعتبار
+Name[fi]=Varmistamaton avain
+Name[fr]=Clé non validée
+Name[fy]=Net falidearre kaai
+Name[gl]=Non hai Chave Validada
+Name[he]=מפתח ×œ× ×ž×•×•×“×
+Name[hu]=Nem ellenőrzött kulcs
+Name[is]=Ekki staðfestur lykill
+Name[it]=Chiave non convalidata
+Name[ja]=èªè¨¼ã•ã‚Œã¦ã„ãªã„éµ
+Name[ka]=დáƒáƒ£áƒ›áƒáƒ¬áƒ›áƒ”ბელი გáƒáƒ¡áƒáƒ¦áƒ”ბი
+Name[kk]=ТекÑерілмеген кілт
+Name[km]=កូនសោ​គ្មាន​សុពលភាព
+Name[ko]=ê²€ì¦ë˜ì§€ ì•Šì€ í‚¤
+Name[lt]=Nevaliduotas raktas
+Name[ms]=Kekunci Tidak Disahkan
+Name[nb]=Nøkkel ikke sjekket for gyldighet
+Name[nds]=Nich pröövt Slötel
+Name[ne]=पà¥à¤°à¤®à¤¾à¤£à¥€à¤¤ नगरिà¤à¤•à¥‹ कà¥à¤žà¥à¤œà¥€
+Name[nl]=Geen gevalideerde sleutel
+Name[nn]=Ikkje-validert nøkkel
+Name[pl]=Niesprawdzony klucz
+Name[pt]=Chave Não Validada
+Name[pt_BR]=Chave Não Validada
+Name[ru]=Ðепроверенный ключ
+Name[se]=Ii-validerejuvvon Äoavdda
+Name[sk]=Neoverený kľúÄ
+Name[sl]=Nepreverjen kljuÄ
+Name[sr]=Ðеоверени кључ
+Name[sr@Latn]=Neovereni kljuÄ
+Name[sv]=Nyckeln har inte validerats
+Name[ta]=செலà¯à®²à¯à®ªà®Ÿà®¿à®¯à®¾à®•à®¾à®¤ விசை
+Name[tr]=Geçerli Olmayan Anahtar
+Name[uk]=Ðеперевірений ключ
+Name[zh_CN]=未校验的密钥
+Name[zh_TW]=未確èªçš„金鑰
+
+[Key Filter #1]
+was-validated=true
+is-expired=true
+is-revoked=false
+foreground-color=255,0,0
+Name=Expired Key
+Name[af]=Sleutel het verval
+Name[bg]=Изтекъл ключ
+Name[br]=Alc'hwez kabac'het
+Name[ca]=Clau expirada
+Name[cs]=Klíš s prošlou platností
+Name[da]=Udløbet nøgle
+Name[de]=Abgelaufener Schlüssel
+Name[el]=Ληγμένο κλειδί
+Name[eo]=Åœlosilo EksvalidiÄinta
+Name[es]=Clave caducada
+Name[et]=Aegunud võti
+Name[eu]=Iraungitako gakoa
+Name[fa]=کلید منقضی
+Name[fi]=Vanhentunut avain
+Name[fr]=Clé expirée
+Name[fy]=Ferrûne kaai
+Name[gl]=Chave caducada
+Name[he]=מפתח ×œ× ×ª×§×£
+Name[hu]=Lejárt kulcs
+Name[is]=Útrunninn lykill
+Name[it]=Chiave scaduta
+Name[ja]=期é™åˆ‡ã‚Œã®éµ
+Name[ka]=ვáƒáƒ“áƒáƒ’áƒáƒ¡áƒ£áƒšáƒ˜ გáƒáƒ¡áƒáƒ¦áƒ”ბი
+Name[kk]=ЕÑкірген кілт
+Name[km]=កូនសោ​បាន​ផុážáž€áŸ†ážŽážáŸ‹
+Name[ko]=ë§Œë£Œëœ í‚¤
+Name[lt]=Baigęs galioti raktas
+Name[mk]=ИÑтечен клуч
+Name[ms]=Kekunci Luput
+Name[nb]=Utgått nøkkel
+Name[nds]=Aflopen Slötel
+Name[ne]=मà¥à¤¯à¤¾à¤¦ समापà¥à¤¤ भà¤à¤•à¥‹ कà¥à¤žà¥à¤œà¥€
+Name[nl]=Verlopen sleutel
+Name[nn]=Forelda nøkkel
+Name[pl]=Klucz, który stracił ważność
+Name[pt]=Chave Expirada
+Name[pt_BR]=Chave Expirada
+Name[ru]=УтерÑвший Ñилу ключ
+Name[se]=Boarásmuvvan Äoavdda
+Name[sk]=VyprÅ¡aný kľúÄ
+Name[sl]=PreteÄen kljuÄ
+Name[sr]=ИÑтекли кључ
+Name[sr@Latn]=Istekli kljuÄ
+Name[sv]=Utgången nyckel
+Name[ta]=காலாவதியான விசை
+Name[tr]=Süresi Dolmuş Anahtar
+Name[uk]=ЗаÑтарілий ключ
+Name[zh_CN]=过期密钥
+Name[zh_TW]=å·²éŽæœŸçš„金鑰
+
+[Key Filter #2]
+was-validated=true
+is-revoked=true
+Name=Revoked Key
+Name[af]=Sleutel was herroep
+Name[bg]=Ðнулиран ключ
+Name[ca]=Clau revocada
+Name[cs]=Odvolaný klíÄ
+Name[da]=Fjernet nøgle
+Name[de]=Widerrufener Schlüssel
+Name[el]=ΑκυÏωμένο κλειδί
+Name[eo]=Åœlosilo Revokita
+Name[es]=Clave revocada
+Name[et]=Tühistatud võti
+Name[eu]=Errebokatutako gakoa
+Name[fa]=کلید لغو‌شده
+Name[fi]=Peruutettu avain
+Name[fr]=Clé révoquée
+Name[fy]=Ynlutsen kaai
+Name[gl]=Chave revocada
+Name[he]=מפתח ×œ× ×§×‘×™×œ
+Name[hu]=Visszavont kulcs
+Name[is]=Afturkallaður lykill
+Name[it]=Chiave revocata
+Name[ja]=破棄ã•ã‚ŒãŸéµ
+Name[ka]=áƒáƒœáƒ£áƒšáƒ˜áƒ áƒ”ბული გáƒáƒ¡áƒáƒ¦áƒ”ბი
+Name[kk]=Күші жойылған кілт
+Name[km]=កូនសោ​ážáŸ’រូវ​បាន​ដកហូáž
+Name[ko]=ê±°ë¶€ëœ í‚¤
+Name[lt]=Atšauktas raktas
+Name[mk]=Отповикан клуч
+Name[ms]=Kekunci Dibatalkan
+Name[nb]=Tilbakekalt nøkkel
+Name[nds]=Torüchropen Slötel
+Name[ne]=रदà¥à¤¦ गरिà¤à¤•à¥‹ कà¥à¤žà¥à¤œà¥€
+Name[nl]=Ingetrokken sleutel
+Name[nn]=Tilbakekalla nøkkel
+Name[pl]=Odwołany klucz
+Name[pt]=Chave Revogada
+Name[pt_BR]=Chave Revogada
+Name[ru]=Отозванный ключ
+Name[sk]=KÄ¾ÃºÄ so zruÅ¡enou platnosÅ¥ou
+Name[sl]=Preklican kljuÄ
+Name[sr]=Опозвани кључ
+Name[sr@Latn]=Opozvani kljuÄ
+Name[sv]=Ã…terkallad nyckel
+Name[ta]=நீகà¯à®•à®¿à®¯ விசை
+Name[tr]=Geri Alınmış Anahtar
+Name[uk]=Ðнульований ключ
+Name[zh_CN]=åŠé”€çš„密钥
+Name[zh_TW]=已廢棄的金鑰
+
+[Key Filter #3]
+was-validated=true
+is-root-certificate=true
+is-validity=ultimate
+Name=Trusted Root Certificate
+Name[af]=Vertroude 'Root' sertifikaat
+Name[ar]=شهادة جذر موثوق بها
+Name[bg]=Ðадеждно удоÑтоверение
+Name[ca]=Certificat arrel de confiança
+Name[cs]=Důvěryhodný kořenový certifikát
+Name[da]=Root-certifikat der stoles på
+Name[de]=Vertrauenswürdiges Stammzertifikat
+Name[el]=Έμπιστο βασικό πιστοποιητικό
+Name[eo]=Fidinda Radika Certifikato
+Name[es]=Certificado raíz de confianza
+Name[et]=Usaldusväärne juursertifikaat
+Name[eu]=Konfidantzazko erro ziurtagiria
+Name[fa]=گواهی‌نامۀ معتبر کاربر ارشد
+Name[fi]=Luotettu juurivarmenne
+Name[fr]=Certificat racine de confiance
+Name[fy]=Fertroude haadsertifikaat
+Name[gl]=Certificado raiz autentificado
+Name[hu]=Megbízható gyökértanúsítvány
+Name[is]=Treyst rótarskilríki
+Name[it]=Certificato radice affidabile
+Name[ja]=ä¿¡é ¼ã•ã‚ŒãŸãƒ«ãƒ¼ãƒˆè¨¼æ˜Žæ›¸
+Name[ka]= რუტის სáƒáƒœáƒ“რსერთიფიკáƒáƒ¢áƒ˜
+Name[kk]=Сенім артылған түбір куәлігі
+Name[km]=វិញ្ញាបនបážáŸ’ážš Root ដែល​អាច​ជឿទុកចិážáŸ’áž
+Name[lt]=Patikimas root sertifikatas
+Name[mk]=Доверлив коренов Ñертификат
+Name[ms]=Sijil Root Dipercaya
+Name[nb]=Tiltrodd rot-sertifikat
+Name[nds]=Vertroonswöördig Wörtelzertifikaat
+Name[ne]=विशà¥à¤µà¤¾à¤¸ गरिà¤à¤•à¤¾ मूल पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°
+Name[nl]=Vertrouwd hoofdcertificaat
+Name[nn]=Tiltrudd rotsertifikat
+Name[pl]=Zaufany certyfikat bazowy
+Name[pt]=Certificado Raiz de Confiança
+Name[pt_BR]=Certificado Raiz Confiável
+Name[ru]=ДоверÑемый корневой Ñертификат
+Name[se]=Luohttehahtti ruohtassertifikáhta
+Name[sk]=Dôveryhodný koreňový certifikát
+Name[sl]=Zaupan korenski certifikat
+Name[sr]=Корени Ñертификат од поверења
+Name[sr@Latn]=Koreni sertifikat od poverenja
+Name[sv]=PÃ¥litligt rotcertifikat
+Name[ta]=நமà¯à®ªà®•à®®à®¾à®© மூல சானà¯à®±à®¿à®¤à®´à¯
+Name[tr]=Güvenilir Kök Sertifikası
+Name[uk]=Кореневий Ñертифікат з довірою
+Name[zh_CN]=å¯ä¿¡ä»»çš„æ ¹è¯ä¹¦
+Name[zh_TW]=å¯ä¿¡ä»»çš„根憑證
+
+[Key Filter #4]
+was-validated=true
+is-root-certificate=true
+is-not-validity=ultimate
+Name=Not Trusted Root Certificate
+Name[af]=Nie vertroude 'root' sertifikaat
+Name[ar]=شهادة جذر غير موثوق بها
+Name[bg]=Ðенадеждно удоÑтоверение
+Name[ca]=Certificat arrel sense confiança
+Name[cs]=Nedůvěryhodný kořenový certifikát
+Name[da]=Root-certifikat der ikke stoles på
+Name[de]=Nicht vertrauenswürdiges Stammzertifikat
+Name[el]=Μη έμπιστο βασικό πιστοποιητικό
+Name[eo]=Ne Fidinda Radika Certifikato
+Name[es]=Certificado raíz no de confianza
+Name[et]=Ebausaldusväärne juursertifikaat
+Name[eu]=Konfidantza gabeko erro ziurtagiria
+Name[fa]=گواهی‌نامۀ بدون اعتبار کاربر ارشد
+Name[fi]=Ei-luotettu juurivarmenne
+Name[fr]=Certificat racine non fiable
+Name[fy]=Net fertroude haadsertifikaat
+Name[gl]=Certificado raiz non autentificado
+Name[hu]=Nem megbízható gyökértanúsítvány
+Name[is]=Ekki traust rótarskilríki
+Name[it]=Certificato radice non affidabile
+Name[ja]=ä¿¡é ¼ã•ã‚Œã¦ãªã„ルート証明書
+Name[ka]=რუტის áƒáƒ áƒáƒ¡áƒáƒœáƒ“რსერტიფიკáƒáƒ¢áƒ˜
+Name[kk]=Сенім артылмаған түбір куәлігі
+Name[km]=វិញ្ញាបនបážáŸ’ážš Root ដែល​មិន​អាច​ជឿទុកចិážáŸ’áž
+Name[lt]=Nepatikimas root sertifikatas
+Name[mk]=Ðедоверлив коренов Ñертификат
+Name[ms]=Sijil Root Tak Dipercaya
+Name[nb]=Ikke tiltrodd rot-sertifikat
+Name[nds]=Nich vertroonswöördig Wörtelzertifikaat
+Name[ne]=विशà¥à¤µà¤¾à¤¸ नगरिà¤à¤•à¤¾ मूल पà¥à¤°à¤®à¤¾à¤£à¤ªà¤¤à¥à¤°
+Name[nl]=Niet vertrouwd hoofdcertificaat
+Name[nn]=Ikkje tiltrudd rotsertifikat
+Name[pl]=Nie zaufany certyfikat bazowy
+Name[pt]=Certificado Raiz Não de Confiança
+Name[pt_BR]=Certificado Raiz Não-Confiável
+Name[ru]=Ðе доверÑемый корневой Ñертификат
+Name[se]=Ii luohttehahtti ruohtassertifikáhta
+Name[sk]=Nedôveryhodný koreňový certifikát
+Name[sl]=Nezaupan korenski certifikat
+Name[sr]=Корени Ñертификат који није од поверења
+Name[sr@Latn]=Koreni sertifikat koji nije od poverenja
+Name[sv]=Opålitligt rotcertifikat
+Name[ta]=நமà¯à®ªà®®à¯à®Ÿà®¿à®¯à®¾à®¤ மூல சானà¯à®±à®¿à®¤à®´à¯
+Name[tr]=Güvenilmeyen Kök Sertifikası
+Name[uk]=Кореневий Ñертифікат без довіри
+Name[zh_CN]=未信任的根è¯ä¹¦
+Name[zh_TW]=ä¸å¯ä¿¡ä»»çš„根憑證
+
+[Key Filter #5]
+was-validated=true
+Name=Other Keys
+Name[af]=Ander Sleutels
+Name[ar]=Ù…Ùاتيح آخرى
+Name[bg]=Други ключове
+Name[br]=Alc'hwezioù all
+Name[ca]=Altres claus
+Name[cs]=Ostatní klíÄe
+Name[da]=Andre nøgler
+Name[de]=Andere Schlüssel
+Name[el]=Άλλα κλειδιά
+Name[eo]=Aliaj Åœlosiloj
+Name[es]=Otras claves
+Name[et]=Muud võtmed
+Name[eu]=Beste gakoak
+Name[fa]=کلیدهای دیگر
+Name[fi]=Muut avaimet
+Name[fr]=Autres clés
+Name[fy]=Oare kaaien
+Name[ga]=Eochracha Eile
+Name[gl]=Outras chaves
+Name[he]=מפתחות ×חרי×
+Name[hu]=Egyéb kulcsok
+Name[is]=Aðrir lyklar
+Name[it]=Altre chiavi
+Name[ja]=ä»–ã®éµ
+Name[ka]=სხვრგáƒáƒ¡áƒáƒ¦áƒ”ბები
+Name[kk]=БаÑқа кілттер
+Name[km]=កូនសោ​ផ្សáŸáž„​ទៀáž
+Name[ko]=기타 키
+Name[lt]=Kiti raktai
+Name[mk]=Други клучеви
+Name[ms]=Kekunci Lain
+Name[nb]=Andre nøkler
+Name[nds]=Anner Slötels
+Name[ne]=अनà¥à¤¯ कà¥à¤žà¥à¤œà¥€
+Name[nl]=Andere sleutels
+Name[nn]=Andre nøklar
+Name[pa]=ਹੋਰ ਕà©à©°à¨œà©€à¨†à¨‚
+Name[pl]=Inne klucze
+Name[pt]=Outras Chaves
+Name[pt_BR]=Outras Chaves
+Name[ru]=Другие ключи
+Name[se]=Eará Äoavdagat
+Name[sk]=Iné kľúÄe
+Name[sl]=Drugi kljuÄi
+Name[sr]=Други кључеви
+Name[sr@Latn]=Drugi kljuÄevi
+Name[sv]=Andra nycklar
+Name[ta]=மறà¯à®± விசைகளà¯
+Name[tr]=DiÄŸer Anahtarlar
+Name[uk]=Інші ключі
+Name[uz]=Boshqa kalitlar
+Name[uz@cyrillic]=Бошқа калитлар
+Name[zh_CN]=其它密钥
+Name[zh_TW]=其他金鑰
+
diff --git a/certmanager/lib/pics/Makefile.am b/certmanager/lib/pics/Makefile.am
new file mode 100644
index 000000000..33704d1b2
--- /dev/null
+++ b/certmanager/lib/pics/Makefile.am
@@ -0,0 +1,4 @@
+picsdir = $(kde_datadir)/libkleopatra/pics
+pics_DATA = key.png key_ok.png key_bad.png key_unknown.png chiasmus_chi.png
+
+KDE_ICON = gpg gpgsm
diff --git a/certmanager/lib/pics/chiasmus_chi.png b/certmanager/lib/pics/chiasmus_chi.png
new file mode 100644
index 000000000..cd1d17cd5
--- /dev/null
+++ b/certmanager/lib/pics/chiasmus_chi.png
Binary files differ
diff --git a/certmanager/lib/pics/cr16-app-gpg.png b/certmanager/lib/pics/cr16-app-gpg.png
new file mode 100644
index 000000000..04a05c1cb
--- /dev/null
+++ b/certmanager/lib/pics/cr16-app-gpg.png
Binary files differ
diff --git a/certmanager/lib/pics/cr16-app-gpgsm.png b/certmanager/lib/pics/cr16-app-gpgsm.png
new file mode 100644
index 000000000..04a05c1cb
--- /dev/null
+++ b/certmanager/lib/pics/cr16-app-gpgsm.png
Binary files differ
diff --git a/certmanager/lib/pics/cr22-app-gpg.png b/certmanager/lib/pics/cr22-app-gpg.png
new file mode 100644
index 000000000..351df8709
--- /dev/null
+++ b/certmanager/lib/pics/cr22-app-gpg.png
Binary files differ
diff --git a/certmanager/lib/pics/cr22-app-gpgsm.png b/certmanager/lib/pics/cr22-app-gpgsm.png
new file mode 100644
index 000000000..351df8709
--- /dev/null
+++ b/certmanager/lib/pics/cr22-app-gpgsm.png
Binary files differ
diff --git a/certmanager/lib/pics/cr32-app-gpg.png b/certmanager/lib/pics/cr32-app-gpg.png
new file mode 100644
index 000000000..f6db91460
--- /dev/null
+++ b/certmanager/lib/pics/cr32-app-gpg.png
Binary files differ
diff --git a/certmanager/lib/pics/cr32-app-gpgsm.png b/certmanager/lib/pics/cr32-app-gpgsm.png
new file mode 100644
index 000000000..f6db91460
--- /dev/null
+++ b/certmanager/lib/pics/cr32-app-gpgsm.png
Binary files differ
diff --git a/certmanager/lib/pics/key.png b/certmanager/lib/pics/key.png
new file mode 100644
index 000000000..2da8bd755
--- /dev/null
+++ b/certmanager/lib/pics/key.png
Binary files differ
diff --git a/certmanager/lib/pics/key_bad.png b/certmanager/lib/pics/key_bad.png
new file mode 100644
index 000000000..1e0f8ca18
--- /dev/null
+++ b/certmanager/lib/pics/key_bad.png
Binary files differ
diff --git a/certmanager/lib/pics/key_ok.png b/certmanager/lib/pics/key_ok.png
new file mode 100644
index 000000000..3fa7e6f0d
--- /dev/null
+++ b/certmanager/lib/pics/key_ok.png
Binary files differ
diff --git a/certmanager/lib/pics/key_unknown.png b/certmanager/lib/pics/key_unknown.png
new file mode 100644
index 000000000..ee3f542e2
--- /dev/null
+++ b/certmanager/lib/pics/key_unknown.png
Binary files differ
diff --git a/certmanager/lib/tests/Makefile.am b/certmanager/lib/tests/Makefile.am
new file mode 100644
index 000000000..3fa819f76
--- /dev/null
+++ b/certmanager/lib/tests/Makefile.am
@@ -0,0 +1,20 @@
+AM_CPPFLAGS = -I$(top_srcdir)/certmanager/lib \
+ -I$(top_srcdir)/libkdenetwork \
+ $(GPGME_CFLAGS) $(all_includes) -DKDESRCDIR=\"$(srcdir)\"
+
+check_PROGRAMS = test_keylister test_keygen test_keyselectiondialog \
+ test_cryptoconfig test_gnupgprocessbase test_jobs test_verify
+TESTS = test_verify
+
+test_keylister_SOURCES = test_keylister.cpp
+test_keygen_SOURCES = test_keygen.cpp
+test_keyselectiondialog_SOURCES = test_keyselectiondialog.cpp
+test_cryptoconfig_SOURCES = test_cryptoconfig.cpp
+test_gnupgprocessbase_SOURCES = test_gnupgprocessbase.cpp
+test_jobs_SOURCES = test_jobs.cpp
+test_verify_SOURCES = test_verify.cpp
+
+LDADD = ../libkleopatra.la
+
+METASOURCES = AUTO
+
diff --git a/certmanager/lib/tests/gnupg_home/pubring.gpg b/certmanager/lib/tests/gnupg_home/pubring.gpg
new file mode 100644
index 000000000..5b9b35b1b
--- /dev/null
+++ b/certmanager/lib/tests/gnupg_home/pubring.gpg
Binary files differ
diff --git a/certmanager/lib/tests/gnupg_home/secring.gpg b/certmanager/lib/tests/gnupg_home/secring.gpg
new file mode 100644
index 000000000..1556bbdac
--- /dev/null
+++ b/certmanager/lib/tests/gnupg_home/secring.gpg
Binary files differ
diff --git a/certmanager/lib/tests/gnupg_home/trustdb.gpg b/certmanager/lib/tests/gnupg_home/trustdb.gpg
new file mode 100644
index 000000000..37cc64fd9
--- /dev/null
+++ b/certmanager/lib/tests/gnupg_home/trustdb.gpg
Binary files differ
diff --git a/certmanager/lib/tests/gnupgviewer.h b/certmanager/lib/tests/gnupgviewer.h
new file mode 100644
index 000000000..efba1760b
--- /dev/null
+++ b/certmanager/lib/tests/gnupgviewer.h
@@ -0,0 +1,64 @@
+/*
+ gnupgviewer.h
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_TESTS_GNUPGVIEWER_H__
+#define __KLEO_TESTS_GNUPGVIEWER_H__
+
+#include <qtextedit.h>
+#include <qstring.h>
+
+namespace Kleo {
+ class GnuPGProcessBase;
+}
+class KProcess;
+class QStringList;
+
+class GnuPGViewer : public QTextEdit {
+ Q_OBJECT
+public:
+ GnuPGViewer( QWidget * parent=0, const char * name=0 );
+ ~GnuPGViewer();
+
+ void setProcess( Kleo::GnuPGProcessBase * process );
+
+private slots:
+ void slotStdout( KProcess *, char *, int );
+ void slotStderr( KProcess *, char *, int );
+ void slotStatus( Kleo::GnuPGProcessBase *, const QString &, const QStringList & );
+ void slotProcessExited( KProcess * );
+
+private:
+ Kleo::GnuPGProcessBase * mProcess;
+ QString mLastStdout, mLastStderr, mLastStatus;
+};
+
+#endif // __KLEO_TESTS_GNUPGVIEWER_H__
diff --git a/certmanager/lib/tests/test.data b/certmanager/lib/tests/test.data
new file mode 100644
index 000000000..b4bce1a93
--- /dev/null
+++ b/certmanager/lib/tests/test.data
@@ -0,0 +1,295 @@
+/* -*- mode: c++; c-basic-offset:4 -*-
+ tests/test_uiserver.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2007 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+//
+// Usage: test_uiserver <socket> --verify-detached <signed data> <signature>
+//
+#ifndef _ASSUAN_ONLY_GPG_ERRORS
+#define _ASSUAN_ONLY_GPG_ERRORS
+#endif
+#include "../uiserver/kleo-assuan.h"
+#include <gpg-error.h>
+
+#include <QtCore>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+#include <iostream>
+#include <map>
+#include <string>
+#include <vector>
+
+using namespace Kleo;
+
+static std::vector<int> inFDs, outFDs, msgFDs;
+static std::vector<std::string> inFiles, outFiles, msgFiles;
+static std::map<std::string,std::string> inquireData;
+
+static std::string hexencode( const std::string & in ) {
+ std::string result;
+ result.reserve( 3 * in.size() );
+
+ static const char hex[] = "0123456789ABCDEF";
+
+ for ( std::string::const_iterator it = in.begin(), end = in.end() ; it != end ; ++it )
+ switch ( const unsigned char ch = *it ) {
+ default:
+ if ( ch >= '!' && ch <= '~' || ch > 0xA0 ) {
+ result += ch;
+ break;
+ }
+ // else fall through
+ case ' ':
+ result += '+';
+ break;
+ case '"':
+ case '#':
+ case '$':
+ case '%':
+ case '\'':
+ case '+':
+ case '=':
+ result += '%';
+ result += hex[ (ch & 0xF0) >> 4 ];
+ result += hex[ (ch & 0x0F) ];
+ break;
+ }
+
+ return result;
+}
+
+static void usage( const std::string & msg=std::string() ) {
+ std::cerr << msg << std::endl <<
+ "\n"
+ "Usage: test_uiserver <socket> [<io>] [<options>] [<inquire>] command [<args>]\n"
+ "where:\n"
+ " <io>: [--input[-fd] <file>] [--output[-fd] <file>] [--message[-fd] <file>]\n"
+ " <options>: *[--option name=value]\n"
+ " <inquire>: [--inquire keyword=<file>]\n";
+ exit( 1 );
+}
+
+static int data( void * void_ctx, const void * buffer, size_t len ) {
+ (void)void_ctx; (void)buffer; (void)len;
+ return 0; // ### implement me
+}
+
+static int status( void * void_ctx, const char * line ) {
+ (void)void_ctx; (void)line;
+ return 0;
+}
+
+static int inquire( void * void_ctx, const char * keyword ) {
+ assuan_context_t ctx = (assuan_context_t)void_ctx;
+ assert( ctx );
+ const std::map<std::string,std::string>::const_iterator it = inquireData.find( keyword );
+ if ( it == inquireData.end() )
+ return gpg_error( GPG_ERR_UNKNOWN_COMMAND );
+
+ if ( !it->second.empty() && it->second[0] == '@' )
+ return gpg_error( GPG_ERR_NOT_IMPLEMENTED );
+
+ if ( const gpg_error_t err = assuan_send_data( ctx, it->second.c_str(), it->second.size() ) ) {
+ qDebug( "assuan_write_data: %s", gpg_strerror( err ) );
+ return err;
+ }
+
+ return 0;
+}
+
+int main( int argc, char * argv[] ) {
+
+ assuan_set_assuan_err_source( GPG_ERR_SOURCE_DEFAULT );
+
+ if ( argc < 3 )
+ usage(); // need socket and command, at least
+
+ const char * socket = argv[1];
+
+ std::vector<const char*> options;
+
+ std::string command;
+ for ( int optind = 2 ; optind < argc ; ++optind ) {
+ const char * const arg = argv[optind];
+ if ( qstrcmp( arg, "--input-fd" ) == 0 ) {
+ int inFD;
+ if ( (inFD = open( argv[++optind], O_RDONLY )) == -1 ) {
+ perror( "--input-fd open()" );
+ return 1;
+ }
+ inFDs.push_back( inFD );
+ } else if ( qstrcmp( arg, "--output-fd" ) == 0 ) {
+ int outFD;
+ if ( (outFD = open( argv[++optind], O_WRONLY|O_CREAT )) == -1 ) {
+ perror( "--output-fd open()" );
+ return 1;
+ }
+ outFDs.push_back( outFD );
+ } else if ( qstrcmp( arg, "--message-fd" ) == 0 ) {
+ int msgFD;
+ if ( (msgFD = open( argv[++optind], O_RDONLY )) == -1 ) {
+ perror( "--message-fd open()" );
+ return 1;
+ }
+ msgFDs.push_back( msgFD );
+ } else if ( qstrcmp( arg, "--input" ) == 0 ) {
+ const std::string file = argv[++optind];
+ inFiles.push_back( file );
+ } else if ( qstrcmp( arg, "--output" ) == 0 ) {
+ const std::string file = argv[++optind];
+ outFiles.push_back( file );
+ } else if ( qstrcmp( arg, "--message" ) == 0 ) {
+ const std::string file = argv[++optind];
+ msgFiles.push_back( file );
+ } else if ( qstrcmp( arg, "--option" ) == 0 ) {
+ options.push_back( argv[++optind] );
+ } else if ( qstrcmp( arg, "--inquire" ) == 0 ) {
+ const std::string inqval = argv[++optind];
+ const size_t pos = inqval.find( '=' );
+ // ### implement indirection with "@file"...
+ inquireData[inqval.substr( 0, pos )] = inqval.substr( pos+1 );
+ } else {
+ while ( optind < argc ) {
+ if ( !command.empty() )
+ command += ' ';
+ command += argv[optind++];
+ }
+ }
+ }
+ if ( command.empty() )
+ usage( "Command expected, but only options found" );
+
+ assuan_context_t ctx = 0;
+
+ if ( const gpg_error_t err = assuan_socket_connect_ext( &ctx, socket, -1, 1 ) ) {
+ qDebug( "%s", assuan_exception( err, "assuan_socket_connect_ext" ).what() );
+ return 1;
+ }
+
+ assuan_set_log_stream( ctx, stderr );
+
+ for ( std::vector<int>::const_iterator it = inFDs.begin(), end = inFDs.end() ; it != end ; ++it ) {
+ if ( const gpg_error_t err = assuan_sendfd( ctx, *it ) ) {
+ qDebug( "%s", assuan_exception( err, "assuan_sendfd( inFD )" ).what() );
+ return 1;
+ }
+
+ if ( const gpg_error_t err = assuan_transact( ctx, "INPUT FD", 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, "INPUT FD" ).what() );
+ return 1;
+ }
+ }
+
+
+ for ( std::vector<std::string>::const_iterator it = inFiles.begin(), end = inFiles.end() ; it != end ; ++it ) {
+ char buffer[1024];
+ sprintf( buffer, "INPUT FILE=%s", hexencode( *it ).c_str() );
+
+ if ( const gpg_error_t err = assuan_transact( ctx, buffer, 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, buffer ).what() );
+ return 1;
+ }
+ }
+
+
+ for ( std::vector<int>::const_iterator it = msgFDs.begin(), end = msgFDs.end() ; it != end ; ++it ) {
+ if ( const gpg_error_t err = assuan_sendfd( ctx, *it ) ) {
+ qDebug( "%s", assuan_exception( err, "assuan_sendfd( msgFD )" ).what() );
+ return 1;
+ }
+
+ if ( const gpg_error_t err = assuan_transact( ctx, "MESSAGE FD", 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, "MESSAGE FD" ).what() );
+ return 1;
+ }
+ }
+
+
+ for ( std::vector<std::string>::const_iterator it = msgFiles.begin(), end = msgFiles.end() ; it != end ; ++it ) {
+ char buffer[1024];
+ sprintf( buffer, "MESSAGE FILE=%s", hexencode( *it ).c_str() );
+
+ if ( const gpg_error_t err = assuan_transact( ctx, buffer, 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, buffer ).what() );
+ return 1;
+ }
+ }
+
+
+ for ( std::vector<int>::const_iterator it = outFDs.begin(), end = outFDs.end() ; it != end ; ++it ) {
+ if ( const gpg_error_t err = assuan_sendfd( ctx, *it ) ) {
+ qDebug( "%s", assuan_exception( err, "assuan_sendfd( outFD )" ).what() );
+ return 1;
+ }
+
+ if ( const gpg_error_t err = assuan_transact( ctx, "OUTPUT FD", 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, "OUTPUT FD" ).what() );
+ return 1;
+ }
+ }
+
+
+ for ( std::vector<std::string>::const_iterator it = outFiles.begin(), end = outFiles.end() ; it != end ; ++it ) {
+ char buffer[1024];
+ sprintf( buffer, "OUTPUT FILE=%s", hexencode( *it ).c_str() );
+
+ if ( const gpg_error_t err = assuan_transact( ctx, buffer, 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, buffer ).what() );
+ return 1;
+ }
+ }
+
+
+
+ Q_FOREACH( const char * opt, options ) {
+ std::string line = "OPTION ";
+ line += opt;
+ if ( const gpg_error_t err = assuan_transact( ctx, line.c_str(), 0, 0, 0, 0, 0, 0 ) ) {
+ qDebug( "%s", assuan_exception( err, line ).what() );
+ return 1;
+ }
+ }
+
+ if ( const gpg_error_t err = assuan_transact( ctx, command.c_str(), data, ctx, inquire, ctx, status, ctx ) ) {
+ qDebug( "%s", assuan_exception( err, command ).what() );
+ return 1;
+ }
+
+ assuan_disconnect( ctx );
+
+ return 0;
+}
diff --git a/certmanager/lib/tests/test.data.gpg b/certmanager/lib/tests/test.data.gpg
new file mode 100644
index 000000000..2e1d7d161
--- /dev/null
+++ b/certmanager/lib/tests/test.data.gpg
Binary files differ
diff --git a/certmanager/lib/tests/test.data.sig b/certmanager/lib/tests/test.data.sig
new file mode 100644
index 000000000..4e2713752
--- /dev/null
+++ b/certmanager/lib/tests/test.data.sig
Binary files differ
diff --git a/certmanager/lib/tests/test_cryptoconfig.cpp b/certmanager/lib/tests/test_cryptoconfig.cpp
new file mode 100644
index 000000000..17d1b4471
--- /dev/null
+++ b/certmanager/lib/tests/test_cryptoconfig.cpp
@@ -0,0 +1,365 @@
+/*
+ test_cryptoconfig.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include <backends/qgpgme/qgpgmecryptoconfig.h>
+
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <iostream>
+using namespace std;
+
+#include <stdlib.h>
+#include <assert.h>
+
+int main( int argc, char** argv ) {
+
+ KAboutData aboutData( "test_cryptoconfig", "CryptoConfig Test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app( false, false );
+
+ Kleo::CryptoConfig * config = new QGpgMECryptoConfig();
+
+ // Dynamic querying of the options
+ cout << "Components:" << endl;
+ QStringList components = config->componentList();
+
+ for( QStringList::Iterator compit = components.begin(); compit != components.end(); ++compit ) {
+ cout << "Component " << (*compit).local8Bit() << ":" << endl;
+ const Kleo::CryptoConfigComponent* comp = config->component( *compit );
+ assert( comp );
+ QStringList groups = comp->groupList();
+ for( QStringList::Iterator groupit = groups.begin(); groupit != groups.end(); ++groupit ) {
+ const Kleo::CryptoConfigGroup* group = comp->group( *groupit );
+ assert( group );
+ cout << " Group " << (*groupit).local8Bit() << ": descr=\"" << group->description().local8Bit() << "\""
+ << " level=" << group->level() << endl;
+ QStringList entries = group->entryList();
+ for( QStringList::Iterator entryit = entries.begin(); entryit != entries.end(); ++entryit ) {
+ const Kleo::CryptoConfigEntry* entry = group->entry( *entryit );
+ assert( entry );
+ cout << " Entry " << (*entryit).local8Bit() << ":"
+ << " descr=\"" << entry->description().local8Bit() << "\""
+ << " " << ( entry->isSet() ? "is set" : "is not set" );
+ if ( !entry->isList() )
+ switch( entry->argType() ) {
+ case Kleo::CryptoConfigEntry::ArgType_None:
+ break;
+ case Kleo::CryptoConfigEntry::ArgType_Int:
+ cout << " int value=" << entry->intValue();
+ break;
+ case Kleo::CryptoConfigEntry::ArgType_UInt:
+ cout << " uint value=" << entry->uintValue();
+ break;
+ case Kleo::CryptoConfigEntry::ArgType_LDAPURL:
+ case Kleo::CryptoConfigEntry::ArgType_URL:
+ cout << " URL value=" << entry->urlValue().prettyURL().local8Bit();
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_Path:
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_DirPath:
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_String:
+
+ cout << " string value=" << entry->stringValue().local8Bit();
+ break;
+ }
+ else // lists
+ {
+ switch( entry->argType() ) {
+ case Kleo::CryptoConfigEntry::ArgType_None: {
+ cout << " set " << entry->numberOfTimesSet() << " times";
+ break;
+ }
+ case Kleo::CryptoConfigEntry::ArgType_Int: {
+ assert( entry->isOptional() ); // empty lists must be allowed (see issue121)
+ QValueList<int> lst = entry->intValueList();
+ QString str;
+ for( QValueList<int>::Iterator it = lst.begin(); it != lst.end(); ++it ) {
+ str += QString::number( *it );
+ }
+ cout << " int values=" << str.local8Bit();
+ break;
+ }
+ case Kleo::CryptoConfigEntry::ArgType_UInt: {
+ assert( entry->isOptional() ); // empty lists must be allowed (see issue121)
+ QValueList<uint> lst = entry->uintValueList();
+ QString str;
+ for( QValueList<uint>::Iterator it = lst.begin(); it != lst.end(); ++it ) {
+ str += QString::number( *it );
+ }
+ cout << " uint values=" << str.local8Bit();
+ break;
+ }
+ case Kleo::CryptoConfigEntry::ArgType_LDAPURL:
+ case Kleo::CryptoConfigEntry::ArgType_URL: {
+ assert( entry->isOptional() ); // empty lists must be allowed (see issue121)
+ KURL::List urls = entry->urlValueList();
+ cout << " url values=" << urls.toStringList().join(" ").local8Bit() << "\n ";
+ }
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_Path:
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_DirPath:
+ // fallthrough
+ case Kleo::CryptoConfigEntry::ArgType_String: {
+ assert( entry->isOptional() ); // empty lists must be allowed (see issue121)
+ QStringList lst = entry->stringValueList();
+ cout << " string values=" << lst.join(" ").local8Bit();
+ break;
+ }
+ }
+ }
+ cout << endl;
+ }
+ // ...
+ }
+ }
+
+ {
+ // Static querying of a single boolean option
+ static const char* s_groupName = "Monitor";
+ static const char* s_entryName = "quiet";
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ if ( entry ) {
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None );
+ bool val = entry->boolValue();
+ cout << "quiet option initially: " << ( val ? "is set" : "is not set" ) << endl;
+
+ entry->setBoolValue( !val );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ // Clear cached values!
+ config->clear();
+
+ // Check new value
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( entry );
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None );
+ cout << "quiet option now: " << ( val ? "is set" : "is not set" ) << endl;
+ assert( entry->boolValue() == !val );
+
+ // Set to default
+ entry->resetToDefault();
+ assert( entry->boolValue() == false ); // that's the default
+ assert( entry->isDirty() );
+ assert( !entry->isSet() );
+ config->sync( true );
+ config->clear();
+
+ // Check value
+ entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( !entry->isDirty() );
+ assert( !entry->isSet() );
+ cout << "quiet option reset to default: " << ( entry->boolValue() ? "is set" : "is not set" ) << endl;
+ assert( entry->boolValue() == false );
+
+ // Reset old value
+ entry->setBoolValue( val );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ cout << "quiet option reset to initial: " << ( val ? "is set" : "is not set" ) << endl;
+ }
+ else
+ cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl;
+ }
+
+ {
+ // Static querying and setting of a single int option
+ static const char* s_groupName = "LDAP";
+ static const char* s_entryName = "ldaptimeout";
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ if ( entry ) {
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt );
+ uint val = entry->uintValue();
+ cout << "LDAP timeout initially: " << val << " seconds." << endl;
+
+ // Test setting the option directly, then querying again
+ //system( "echo 'ldaptimeout:0:101' | gpgconf --change-options dirmngr" );
+ // Now let's do it with the C++ API instead
+ entry->setUIntValue( 101 );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ // Clear cached values!
+ config->clear();
+
+ // Check new value
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( entry );
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt );
+ cout << "LDAP timeout now: " << entry->uintValue() << " seconds." << endl;
+ assert( entry->uintValue() == 101 );
+
+ // Set to default
+ entry->resetToDefault();
+ assert( entry->uintValue() == 100 );
+ assert( entry->isDirty() );
+ assert( !entry->isSet() );
+ config->sync( true );
+ config->clear();
+
+ // Check value
+ entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( !entry->isDirty() );
+ assert( !entry->isSet() );
+ cout << "LDAP timeout reset to default, " << entry->uintValue() << " seconds." << endl;
+ assert( entry->uintValue() == 100 );
+
+ // Reset old value
+ entry->setUIntValue( val );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ cout << "LDAP timeout reset to initial " << val << " seconds." << endl;
+ }
+ else
+ cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl;
+ }
+
+ {
+ // Static querying and setting of a single string option
+ static const char* s_groupName = "Debug";
+ static const char* s_entryName = "log-file";
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ if ( entry ) {
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Path );
+ QString val = entry->stringValue();
+ cout << "Log-file initially: " << val.local8Bit() << endl;
+
+ // Test setting the option, sync'ing, then querying again
+ entry->setStringValue( QString::fromUtf8( "/tmp/test:%e5ä" ) );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ // Let's see how it prints it
+ system( "gpgconf --list-options dirmngr | grep log-file" );
+
+ // Clear cached values!
+ config->clear();
+
+ // Check new value
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( entry );
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Path );
+ cout << "Log-file now: " << entry->stringValue().local8Bit() << endl;
+ assert( entry->stringValue() == QString::fromUtf8( "/tmp/test:%e5ä" ) ); // (or even with %e5 decoded)
+
+ // Reset old value
+#if 0
+ QString arg( val );
+ if ( !arg.isEmpty() )
+ arg.prepend( '"' );
+ QCString sys;
+ sys.sprintf( "echo 'log-file:%s' | gpgconf --change-options dirmngr", arg.local8Bit().data() );
+ system( sys.data() );
+#endif
+ entry->setStringValue( val );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ cout << "Log-file reset to initial " << val.local8Bit() << endl;
+ }
+ else
+ cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl;
+ }
+
+ {
+ // Static querying and setting of the LDAP URL list option
+ static const char* s_groupName = "LDAP";
+ static const char* s_entryName = "LDAP Server";
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ if ( entry ) {
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL );
+ assert( entry->isList() );
+ KURL::List val = entry->urlValueList();
+ cout << "URL list initially: " << val.toStringList().join(", ").local8Bit() << endl;
+
+ // Test setting the option, sync'ing, then querying again
+ KURL::List lst;
+ // We use non-empty paths to workaround a bug in KURL (kdelibs-3.2)
+ lst << KURL( "ldap://a:389/?b" );
+ // Test with query containing a litteral ':' (KURL supports this)
+ // and a ' ' (KURL will escape it, see issue119)
+ lst << KURL( "ldap://foo:389/?a:b c" );
+ lst << KURL( "ldap://server:389/?a%3db,c=DE" ); // the query contains a litteral ','
+ //cout << " trying to set: " << lst.toStringList().join(", ").local8Bit() << endl;
+ assert( lst[0].query() == "?b" );
+ assert( lst[1].query() == "?a:b%20c" ); // see, the space got escaped
+ entry->setURLValueList( lst );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ // Let's see how it prints it
+ system( "gpgconf --list-options dirmngr | grep 'LDAP Server'" );
+
+ // Clear cached values!
+ config->clear();
+
+ // Check new value
+ Kleo::CryptoConfigEntry* entry = config->entry( "dirmngr", s_groupName, s_entryName );
+ assert( entry );
+ assert( entry->argType() == Kleo::CryptoConfigEntry::ArgType_LDAPURL );
+ assert( entry->isList() );
+ // Get raw a:b:c:d:e form
+ QStringList asStringList = entry->stringValueList();
+ assert( asStringList.count() == 3 );
+ cout << "asStringList[0]=" << asStringList[0].local8Bit() << endl;
+ cout << "asStringList[1]=" << asStringList[1].local8Bit() << endl;
+ cout << "asStringList[2]=" << asStringList[2].local8Bit() << endl;
+ assert( asStringList[0] == "a:389:::b" );
+ assert( asStringList[1] == "foo:389:::a%3ab c" ); // the space must be decoded (issue119)
+ assert( asStringList[2] == "server:389:::a=b,c=DE" ); // all decoded
+ // Get KURL form
+ KURL::List newlst = entry->urlValueList();
+ cout << "URL list now: " << newlst.toStringList().join(", ").local8Bit() << endl;
+ assert( newlst.count() == 3 );
+ //cout << "newlst[0]=" << newlst[0].url().local8Bit() << endl;
+ //cout << "lst[0]=" << lst[0].url().local8Bit() << endl;
+ assert( newlst[0] == lst[0] );
+ assert( newlst[1] == lst[1] );
+ assert( newlst[2].url() == "ldap://server:389/?a=b,c=DE" ); // != lst[2] due to the encoded =
+
+ // Reset old value
+ entry->setURLValueList( val );
+ assert( entry->isDirty() );
+ config->sync( true );
+
+ cout << "URL list reset to initial: " << val.toStringList().join(", ").local8Bit() << endl;
+ }
+ else
+ cout << "Entry 'dirmngr/" << s_groupName << "/" << s_entryName << "' not found" << endl;
+ }
+
+ cout << "Done." << endl;
+}
diff --git a/certmanager/lib/tests/test_gnupgprocessbase.cpp b/certmanager/lib/tests/test_gnupgprocessbase.cpp
new file mode 100644
index 000000000..37e961801
--- /dev/null
+++ b/certmanager/lib/tests/test_gnupgprocessbase.cpp
@@ -0,0 +1,143 @@
+/*
+ gnupgviewer.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gnupgviewer.h"
+
+#include <backends/qgpgme/gnupgprocessbase.h>
+
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+#include <qstringlist.h>
+
+GnuPGViewer::GnuPGViewer( QWidget * parent, const char * name )
+ : QTextEdit( parent, name ), mProcess( 0 )
+{
+ setTextFormat( LogText );
+ setMaxLogLines( 10000 );
+}
+
+GnuPGViewer::~GnuPGViewer() {
+ if ( mProcess )
+ mProcess->kill();
+}
+
+void GnuPGViewer::setProcess( Kleo::GnuPGProcessBase * process ) {
+ if ( !process )
+ return;
+ mProcess = process;
+ connect( mProcess, SIGNAL(processExited(KProcess*)),
+ SLOT(slotProcessExited(KProcess*)) );
+ connect( mProcess, SIGNAL(receivedStdout(KProcess*,char*,int)),
+ SLOT(slotStdout(KProcess*,char*,int)) );
+ connect( mProcess, SIGNAL(receivedStderr(KProcess*,char*,int)),
+ SLOT(slotStderr(KProcess*,char*,int)) );
+ connect( mProcess, SIGNAL(status(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)),
+ SLOT(slotStatus(Kleo::GnuPGProcessBase*,const QString&,const QStringList&)) );
+}
+
+static QStringList split( char * buffer, int buflen, QString & old ) {
+ // when done right, this would need to use QTextCodec...
+ const QString str = old + QString::fromLocal8Bit( buffer, buflen );
+ QStringList l = QStringList::split( '\n', str, true );
+ if ( l.empty() )
+ return l;
+ if ( str.endsWith( "\n" ) ) {
+ old = QString::null;
+ } else {
+ old = l.back();
+ l.pop_back();
+ }
+ return l;
+}
+
+static QString escape( QString str ) {
+ return str.replace( '&', "&amp" ).replace( '<', "&lt;" ).replace( '>', "&gt;" );
+}
+
+void GnuPGViewer::slotStdout( KProcess *, char * buffer, int buflen ) {
+ const QStringList l = split( buffer, buflen, mLastStdout );
+ for ( QStringList::const_iterator it = l.begin() ; it != l.end() ; ++it )
+ append( "stdout: " + escape( *it ) );
+}
+
+void GnuPGViewer::slotStderr( KProcess *, char * buffer, int buflen ) {
+ const QStringList l = split( buffer, buflen, mLastStderr );
+ for ( QStringList::const_iterator it = l.begin() ; it != l.end() ; ++it )
+ append( "<b>stderr: " + escape( *it ) + "</b>" );
+}
+void GnuPGViewer::slotStatus( Kleo::GnuPGProcessBase *, const QString & type, const QStringList & args ) {
+ append( "<b><font color=\"red\">status: " + escape( type + ' ' + args.join( " " ) ) + "</font></b>" );
+}
+void GnuPGViewer::slotProcessExited( KProcess * proc ) {
+ if ( !proc )
+ return;
+ if ( proc->normalExit() )
+ append( QString( "<b>Process exit: return code %1</b>" ).arg ( proc->exitStatus() ) );
+ else
+ append( "<b>Process exit: killed</b>" );
+}
+
+int main( int argc, char** argv ) {
+ if ( argc < 3 ) {
+ kdDebug() << "Need at least two arguments" << endl;
+ return 1;
+ }
+ KAboutData aboutData( "test_gnupgprocessbase", "GnuPGProcessBase Test", "0.1" );
+ KCmdLineArgs::init( &aboutData );
+ KApplication app;
+
+ Kleo::GnuPGProcessBase gpg;
+ for ( int i = 1 ; i < argc ; ++i )
+ gpg << argv[i];
+
+ gpg.setUseStatusFD( true );
+
+ GnuPGViewer * gv = new GnuPGViewer();
+ gv->setProcess( &gpg );
+
+ app.setMainWidget( gv );
+ gv->show();
+
+ gpg.start( KProcess::NotifyOnExit, KProcess::AllOutput );
+
+ return app.exec();
+}
+
+#include "gnupgviewer.moc"
diff --git a/certmanager/lib/tests/test_jobs.cpp b/certmanager/lib/tests/test_jobs.cpp
new file mode 100644
index 000000000..22d9136d4
--- /dev/null
+++ b/certmanager/lib/tests/test_jobs.cpp
@@ -0,0 +1,108 @@
+/*
+ test_jobs.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <kleo/cryptobackendfactory.h>
+#include <kleo/signjob.h>
+#include <kleo/keylistjob.h>
+
+#include <gpgmepp/key.h>
+#include <gpgmepp/signingresult.h>
+#include <gpgmepp/keylistresult.h>
+
+#include <kdebug.h>
+#include <assert.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+
+#include <memory>
+
+static const char * protocol = 0;
+
+static void testSign()
+{
+ const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ;
+ assert( proto );
+
+ kdDebug() << "Using protocol " << proto->name() << endl;
+
+
+ std::vector<GpgME::Key> signingKeys;
+
+ std::auto_ptr<Kleo::KeyListJob> listJob( proto->keyListJob( false, false, true ) ); // use validating keylisting
+ if ( listJob.get() ) {
+ // ##### Adjust this to your own identity
+ listJob->exec( "faure@kde.org", true /*secret*/, signingKeys );
+ assert( !signingKeys.empty() );
+ } else {
+ assert( 0 ); // job failed
+ }
+
+ Kleo::SignJob* job = proto->signJob( true, true );
+
+ QCString cText = "Hallo Leute\n"; // like gpgme's t-sign.c
+ QByteArray plainText;
+ plainText.duplicate( cText.data(), cText.length() ); // hrmpf...
+ kdDebug() << k_funcinfo << "plainText=" << cText.data() << endl;
+
+ kdDebug() << k_funcinfo << " signing with " << signingKeys[0].primaryFingerprint() << endl;
+
+ QByteArray signature;
+ const GpgME::SigningResult res =
+ job->exec( signingKeys, plainText, GpgME::Context::Clearsigned, signature );
+ if ( res.error().isCanceled() ) {
+ kdDebug() << "signing was canceled by user" << endl;
+ return;
+ }
+ if ( res.error() ) {
+ kdDebug() << "signing failed: " << res.error().asString() << endl;
+ return;
+ }
+ kdDebug() << k_funcinfo << "signing resulted in signature="
+ << QCString( signature.data(), signature.size() + 1 ) << endl;
+}
+
+int main( int argc, char** argv ) {
+ protocol = "openpgp";
+ if ( argc == 2 ) {
+ protocol = argv[1];
+ argc = 1; // hide from KDE
+ }
+ KAboutData aboutData( "test_jobs", "Signing Job Test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app;
+
+ testSign();
+}
diff --git a/certmanager/lib/tests/test_keygen.cpp b/certmanager/lib/tests/test_keygen.cpp
new file mode 100644
index 000000000..9303b331c
--- /dev/null
+++ b/certmanager/lib/tests/test_keygen.cpp
@@ -0,0 +1,160 @@
+/*
+ test_keygen.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "test_keygen.h"
+
+#include <kleo/keylistjob.h>
+#include <kleo/keygenerationjob.h>
+#include <kleo/cryptobackendfactory.h>
+
+#include <ui/progressdialog.h>
+
+#include <gpgmepp/keygenerationresult.h>
+
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <kdebug.h>
+
+#include <qmessagebox.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+
+#include <assert.h>
+
+static const char * keyParams[] = {
+ "Key-Type", "Key-Length",
+ "Subkey-Type", "Subkey-Length",
+ "Name-Real", "Name-Comment", "Name-Email", "Name-DN",
+ "Expire-Date",
+ "Passphrase"
+};
+static const int numKeyParams = sizeof keyParams / sizeof *keyParams;
+
+static const char * protocol = 0;
+
+KeyGenerator::KeyGenerator( QWidget * parent, const char * name, WFlags )
+ : KDialogBase( parent, name, true, "KeyGenerationJob test",
+ Close|User1, User1, true, KGuiItem( "Create" ) )
+{
+ QWidget * w = new QWidget( this );
+ setMainWidget( w );
+
+ QGridLayout * glay = new QGridLayout( w, numKeyParams+3, 2, marginHint(), spacingHint() );
+
+ int row = -1;
+
+ ++row;
+ glay->addMultiCellWidget( new QLabel( "<GnupgKeyParms format=\"internal\">", w ),
+ row, row, 0, 1 );
+ for ( int i = 0 ; i < numKeyParams ; ++i ) {
+ ++row;
+ glay->addWidget( new QLabel( keyParams[i], w ), row, 0 );
+ glay->addWidget( mLineEdits[i] = new QLineEdit( w ), row, 1 );
+ }
+
+ ++row;
+ glay->addMultiCellWidget( new QLabel( "</GnupgKeyParms>", w ),
+ row, row, 0, 1 );
+ ++row;
+ glay->setRowStretch( row, 1 );
+ glay->setColStretch( 1, 1 );
+
+ connect( this, SIGNAL(user1Clicked()), SLOT(slotStartKeyGeneration()) );
+}
+
+KeyGenerator::~KeyGenerator() {}
+
+void KeyGenerator::slotStartKeyGeneration() {
+ QString params = "<GnupgKeyParms format=\"internal\">\n";
+ for ( int i = 0 ; i < numKeyParams ; ++i )
+ if ( mLineEdits[i] && !mLineEdits[i]->text().stripWhiteSpace().isEmpty() )
+ params += keyParams[i] + ( ": " + mLineEdits[i]->text().stripWhiteSpace() ) + '\n';
+ params += "</GnupgKeyParms>\n";
+
+ const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ;
+ if ( !proto )
+ proto = Kleo::CryptoBackendFactory::instance()->smime();
+ assert( proto );
+
+ kdDebug() << "Using protocol " << proto->name() << endl;
+
+ Kleo::KeyGenerationJob * job = proto->keyGenerationJob();
+ assert( job );
+
+ connect( job, SIGNAL(result(const GpgME::KeyGenerationResult&,const QByteArray&)),
+ SLOT(slotResult(const GpgME::KeyGenerationResult&,const QByteArray&)) );
+
+ const GpgME::Error err = job->start( params );
+ if ( err )
+ showError( err );
+ else
+ (void)new Kleo::ProgressDialog( job, "Generating key", this );
+}
+
+void KeyGenerator::showError( const GpgME::Error & err ) {
+ KMessageBox::error( this, "Could not start key generation: " + QString::fromLocal8Bit( err.asString() ),
+ "Key Generation Error" );
+}
+
+void KeyGenerator::slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData ) {
+ if ( res.error() )
+ showError( res.error() );
+ else
+ KMessageBox::information( this, QString("Key generated successfully, %1 bytes long").arg( keyData.size() ),
+ "Key Generation Finished" );
+}
+
+int main( int argc, char** argv ) {
+ if ( argc == 2 ) {
+ protocol = argv[1];
+ argc = 1; // hide from KDE
+ }
+ KAboutData aboutData( "test_keygen", "KeyGenerationJob Test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app;
+
+ KeyGenerator * keygen = new KeyGenerator( 0, "KeyGenerator top-level" );
+ app.setMainWidget( keygen );
+ keygen->show();
+
+ return app.exec();
+}
+
+#include "test_keygen.moc"
diff --git a/certmanager/lib/tests/test_keygen.h b/certmanager/lib/tests/test_keygen.h
new file mode 100644
index 000000000..0ba713823
--- /dev/null
+++ b/certmanager/lib/tests/test_keygen.h
@@ -0,0 +1,62 @@
+/*
+ test_keygen.h
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_TEST_KEYGEN_H__
+#define __KLEO_TEST_KEYGEN_H__
+
+#include <kdialogbase.h>
+
+#include <qcstring.h>
+
+namespace GpgME {
+ class Error;
+ class KeyGenerationResult;
+}
+
+class QLineEdit;
+
+class KeyGenerator : public KDialogBase {
+ Q_OBJECT
+public:
+ KeyGenerator( QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~KeyGenerator();
+
+public slots:
+ void slotStartKeyGeneration();
+ void slotResult( const GpgME::KeyGenerationResult & res, const QByteArray & keyData );
+private:
+ void showError( const GpgME::Error & err );
+
+private:
+ QLineEdit * mLineEdits[20];
+};
+
+#endif // __KLEO_TEST_KEYGEN_H__
diff --git a/certmanager/lib/tests/test_keylister.cpp b/certmanager/lib/tests/test_keylister.cpp
new file mode 100644
index 000000000..9507221e7
--- /dev/null
+++ b/certmanager/lib/tests/test_keylister.cpp
@@ -0,0 +1,146 @@
+/*
+ test_keylister.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include <config.h>
+
+#include "test_keylister.h"
+
+#include <kleo/keylistjob.h>
+#include <cryptplugwrapper.h>
+#include <kleo/cryptobackendfactory.h>
+
+#include <gpgmepp/keylistresult.h>
+#include <gpgmepp/key.h>
+
+#include <kapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <kdebug.h>
+
+#include <qmessagebox.h>
+#include <qstringlist.h>
+#include <qtimer.h>
+
+#include <assert.h>
+
+namespace {
+ class TestColumnStrategy : public Kleo::KeyListView::ColumnStrategy {
+ public:
+ ~TestColumnStrategy() {}
+ QString title( int col ) const;
+ QString toolTip( const GpgME::Key & key, int col ) const;
+ QString text( const GpgME::Key & key, int col ) const;
+ };
+
+ QString TestColumnStrategy::title( int col ) const {
+ switch ( col ) {
+ case 0: return "Subject";
+ case 1: return "EMail";
+ case 2: return "Issuer";
+ case 3: return "Serial";
+ case 4: return "Protocol";
+ case 5: return "Validity";
+ default: return QString::null;
+ }
+ }
+
+ QString TestColumnStrategy::toolTip( const GpgME::Key & key, int ) const {
+ return "Fingerprint: " + QString::fromUtf8( key.primaryFingerprint() );
+ }
+
+ QString TestColumnStrategy::text( const GpgME::Key & key, int col ) const {
+ if ( key.isNull() )
+ return "<null>";
+ switch ( col ) {
+ case 0: return QString::fromUtf8( key.userID(0).id() );
+ case 1: return QString::fromUtf8( key.userID(0).email() );
+ case 2: return QString::fromUtf8( key.issuerName() );
+ case 3: return key.issuerSerial();
+ case 4: return key.protocolAsString();
+ case 5: return QChar( key.userID(0).validityAsString() );
+ default: return QString::null;
+ }
+ }
+}
+
+CertListView::CertListView( QWidget * parent, const char * name, WFlags f )
+ : Kleo::KeyListView( new TestColumnStrategy(), 0, parent, name, f )
+{
+ setHierarchical( true );
+ setRootIsDecorated( true );
+}
+
+void CertListView::slotResult( const GpgME::KeyListResult & result ) {
+ kdDebug() << "CertListView::slotResult()" << endl;
+ if ( result.isNull() )
+ QMessageBox::information( this, "Key Listing Result", "KeyListResult is null!" );
+ else if ( result.error() )
+ QMessageBox::critical( this, "Key Listing Result",
+ QString("KeyListResult Error: %1").arg( result.error().asString() ) );
+ else if ( result.isTruncated() )
+ QMessageBox::information( this, "Key Listing Result", "KeyListResult is truncated!" );
+ else
+ QMessageBox::information( this, "Key Listing Result", "Key listing successful" );
+}
+
+void CertListView::slotStart() {
+ kdDebug() << "CertListView::slotStart()" << endl;
+ Kleo::KeyListJob * job = Kleo::CryptoBackendFactory::instance()->smime()->keyListJob( false );
+ assert( job );
+ QObject::connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ this, SLOT(slotAddKey(const GpgME::Key&)) );
+ QObject::connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ this, SLOT(slotResult(const GpgME::KeyListResult&)) );
+#if 0
+ QStringList l;
+ l << "Marc";
+ job->start( l, false );
+#else
+ job->start( QStringList(), false );
+#endif
+}
+
+int main( int argc, char** argv ) {
+
+ KAboutData aboutData( "test_keylister", "KeyLister Test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app;
+
+ CertListView * clv = new CertListView( 0, "CertListView top-level" );
+ app.setMainWidget( clv );
+ clv->show();
+
+ QTimer::singleShot( 5000, clv, SLOT(slotStart()) );
+
+ return app.exec();
+}
+
+#include "test_keylister.moc"
diff --git a/certmanager/lib/tests/test_keylister.h b/certmanager/lib/tests/test_keylister.h
new file mode 100644
index 000000000..348ec262f
--- /dev/null
+++ b/certmanager/lib/tests/test_keylister.h
@@ -0,0 +1,52 @@
+/*
+ test_keylister.h
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_TEST_KEYLISTER_H__
+#define __KLEO_TEST_KEYLISTER_H__
+
+#include <ui/keylistview.h>
+
+namespace GpgME {
+ class Key;
+ class KeyListResult;
+}
+
+class CertListView : public Kleo::KeyListView {
+ Q_OBJECT
+public:
+ CertListView( QWidget * parent=0, const char * name=0, WFlags f=0 );
+
+public slots:
+ void slotResult( const GpgME::KeyListResult & result );
+ void slotStart();
+};
+
+#endif // __KLEO_TEST_KEYLISTER_H__
diff --git a/certmanager/lib/tests/test_keyselectiondialog.cpp b/certmanager/lib/tests/test_keyselectiondialog.cpp
new file mode 100644
index 000000000..e6c85fca0
--- /dev/null
+++ b/certmanager/lib/tests/test_keyselectiondialog.cpp
@@ -0,0 +1,67 @@
+/*
+ test_keygen.cpp
+
+ This file is part of libkleopatra's test suite.
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include <config.h>
+
+#include <ui/keyselectiondialog.h>
+#include <gpgmepp/key.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include <vector>
+
+int main( int argc, char ** argv ) {
+ KAboutData aboutData( "test_keyselectiondialog", "KeySelectionDialog Test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app;
+
+ KGlobal::iconLoader()->addAppDir( "libkleopatra" );
+
+ Kleo::KeySelectionDialog dlg( "Kleo::KeySelectionDialog Test",
+ "Please select a key:",
+ std::vector<GpgME::Key>(),
+ Kleo::KeySelectionDialog::AllKeys, true, true );
+
+ if ( dlg.exec() == QDialog::Accepted ) {
+ kdDebug() << "accepted; selected key: " << (dlg.selectedKey().userID(0).id() ? dlg.selectedKey().userID(0).id() : "<null>") << "\nselected _keys_:" << endl;
+ for ( std::vector<GpgME::Key>::const_iterator it = dlg.selectedKeys().begin() ; it != dlg.selectedKeys().end() ; ++it )
+ kdDebug() << (it->userID(0).id() ? it->userID(0).id() : "<null>") << endl;
+ } else {
+ kdDebug() << "rejected" << endl;
+ }
+
+ return 0;
+}
diff --git a/certmanager/lib/tests/test_verify.cpp b/certmanager/lib/tests/test_verify.cpp
new file mode 100644
index 000000000..a81e50466
--- /dev/null
+++ b/certmanager/lib/tests/test_verify.cpp
@@ -0,0 +1,99 @@
+/*
+ This file is part of Kleopatra's test suite.
+ Copyright (c) 2007 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include <config.h>
+
+#include <kleo/cryptobackendfactory.h>
+#include <kleo/verifydetachedjob.h>
+#include <kleo/verifyopaquejob.h>
+
+#include <gpgmepp/verificationresult.h>
+#include <gpgmepp/key.h>
+
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+
+#include <qdir.h>
+#include <qfile.h>
+
+#include <assert.h>
+
+int main( int argc, char **argv )
+{
+ setenv("GNUPGHOME", KDESRCDIR "/gnupg_home", 1 );
+ setenv("LC_ALL", "C", 1);
+ setenv("KDEHOME", QFile::encodeName( QDir::homeDirPath() + "/.kde-unit-test" ), 1);
+
+ KAboutData aboutData( "test_verify", "verify job test", "0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KApplication app( false, false );
+
+ const QString sigFileName = KDESRCDIR "/test.data.sig";
+ const QString dataFileName = KDESRCDIR "/test.data";
+
+ QFile sigFile( sigFileName );
+ assert( sigFile.open( IO_ReadOnly ) );
+ QFile dataFile( dataFileName );
+ assert( dataFile.open( IO_ReadOnly ) );
+
+ const Kleo::CryptoBackend::Protocol * const backend = Kleo::CryptoBackendFactory::instance()->protocol( "openpgp" );
+
+ Kleo::VerifyDetachedJob *job = backend->verifyDetachedJob();
+ GpgME::VerificationResult result = job->exec( sigFile.readAll(), dataFile.readAll() );
+ assert( !result.error() );
+ assert( result.signatures().size() == 1 );
+
+ GpgME::Signature sig = result.signature( 0 );
+ assert( (sig.summary() & GpgME::Signature::KeyMissing) == 0 );
+ assert( sig.creationTime() == 1189650248L );
+ assert( sig.validity() == GpgME::Signature::Full );
+
+ const QString opaqueFileName = KDESRCDIR "/test.data.gpg";
+ QFile opaqueFile( opaqueFileName );
+ assert( opaqueFile.open( IO_ReadOnly ) );
+ QByteArray clearText;
+
+ Kleo::VerifyOpaqueJob *job2 = backend->verifyOpaqueJob();
+ result = job2->exec( opaqueFile.readAll(), clearText );
+ assert( !result.error() );
+ assert( result.signatures().size() == 1 );
+
+ sig = result.signature( 0 );
+ assert( (sig.summary() & GpgME::Signature::KeyMissing) == 0 );
+ assert( (sig.summary() & GpgME::Signature::Green ) );
+ assert( sig.creationTime() > 0 );
+ assert( sig.validity() == GpgME::Signature::Full );
+
+ dataFile.reset();
+ assert( clearText == dataFile.readAll() );
+
+ return 0;
+}
diff --git a/certmanager/lib/ui/Makefile.am b/certmanager/lib/ui/Makefile.am
new file mode 100644
index 000000000..f381fb64d
--- /dev/null
+++ b/certmanager/lib/ui/Makefile.am
@@ -0,0 +1,42 @@
+
+INCLUDES = -I$(top_srcdir)/libkdenetwork \
+ -I$(top_srcdir)/libkpgp \
+ -I$(top_srcdir)/certmanager/lib \
+ $(GPGME_CFLAGS) $(all_includes)
+
+noinst_LTLIBRARIES = libkleopatra_ui.la
+
+libkleopatra_ui_la_SOURCES = \
+ kdhorizontalline.cpp \
+ messagebox.cpp \
+ progressbar.cpp \
+ progressdialog.cpp \
+ keylistview.cpp \
+ keyselectiondialog.cpp \
+ keyrequester.cpp \
+ passphrasedialog.cpp \
+ keyapprovaldialog.cpp \
+ backendconfigwidget.cpp \
+ dnattributeorderconfigwidget.cpp \
+ cryptoconfigmodule.cpp \
+ cryptoconfigdialog.cpp \
+ directoryserviceswidgetbase.ui \
+ directoryserviceswidget.cpp \
+ adddirectoryservicedialog.ui \
+ adddirectoryservicedialogimpl.cpp
+
+kleodir = $(includedir)/kleo
+kleo_HEADERS = \
+ kdhorizontalline.h \
+ messagebox.h \
+ progressbar.h \
+ progressdialog.h \
+ keylistview.h \
+ keyselectiondialog.h \
+ keyrequester.h \
+ passphrasedialog.h \
+ keyapprovaldialog.h \
+ backendconfigwidget.h \
+ dnattributeorderconfigwidget.h
+
+METASOURCES = AUTO
diff --git a/certmanager/lib/ui/adddirectoryservicedialog.ui b/certmanager/lib/ui/adddirectoryservicedialog.ui
new file mode 100644
index 000000000..98e171887
--- /dev/null
+++ b/certmanager/lib/ui/adddirectoryservicedialog.ui
@@ -0,0 +1,207 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>AddDirectoryServiceDialog</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>AddDirectoryServiceDialog</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>389</width>
+ <height>257</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Add or Change Directory Service</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>serverNameLA</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Server name:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>serverNameED</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="2" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>descriptionED</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="1" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>portED</cstring>
+ </property>
+ <property name="text">
+ <string>389</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>serverNameED</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>usernameLA</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;User name (optional):</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>usernameED</cstring>
+ </property>
+ </widget>
+ <spacer row="5" column="3">
+ <property name="name">
+ <cstring>spacer23</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>60</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="4" column="0">
+ <property name="name">
+ <cstring>passwordLA</cstring>
+ </property>
+ <property name="text">
+ <string>Pass&amp;word (optional):</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>passwordED</cstring>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="8" column="2">
+ <property name="name">
+ <cstring>PushButton3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton" row="8" column="3">
+ <property name="name">
+ <cstring>PushButton4</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ </widget>
+ <widget class="Line" row="6" column="0" rowspan="1" colspan="4">
+ <property name="name">
+ <cstring>line1</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>HLine</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ </widget>
+ <spacer row="7" column="0" rowspan="2" colspan="2">
+ <property name="name">
+ <cstring>spacer21</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>260</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit" row="3" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>usernameED</cstring>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="4" column="1" rowspan="1" colspan="3">
+ <property name="name">
+ <cstring>passwordED</cstring>
+ </property>
+ <property name="echoMode">
+ <enum>Password</enum>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>descriptionLA</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Base DN:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>descriptionED</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>portLA</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Port:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>portED</cstring>
+ </property>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>PushButton3</sender>
+ <signal>clicked()</signal>
+ <receiver>AddDirectoryServiceDialog</receiver>
+ <slot>accept()</slot>
+ </connection>
+ <connection>
+ <sender>PushButton4</sender>
+ <signal>clicked()</signal>
+ <receiver>AddDirectoryServiceDialog</receiver>
+ <slot>reject()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>serverNameED</tabstop>
+ <tabstop>portED</tabstop>
+ <tabstop>descriptionED</tabstop>
+ <tabstop>usernameED</tabstop>
+ <tabstop>passwordED</tabstop>
+ <tabstop>PushButton3</tabstop>
+ <tabstop>PushButton4</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/certmanager/lib/ui/adddirectoryservicedialogimpl.cpp b/certmanager/lib/ui/adddirectoryservicedialogimpl.cpp
new file mode 100644
index 000000000..973266b16
--- /dev/null
+++ b/certmanager/lib/ui/adddirectoryservicedialogimpl.cpp
@@ -0,0 +1,63 @@
+/*
+ adddirectoryservicedialogimpl.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "adddirectoryservicedialogimpl.h"
+
+#include <qvalidator.h>
+#include <klineedit.h>
+
+/*
+ * Constructs a AddDirectoryServiceDialogImpl which is a child of 'parent', with the
+ * name 'name' and widget flags set to 'f'
+ *
+ * The dialog will by default be modeless, unless you set 'modal' to
+ * TRUE to construct a modal dialog.
+ */
+AddDirectoryServiceDialogImpl::AddDirectoryServiceDialogImpl( QWidget* parent, const char* name, bool modal, WFlags fl )
+ : AddDirectoryServiceDialog( parent, name, modal, fl )
+{
+ portED->setValidator( new QIntValidator( 0, 65535, portED ) );
+}
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+AddDirectoryServiceDialogImpl::~AddDirectoryServiceDialogImpl()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+#include "adddirectoryservicedialogimpl.moc"
diff --git a/certmanager/lib/ui/adddirectoryservicedialogimpl.h b/certmanager/lib/ui/adddirectoryservicedialogimpl.h
new file mode 100644
index 000000000..deee06439
--- /dev/null
+++ b/certmanager/lib/ui/adddirectoryservicedialogimpl.h
@@ -0,0 +1,47 @@
+/*
+ adddirectoryservicedialogimpl.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef ADDDIRECTORYSERVICEDIALOGIMPL_H
+#define ADDDIRECTORYSERVICEDIALOGIMPL_H
+#include "adddirectoryservicedialog.h"
+
+class AddDirectoryServiceDialogImpl : public AddDirectoryServiceDialog
+{
+ Q_OBJECT
+
+public:
+ AddDirectoryServiceDialogImpl( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 );
+ ~AddDirectoryServiceDialogImpl();
+
+};
+
+#endif // ADDDIRECTORYSERVICEDIALOGIMPL_H
diff --git a/certmanager/lib/ui/backendconfigwidget.cpp b/certmanager/lib/ui/backendconfigwidget.cpp
new file mode 100644
index 000000000..c40890a43
--- /dev/null
+++ b/certmanager/lib/ui/backendconfigwidget.cpp
@@ -0,0 +1,323 @@
+/* -*- c++ -*-
+ backendconfigwidget.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2002,2004,2005 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "backendconfigwidget.h"
+#include "cryptoconfigdialog.h"
+
+#include "kleo/cryptobackendfactory.h"
+#include "ui/keylistview.h" // for lvi_cast<>
+
+#include <klistview.h>
+#include <kdialog.h>
+#include <klocale.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kapplication.h>
+#include <dcopclient.h>
+
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <qheader.h>
+#include <qtimer.h>
+
+#include <assert.h>
+
+namespace Kleo {
+ class BackendListView;
+}
+
+class Kleo::BackendConfigWidget::Private {
+public:
+ Kleo::BackendListView * listView;
+ QPushButton * configureButton;
+ QPushButton * rescanButton;
+ Kleo::CryptoBackendFactory * backendFactory;
+};
+
+namespace Kleo {
+ class BackendListViewItem;
+ class ProtocolCheckListItem;
+}
+
+class Kleo::BackendListView : public KListView
+{
+public:
+ BackendListView( BackendConfigWidget* parent, const char* name = 0 )
+ : KListView( parent, name ) {}
+
+ /// return backend for currently selected (/current) item. Used by Configure button.
+ const Kleo::CryptoBackend* currentBackend() const;
+
+ /// return which protocol implementation was chosen (checked) for each type (used when saving)
+ const Kleo::CryptoBackend* chosenBackend( const char * protocol );
+
+ /// deselect all except one for a given protocol type (radiobutton-like exclusivity)
+ void deselectAll( const char * protocol, QCheckListItem* except );
+
+ void emitChanged() { static_cast<BackendConfigWidget *>( parentWidget() )->emitChanged( true ); }
+};
+
+// Toplevel listviewitem for a given backend (e.g. "GpgME", "Kgpg/gpg v2")
+class Kleo::BackendListViewItem : public QListViewItem
+{
+public:
+ BackendListViewItem( KListView* lv, QListViewItem *prev, const CryptoBackend *cryptoBackend )
+ : QListViewItem( lv, prev, cryptoBackend->displayName() ), mCryptoBackend( cryptoBackend )
+ {}
+
+ const CryptoBackend *cryptoBackend() const { return mCryptoBackend; }
+ enum { RTTI = 0x2EAE3BE0, RTTI_MASK = 0xFFFFFFFF };
+ int rtti() const { return RTTI; }
+
+private:
+ const CryptoBackend *mCryptoBackend;
+};
+
+
+// Checklist item under a BackendListViewItem
+// (e.g. "GpgME supports protocol OpenPGP")
+class Kleo::ProtocolCheckListItem : public QCheckListItem
+{
+public:
+ ProtocolCheckListItem( BackendListViewItem* blvi,
+ QListViewItem* prev, const char * protocolName,
+ const CryptoBackend::Protocol* protocol ) // can be 0
+ : QCheckListItem( blvi, prev, itemText( protocolName, protocol ),
+ QCheckListItem::CheckBox ),
+ mProtocol( protocol ), mProtocolName( protocolName )
+ {}
+
+ enum { RTTI = 0x2EAE3BE1, RTTI_MASK = 0xFFFFFFFF };
+ virtual int rtti() const { return RTTI; }
+
+ // can be 0
+ const CryptoBackend::Protocol* protocol() const { return mProtocol; }
+ const char * protocolName() const { return mProtocolName; }
+
+protected:
+ virtual void stateChange( bool b ) {
+ BackendListView* lv = static_cast<BackendListView *>( listView() );
+ // "radio-button-like" behavior for the protocol checkboxes
+ if ( b )
+ lv->deselectAll( mProtocolName, this );
+ lv->emitChanged();
+ QCheckListItem::stateChange( b );
+ }
+
+private:
+ // Helper for the constructor.
+ static QString itemText( const char * protocolName, const CryptoBackend::Protocol* protocol ) {
+ // First one is the generic name (find a nice one for OpenPGP, SMIME)
+ const QString protoName = qstricmp( protocolName, "openpgp" ) != 0
+ ? qstricmp( protocolName, "smime" ) != 0
+ ? QString::fromLatin1( protocolName )
+ : i18n( "S/MIME" )
+ : i18n( "OpenPGP" );
+ // second one is implementation name (gpg, gpgsm...)
+ const QString impName = protocol ? protocol->displayName() : i18n( "failed" );
+ return i18n( "Items in Kleo::BackendConfigWidget listview (1: protocol; 2: implementation name)",
+ "%1 (%2)" ).arg( protoName, impName );
+ }
+
+ const CryptoBackend::Protocol* mProtocol; // can be 0
+ const char * mProtocolName;
+};
+
+const Kleo::CryptoBackend* Kleo::BackendListView::currentBackend() const {
+ const QListViewItem* curItem = currentItem();
+ if ( !curItem ) // can't happen
+ return 0;
+ if ( lvi_cast<Kleo::ProtocolCheckListItem>( curItem ) )
+ curItem = curItem->parent();
+ if ( const Kleo::BackendListViewItem * blvi = lvi_cast<Kleo::BackendListViewItem>( curItem ) )
+ return blvi->cryptoBackend();
+ return 0;
+}
+
+// can't be const method due to QListViewItemIterator (why?)
+const Kleo::CryptoBackend* Kleo::BackendListView::chosenBackend( const char * protocolName )
+{
+ for ( QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ ) ;
+ it.current() ; ++it )
+ if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
+ if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 ) {
+ // OK that's the one. Now go up to the parent backend
+ // (need to do that in the listview since Protocol doesn't know it)
+ if ( const BackendListViewItem * parItem = lvi_cast<BackendListViewItem>( it.current()->parent() ) )
+ return parItem->cryptoBackend();
+ }
+ return 0;
+}
+
+void Kleo::BackendListView::deselectAll( const char * protocolName, QCheckListItem* except )
+{
+ for ( QListViewItemIterator it( this /*, QListViewItemIterator::Checked doesn't work*/ ) ;
+ it.current() ; ++it ) {
+ if ( it.current() == except ) continue;
+ if ( ProtocolCheckListItem * p = lvi_cast<ProtocolCheckListItem>( it.current() ) )
+ if ( p->isOn() && qstricmp( p->protocolName(), protocolName ) == 0 )
+ p->setOn( false );
+ }
+}
+
+////
+
+Kleo::BackendConfigWidget::BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent, const char * name, WFlags f )
+ : QWidget( parent, name, f ), d( 0 )
+{
+ assert( factory );
+ d = new Private();
+ d->backendFactory = factory;
+
+ QHBoxLayout * hlay =
+ new QHBoxLayout( this, 0, KDialog::spacingHint() );
+
+ d->listView = new BackendListView( this, "d->listView" );
+ d->listView->addColumn( i18n("Available Backends") );
+ d->listView->setAllColumnsShowFocus( true );
+ d->listView->setSorting( -1 );
+ d->listView->header()->setClickEnabled( false );
+ d->listView->setFullWidth( true );
+
+ hlay->addWidget( d->listView, 1 );
+
+ connect( d->listView, SIGNAL(selectionChanged(QListViewItem*)),
+ SLOT(slotSelectionChanged(QListViewItem*)) );
+
+ QVBoxLayout * vlay = new QVBoxLayout( hlay ); // inherits spacing
+
+ d->configureButton = new QPushButton( i18n("Confi&gure..."), this );
+ d->configureButton->setAutoDefault( false );
+ vlay->addWidget( d->configureButton );
+
+ connect( d->configureButton, SIGNAL(clicked()),
+ SLOT(slotConfigureButtonClicked()) );
+
+ d->rescanButton = new QPushButton( i18n("Rescan"), this );
+ d->rescanButton->setAutoDefault( false );
+ vlay->addWidget( d->rescanButton );
+
+ connect( d->rescanButton, SIGNAL(clicked()),
+ SLOT(slotRescanButtonClicked()) );
+
+ vlay->addStretch( 1 );
+}
+
+Kleo::BackendConfigWidget::~BackendConfigWidget() {
+ delete d; d = 0;
+}
+
+void Kleo::BackendConfigWidget::load() {
+ d->listView->clear();
+
+ unsigned int backendCount = 0;
+
+ // populate the plugin list:
+ BackendListViewItem * top = 0;
+ for ( unsigned int i = 0 ; const CryptoBackend * b = d->backendFactory->backend( i ) ; ++i ) {
+
+ top = new Kleo::BackendListViewItem( d->listView, top, b );
+
+ ProtocolCheckListItem * last = 0;
+ for ( int i = 0 ; const char * name = b->enumerateProtocols( i ) ; ++i ) {
+ const CryptoBackend::Protocol * protocol = b->protocol( name );
+
+ if ( protocol ) {
+ last = new ProtocolCheckListItem( top, last, name, protocol );
+ last->setOn( protocol == d->backendFactory->protocol( name ) );
+ } else if ( b->supportsProtocol( name ) ) {
+ last = new ProtocolCheckListItem( top, last, name, 0 );
+ last->setOn( false );
+ last->setEnabled( false );
+ }
+ }
+
+ top->setOpen( true );
+ ++backendCount;
+ }
+
+ if ( backendCount ) {
+ d->listView->setCurrentItem( d->listView->firstChild() );
+ d->listView->setSelected( d->listView->firstChild(), true );
+ }
+
+ slotSelectionChanged( d->listView->firstChild() );
+}
+
+void Kleo::BackendConfigWidget::slotSelectionChanged( QListViewItem * ) {
+ const CryptoBackend* backend = d->listView->currentBackend();
+ if ( backend && !backend->config() )
+ kdDebug(5150) << "Backend w/o config object!" << endl;
+ d->configureButton->setEnabled( backend && backend->config() );
+}
+
+
+void Kleo::BackendConfigWidget::slotRescanButtonClicked() {
+ QStringList reasons;
+ d->backendFactory->scanForBackends( &reasons );
+ if ( !reasons.empty() )
+ KMessageBox::informationList( this,
+ i18n("The following problems where encountered during scanning:"),
+ reasons, i18n("Scan Results") );
+ load();
+ emit changed( true );
+}
+
+void Kleo::BackendConfigWidget::slotConfigureButtonClicked() {
+ const CryptoBackend* backend = d->listView->currentBackend();
+ if ( backend && backend->config() ) {
+ Kleo::CryptoConfigDialog dlg( backend->config(), this );
+ int result = dlg.exec();
+ if ( result == QDialog::Accepted ) {
+ // Tell other users of gpgconf (e.g. the s/mime page) that the gpgconf data might have changed
+ kapp->dcopClient()->emitDCOPSignal( "KPIM::CryptoConfig", "changed()", QByteArray() );
+ // and schedule a rescan, in case the updates make a backend valid
+ QTimer::singleShot( 0, this, SLOT(slotRescanButtonClicked()) );
+ }
+ }
+ else // shouldn't happen, button is disabled
+ kdWarning(5150) << "Can't configure backend, no config object available" << endl;
+}
+
+void Kleo::BackendConfigWidget::save() const {
+ for ( int i = 0 ; const char * name = d->backendFactory->enumerateProtocols( i ) ; ++i )
+ d->backendFactory->setProtocolBackend( name, d->listView->chosenBackend( name ) );
+}
+
+void Kleo::BackendConfigWidget::virtual_hook( int, void* ) {}
+
+#include "backendconfigwidget.moc"
diff --git a/certmanager/lib/ui/backendconfigwidget.h b/certmanager/lib/ui/backendconfigwidget.h
new file mode 100644
index 000000000..0e26655ce
--- /dev/null
+++ b/certmanager/lib/ui/backendconfigwidget.h
@@ -0,0 +1,76 @@
+/* -*- c++ -*-
+ backendconfigwidget.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2002,2004 Klarälvdalens Datakonsult AB
+ Copyright (c) 2002,2003 Marc Mutz <mutz@kde.org>
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifndef __KLEO_UI_BACKENDCONFIGWIDGET_H__
+#define __KLEO_UI_BACKENDCONFIGWIDGET_H__
+
+#include <qwidget.h>
+#include <kdepimmacros.h>
+
+namespace Kleo {
+ class CryptoBackendFactory;
+}
+
+class QListViewItem;
+
+namespace Kleo {
+
+ class KDE_EXPORT BackendConfigWidget : public QWidget {
+ Q_OBJECT
+ public:
+ BackendConfigWidget( CryptoBackendFactory * factory, QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~BackendConfigWidget();
+
+ void load();
+ void save() const;
+
+ void emitChanged( bool b ) { emit changed( b ); }
+
+ signals:
+ void changed( bool );
+
+ private slots:
+ void slotSelectionChanged( QListViewItem * );
+ void slotRescanButtonClicked();
+ void slotConfigureButtonClicked();
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ virtual void virtual_hook( int, void* );
+ };
+
+}
+
+#endif // __KLEO_UI_BACKENDCONFIGWIDGET_H__
diff --git a/certmanager/lib/ui/cryptoconfigdialog.cpp b/certmanager/lib/ui/cryptoconfigdialog.cpp
new file mode 100644
index 000000000..3fa0a97ca
--- /dev/null
+++ b/certmanager/lib/ui/cryptoconfigdialog.cpp
@@ -0,0 +1,89 @@
+/*
+ cryptoconfigdialog.h
+
+ This file is part of kgpgcertmanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "cryptoconfigdialog.h"
+#include "cryptoconfigmodule.h"
+#include <klocale.h>
+#include <kaccelmanager.h>
+
+Kleo::CryptoConfigDialog::CryptoConfigDialog( Kleo::CryptoConfig* config, QWidget *parent, const char* name )
+ : KDialogBase( Swallow,
+ // Remove the "whats's this" button since we have no support for it
+ WStyle_Customize | WStyle_DialogBorder | WStyle_Maximize | WStyle_Title | WStyle_SysMenu,
+ parent, name, true /*modal*/,
+ i18n( "Configure" ), Default|Cancel|Apply|Ok|User1,
+ Ok, true /*separator*/, KGuiItem( i18n( "&Reset" ), "undo" ) )
+{
+ mMainWidget = new CryptoConfigModule( config, this );
+ setMainWidget( mMainWidget );
+ connect( mMainWidget, SIGNAL( changed() ), SLOT( slotChanged() ) );
+ enableButton( Apply, false );
+
+ // Automatically assign accelerators
+ KAcceleratorManager::manage( this );
+}
+
+void Kleo::CryptoConfigDialog::slotOk()
+{
+ slotApply();
+ accept();
+}
+
+void Kleo::CryptoConfigDialog::slotCancel()
+{
+ mMainWidget->cancel();
+ reject();
+}
+
+void Kleo::CryptoConfigDialog::slotDefault()
+{
+ mMainWidget->defaults();
+ slotChanged();
+}
+
+void Kleo::CryptoConfigDialog::slotApply()
+{
+ mMainWidget->save();
+ enableButton( Apply, false );
+}
+
+void Kleo::CryptoConfigDialog::slotUser1() // reset
+{
+ mMainWidget->reset();
+ enableButton( Apply, false );
+}
+
+void Kleo::CryptoConfigDialog::slotChanged()
+{
+ enableButton( Apply, true );
+}
+
+#include "cryptoconfigdialog.moc"
diff --git a/certmanager/lib/ui/cryptoconfigdialog.h b/certmanager/lib/ui/cryptoconfigdialog.h
new file mode 100644
index 000000000..484c55ea4
--- /dev/null
+++ b/certmanager/lib/ui/cryptoconfigdialog.h
@@ -0,0 +1,69 @@
+/*
+ cryptoconfigdialog.h
+
+ This file is part of kgpgcertmanager
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CRYPTOCONFIGDIALOG_H
+#define CRYPTOCONFIGDIALOG_H
+
+#include <kdialogbase.h>
+#include <kdepimmacros.h>
+
+namespace Kleo {
+
+ class CryptoConfig;
+ class CryptoConfigModule;
+
+ /**
+ * Simple KDialogBase wrapper around CryptoConfigModule
+ */
+ class KDE_EXPORT CryptoConfigDialog : public KDialogBase
+ {
+ Q_OBJECT
+ public:
+ CryptoConfigDialog( Kleo::CryptoConfig* config, QWidget *parent = 0, const char* name = 0 );
+
+ protected:
+ virtual void slotOk();
+ virtual void slotCancel();
+ virtual void slotDefault();
+ virtual void slotApply();
+ virtual void slotUser1(); // reset
+
+ public slots:
+ void slotChanged();
+
+ private:
+ CryptoConfigModule* mMainWidget;
+ };
+
+}
+
+#endif /* CRYPTOCONFIGDIALOG_H */
+
diff --git a/certmanager/lib/ui/cryptoconfigmodule.cpp b/certmanager/lib/ui/cryptoconfigmodule.cpp
new file mode 100644
index 000000000..dbc8edc57
--- /dev/null
+++ b/certmanager/lib/ui/cryptoconfigmodule.cpp
@@ -0,0 +1,634 @@
+/*
+ cryptoconfigmodule.cpp
+
+ This file is part of kgpgcertmanager
+ Copyright (c) 2004 Klar�vdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "cryptoconfigmodule.h"
+#include "cryptoconfigmodule_p.h"
+#include "directoryserviceswidget.h"
+#include "kdhorizontalline.h"
+
+#include <kleo/cryptoconfig.h>
+
+#include <klineedit.h>
+#include <klocale.h>
+#include <kdialogbase.h>
+#include <kdebug.h>
+#include <knuminput.h>
+#include <kiconloader.h>
+#include <kglobal.h>
+#include <kurlrequester.h>
+
+#include <qgrid.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qpushbutton.h>
+#include <qregexp.h>
+#include <qstyle.h>
+#include <qapplication.h>
+
+using namespace Kleo;
+
+static inline QPixmap loadIcon( QString s ) {
+ return KGlobal::instance()->iconLoader()
+ ->loadIcon( s.replace( QRegExp( "[^a-zA-Z0-9_]" ), "_" ), KIcon::NoGroup, KIcon::SizeMedium );
+}
+
+static const KJanusWidget::Face determineJanusFace( const Kleo::CryptoConfig * config ) {
+ return config && config->componentList().size() < 2
+ ? KJanusWidget::Plain
+ : KJanusWidget::IconList ;
+}
+
+Kleo::CryptoConfigModule::CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent, const char * name )
+ : KJanusWidget( parent, name, determineJanusFace( config ) ), mConfig( config )
+{
+ QWidget * vbox = 0;
+ if ( face() == Plain ) {
+ vbox = plainPage();
+ QVBoxLayout * vlay = new QVBoxLayout( vbox, 0, KDialog::spacingHint() );
+ vlay->setAutoAdd( true );
+ }
+
+ const QStringList components = config->componentList();
+ for ( QStringList::const_iterator it = components.begin(); it != components.end(); ++it ) {
+ //kdDebug(5150) << "Component " << (*it).local8Bit() << ":" << endl;
+ Kleo::CryptoConfigComponent* comp = config->component( *it );
+ Q_ASSERT( comp );
+ if ( comp->groupList().empty() )
+ continue;
+ if ( face() != Plain ) {
+ vbox = addVBoxPage( comp->description(), QString::null, loadIcon( comp->iconName() ) );
+ }
+
+ QScrollView * scrollView = new QScrollView( vbox );
+ scrollView->setHScrollBarMode( QScrollView::AlwaysOff );
+ scrollView->setResizePolicy( QScrollView::AutoOneFit );
+ QVBox* boxInScrollView = new QVBox( scrollView->viewport() );
+ boxInScrollView->setMargin( KDialog::marginHint() );
+ scrollView->addChild( boxInScrollView );
+
+ CryptoConfigComponentGUI* compGUI =
+ new CryptoConfigComponentGUI( this, comp, boxInScrollView, (*it).local8Bit() );
+ // KJanusWidget doesn't seem to have iterators, so we store a copy...
+ mComponentGUIs.append( compGUI );
+
+ // Set a nice startup size
+ const int deskHeight = QApplication::desktop()->height();
+ int dialogHeight;
+ if (deskHeight > 1000) // very big desktop ?
+ dialogHeight = 800;
+ else if (deskHeight > 650) // big desktop ?
+ dialogHeight = 500;
+ else // small (800x600, 640x480) desktop
+ dialogHeight = 400;
+ QSize sz = scrollView->sizeHint();
+ scrollView->setMinimumSize( sz.width()
+ + scrollView->style().pixelMetric(QStyle::PM_ScrollBarExtent),
+ QMIN( compGUI->sizeHint().height(), dialogHeight ) );
+ }
+}
+
+void Kleo::CryptoConfigModule::save()
+{
+ bool changed = false;
+ QValueList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
+ for( ; it != mComponentGUIs.end(); ++it ) {
+ if ( (*it)->save() )
+ changed = true;
+ }
+ if ( changed )
+ mConfig->sync(true /*runtime*/);
+}
+
+void Kleo::CryptoConfigModule::reset()
+{
+ QValueList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
+ for( ; it != mComponentGUIs.end(); ++it ) {
+ (*it)->load();
+ }
+}
+
+void Kleo::CryptoConfigModule::defaults()
+{
+ QValueList<CryptoConfigComponentGUI *>::Iterator it = mComponentGUIs.begin();
+ for( ; it != mComponentGUIs.end(); ++it ) {
+ (*it)->defaults();
+ }
+}
+
+void Kleo::CryptoConfigModule::cancel()
+{
+ mConfig->clear();
+}
+
+////
+
+Kleo::CryptoConfigComponentGUI::CryptoConfigComponentGUI(
+ CryptoConfigModule* module, Kleo::CryptoConfigComponent* component,
+ QWidget* parent, const char* name )
+ : QWidget( parent, name ),
+ mComponent( component )
+{
+ QGridLayout * glay = new QGridLayout( this, 1, 3, 0, KDialog::spacingHint() );
+ const QStringList groups = mComponent->groupList();
+ if ( groups.size() > 1 ) {
+ glay->setColSpacing( 0, KDHorizontalLine::indentHint() );
+ for ( QStringList::const_iterator it = groups.begin(), end = groups.end() ; it != end; ++it ) {
+ Kleo::CryptoConfigGroup* group = mComponent->group( *it );
+ Q_ASSERT( group );
+ if ( !group )
+ continue;
+ KDHorizontalLine * hl = new KDHorizontalLine( group->description(), this );
+ const int row = glay->numRows();
+ glay->addMultiCellWidget( hl, row, row, 0, 2 );
+ mGroupGUIs.append( new CryptoConfigGroupGUI( module, group, glay, this ) );
+ }
+ } else if ( !groups.empty() ) {
+ mGroupGUIs.append( new CryptoConfigGroupGUI( module, mComponent->group( groups.front() ), glay, this ) );
+ }
+ glay->setRowStretch( glay->numRows(), 1 );
+}
+
+
+bool Kleo::CryptoConfigComponentGUI::save()
+{
+ bool changed = false;
+ QValueList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
+ for( ; it != mGroupGUIs.end(); ++it ) {
+ if ( (*it)->save() )
+ changed = true;
+ }
+ return changed;
+}
+
+void Kleo::CryptoConfigComponentGUI::load()
+{
+ QValueList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
+ for( ; it != mGroupGUIs.end(); ++it )
+ (*it)->load();
+}
+
+void Kleo::CryptoConfigComponentGUI::defaults()
+{
+ QValueList<CryptoConfigGroupGUI *>::Iterator it = mGroupGUIs.begin();
+ for( ; it != mGroupGUIs.end(); ++it )
+ (*it)->defaults();
+}
+
+////
+
+Kleo::CryptoConfigGroupGUI::CryptoConfigGroupGUI(
+ CryptoConfigModule* module, Kleo::CryptoConfigGroup* group,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : QObject( module, name ), mGroup( group )
+{
+ const int startRow = glay->numRows();
+ const QStringList entries = mGroup->entryList();
+ for( QStringList::const_iterator it = entries.begin(), end = entries.end() ; it != end; ++it ) {
+ Kleo::CryptoConfigEntry* entry = group->entry( *it );
+ Q_ASSERT( entry );
+ if ( entry->level() > CryptoConfigEntry::Level_Advanced ) continue;
+ CryptoConfigEntryGUI* entryGUI =
+ CryptoConfigEntryGUIFactory::createEntryGUI( module, entry, *it, glay, widget );
+ if ( entryGUI ) {
+ mEntryGUIs.append( entryGUI );
+ entryGUI->load();
+ }
+ }
+ const int endRow = glay->numRows() - 1;
+ if ( endRow < startRow )
+ return;
+
+ const QString iconName = group->iconName();
+ if ( iconName.isEmpty() )
+ return;
+
+ QLabel * l = new QLabel( widget );
+ l->setPixmap( loadIcon( iconName ) );
+ glay->addMultiCellWidget( l, startRow, endRow, 0, 0, Qt::AlignTop );
+}
+
+bool Kleo::CryptoConfigGroupGUI::save()
+{
+ bool changed = false;
+ QValueList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
+ for( ; it != mEntryGUIs.end(); ++it ) {
+ if ( (*it)->isChanged() ) {
+ (*it)->save();
+ changed = true;
+ }
+ }
+ return changed;
+}
+
+void Kleo::CryptoConfigGroupGUI::load()
+{
+ QValueList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
+ for( ; it != mEntryGUIs.end(); ++it )
+ (*it)->load();
+}
+
+void Kleo::CryptoConfigGroupGUI::defaults()
+{
+ QValueList<CryptoConfigEntryGUI *>::Iterator it = mEntryGUIs.begin();
+ for( ; it != mEntryGUIs.end(); ++it )
+ (*it)->resetToDefault();
+}
+
+////
+
+CryptoConfigEntryGUI* Kleo::CryptoConfigEntryGUIFactory::createEntryGUI( CryptoConfigModule* module, Kleo::CryptoConfigEntry* entry, const QString& entryName, QGridLayout * glay, QWidget* widget, const char* name )
+{
+ if ( entry->isList() ) {
+ switch( entry->argType() ) {
+ case Kleo::CryptoConfigEntry::ArgType_None:
+ // A list of options with no arguments (e.g. -v -v -v) is shown as a spinbox
+ return new CryptoConfigEntrySpinBox( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_Int:
+ case Kleo::CryptoConfigEntry::ArgType_UInt:
+ // Let people type list of numbers (1,2,3....). Untested.
+ return new CryptoConfigEntryLineEdit( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_URL:
+ case Kleo::CryptoConfigEntry::ArgType_Path:
+ case Kleo::CryptoConfigEntry::ArgType_DirPath:
+ case Kleo::CryptoConfigEntry::ArgType_String:
+ kdWarning(5150) << "No widget implemented for list of type " << entry->argType() << endl;
+ return 0; // TODO when the need arises :)
+ case Kleo::CryptoConfigEntry::ArgType_LDAPURL:
+ return new CryptoConfigEntryLDAPURL( module, entry, entryName, glay, widget, name );
+ }
+ kdWarning(5150) << "No widget implemented for list of (unknown) type " << entry->argType() << endl;
+ return 0;
+ }
+
+ switch( entry->argType() ) {
+ case Kleo::CryptoConfigEntry::ArgType_None:
+ return new CryptoConfigEntryCheckBox( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_Int:
+ case Kleo::CryptoConfigEntry::ArgType_UInt:
+ return new CryptoConfigEntrySpinBox( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_URL:
+ return new CryptoConfigEntryURL( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_Path:
+ return new CryptoConfigEntryPath( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_DirPath:
+ return new CryptoConfigEntryDirPath( module, entry, entryName, glay, widget, name );
+ case Kleo::CryptoConfigEntry::ArgType_LDAPURL:
+ kdWarning(5150) << "No widget implemented for type " << entry->argType() << endl;
+ return 0; // TODO when the need arises :)
+ case Kleo::CryptoConfigEntry::ArgType_String:
+ return new CryptoConfigEntryLineEdit( module, entry, entryName, glay, widget, name );
+ }
+ kdWarning(5150) << "No widget implemented for (unknown) type " << entry->argType() << endl;
+ return 0;
+}
+
+////
+
+Kleo::CryptoConfigEntryGUI::CryptoConfigEntryGUI(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ const char* name )
+ : QObject( module, name ), mEntry( entry ), mName( entryName ), mChanged( false )
+{
+ connect( this, SIGNAL( changed() ), module, SIGNAL( changed() ) );
+}
+
+QString Kleo::CryptoConfigEntryGUI::description() const
+{
+ QString descr = mEntry->description();
+ if ( descr.isEmpty() ) // shouldn't happen
+ descr = QString( "<%1>" ).arg( mName );
+ return descr;
+}
+
+void Kleo::CryptoConfigEntryGUI::resetToDefault()
+{
+ mEntry->resetToDefault();
+ load();
+}
+
+////
+
+Kleo::CryptoConfigEntryLineEdit::CryptoConfigEntryLineEdit(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ const int row = glay->numRows();
+ mLineEdit = new KLineEdit( widget );
+ QLabel* label = new QLabel( mLineEdit, description(), widget );
+ glay->addWidget( label, row, 1 );
+ glay->addWidget( mLineEdit, row, 2 );
+ if ( entry->isReadOnly() ) {
+ label->setEnabled( false );
+ mLineEdit->setEnabled( false );
+ } else {
+ connect( mLineEdit, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryLineEdit::doSave()
+{
+ mEntry->setStringValue( mLineEdit->text() );
+}
+
+void Kleo::CryptoConfigEntryLineEdit::doLoad()
+{
+ mLineEdit->setText( mEntry->stringValue() );
+}
+
+////
+
+Kleo::CryptoConfigEntryPath::CryptoConfigEntryPath(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ const int row = glay->numRows();
+ mUrlRequester = new KURLRequester( widget );
+ mUrlRequester->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly );
+ QLabel* label = new QLabel( mUrlRequester, description(), widget );
+ glay->addWidget( label, row, 1 );
+ glay->addWidget( mUrlRequester, row, 2 );
+ if ( entry->isReadOnly() ) {
+ label->setEnabled( false );
+ mUrlRequester->setEnabled( false );
+ } else {
+ connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryPath::doSave()
+{
+ KURL url;
+ url.setPath( mUrlRequester->url() );
+ mEntry->setURLValue( url );
+}
+
+void Kleo::CryptoConfigEntryPath::doLoad()
+{
+ mUrlRequester->setURL( mEntry->urlValue().path() );
+}
+
+////
+
+Kleo::CryptoConfigEntryDirPath::CryptoConfigEntryDirPath(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ const int row = glay->numRows();
+ mUrlRequester = new KURLRequester( widget );
+ mUrlRequester->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
+ QLabel* label = new QLabel( mUrlRequester, description(), widget );
+ glay->addWidget( label, row, 1 );
+ glay->addWidget( mUrlRequester, row, 2 );
+ if ( entry->isReadOnly() ) {
+ label->setEnabled( false );
+ mUrlRequester->setEnabled( false );
+ } else {
+ connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryDirPath::doSave()
+{
+ KURL url;
+ url.setPath( mUrlRequester->url() );
+ mEntry->setURLValue( url );
+
+}
+
+void Kleo::CryptoConfigEntryDirPath::doLoad()
+{
+ mUrlRequester->setURL( mEntry->urlValue().path() );
+}
+
+////
+
+Kleo::CryptoConfigEntryURL::CryptoConfigEntryURL(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ const int row = glay->numRows();
+ mUrlRequester = new KURLRequester( widget );
+ mUrlRequester->setMode( KFile::File | KFile::ExistingOnly );
+ QLabel* label = new QLabel( mUrlRequester, description(), widget );
+ glay->addWidget( label, row, 1 );
+ glay->addWidget( mUrlRequester, row, 2 );
+ if ( entry->isReadOnly() ) {
+ label->setEnabled( false );
+ mUrlRequester->setEnabled( false );
+ } else {
+ connect( mUrlRequester, SIGNAL( textChanged( const QString& ) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryURL::doSave()
+{
+ mEntry->setURLValue( mUrlRequester->url() );
+}
+
+void Kleo::CryptoConfigEntryURL::doLoad()
+{
+ mUrlRequester->setURL( mEntry->urlValue().url() );
+}
+
+////
+
+Kleo::CryptoConfigEntrySpinBox::CryptoConfigEntrySpinBox(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+
+ if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_None && entry->isList() ) {
+ mKind = ListOfNone;
+ } else if ( entry->argType() == Kleo::CryptoConfigEntry::ArgType_UInt ) {
+ mKind = UInt;
+ } else {
+ Q_ASSERT( entry->argType() == Kleo::CryptoConfigEntry::ArgType_Int );
+ mKind = Int;
+ }
+
+ const int row = glay->numRows();
+ mNumInput = new KIntNumInput( widget );
+ QLabel* label = new QLabel( mNumInput, description(), widget );
+ glay->addWidget( label, row, 1 );
+ glay->addWidget( mNumInput, row, 2 );
+
+ if ( entry->isReadOnly() ) {
+ label->setEnabled( false );
+ mNumInput->setEnabled( false );
+ } else {
+ if ( mKind == UInt || mKind == ListOfNone )
+ mNumInput->setMinValue( 0 );
+ connect( mNumInput, SIGNAL( valueChanged(int) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntrySpinBox::doSave()
+{
+ int value = mNumInput->value();
+ switch ( mKind ) {
+ case ListOfNone:
+ mEntry->setNumberOfTimesSet( value );
+ break;
+ case UInt:
+ mEntry->setUIntValue( value );
+ break;
+ case Int:
+ mEntry->setIntValue( value );
+ break;
+ }
+}
+
+void Kleo::CryptoConfigEntrySpinBox::doLoad()
+{
+ int value = 0;
+ switch ( mKind ) {
+ case ListOfNone:
+ value = mEntry->numberOfTimesSet();
+ break;
+ case UInt:
+ value = mEntry->uintValue();
+ break;
+ case Int:
+ value = mEntry->intValue();
+ break;
+ }
+ mNumInput->setValue( value );
+}
+
+////
+
+Kleo::CryptoConfigEntryCheckBox::CryptoConfigEntryCheckBox(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ const int row = glay->numRows();
+ mCheckBox = new QCheckBox( widget );
+ glay->addMultiCellWidget( mCheckBox, row, row, 1, 2 );
+ mCheckBox->setText( description() );
+ if ( entry->isReadOnly() ) {
+ mCheckBox->setEnabled( false );
+ } else {
+ connect( mCheckBox, SIGNAL( toggled(bool) ), SLOT( slotChanged() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryCheckBox::doSave()
+{
+ mEntry->setBoolValue( mCheckBox->isChecked() );
+}
+
+void Kleo::CryptoConfigEntryCheckBox::doLoad()
+{
+ mCheckBox->setChecked( mEntry->boolValue() );
+}
+
+Kleo::CryptoConfigEntryLDAPURL::CryptoConfigEntryLDAPURL(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * glay, QWidget* widget, const char* name )
+ : CryptoConfigEntryGUI( module, entry, entryName, name )
+{
+ mLabel = new QLabel( widget );
+ mPushButton = new QPushButton( i18n( "Edit..." ), widget );
+
+ const int row = glay->numRows();
+ glay->addWidget( new QLabel( mPushButton, description(), widget ), row, 1 );
+ QHBoxLayout * hlay = new QHBoxLayout;
+ glay->addLayout( hlay, row, 2 );
+ hlay->addWidget( mLabel, 1 );
+ hlay->addWidget( mPushButton );
+
+ if ( entry->isReadOnly() ) {
+ mLabel->setEnabled( false );
+ mPushButton->hide();
+ } else {
+ connect( mPushButton, SIGNAL( clicked() ), SLOT( slotOpenDialog() ) );
+ }
+}
+
+void Kleo::CryptoConfigEntryLDAPURL::doLoad()
+{
+ setURLList( mEntry->urlValueList() );
+}
+
+void Kleo::CryptoConfigEntryLDAPURL::doSave()
+{
+ mEntry->setURLValueList( mURLList );
+}
+
+void Kleo::CryptoConfigEntryLDAPURL::slotOpenDialog()
+{
+ // I'm a bad boy and I do it all on the stack. Enough classes already :)
+ // This is just a simple dialog around the directory-services-widget
+ KDialogBase dialog( mPushButton->parentWidget(), 0, true /*modal*/,
+ i18n( "Configure LDAP Servers" ),
+ KDialogBase::Default|KDialogBase::Cancel|KDialogBase::Ok,
+ KDialogBase::Ok, true /*separator*/ );
+ DirectoryServicesWidget* dirserv = new DirectoryServicesWidget( mEntry, &dialog );
+ dirserv->load();
+ dialog.setMainWidget( dirserv );
+ connect( &dialog, SIGNAL( defaultClicked() ), dirserv, SLOT( defaults() ) );
+ if ( dialog.exec() ) {
+ // Note that we just grab the urls from the dialog, we don't call its save method,
+ // since the user hasn't confirmed the big config dialog yet.
+ setURLList( dirserv->urlList() );
+ slotChanged();
+ }
+}
+
+void Kleo::CryptoConfigEntryLDAPURL::setURLList( const KURL::List& urlList )
+{
+ mURLList = urlList;
+ if ( mURLList.isEmpty() )
+ mLabel->setText( i18n( "No server configured yet" ) );
+ else
+ mLabel->setText( i18n( "1 server configured", "%n servers configured", mURLList.count() ) );
+}
+
+#include "cryptoconfigmodule.moc"
+#include "cryptoconfigmodule_p.moc"
diff --git a/certmanager/lib/ui/cryptoconfigmodule.h b/certmanager/lib/ui/cryptoconfigmodule.h
new file mode 100644
index 000000000..185814594
--- /dev/null
+++ b/certmanager/lib/ui/cryptoconfigmodule.h
@@ -0,0 +1,68 @@
+/*
+ cryptoconfigmodule.h
+
+ This file is part of libkleopatra
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CRYPTOCONFIGMODULE_H
+#define CRYPTOCONFIGMODULE_H
+
+#include <kjanuswidget.h>
+
+#include <qvaluelist.h>
+
+namespace Kleo {
+
+ class CryptoConfig;
+ class CryptoConfigComponentGUI;
+
+ /**
+ * Crypto Config Module widget, dynamically generated from CryptoConfig
+ * It's a simple QWidget so that it can be embedded into a dialog or into a KCModule.
+ */
+ class CryptoConfigModule : public KJanusWidget {
+ Q_OBJECT
+ public:
+ CryptoConfigModule( Kleo::CryptoConfig* config, QWidget * parent=0, const char * name=0 );
+
+ void save();
+ void reset(); // i.e. reload current settings, discarding user input
+ void defaults();
+ void cancel();
+
+ signals:
+ void changed();
+
+ private:
+ Kleo::CryptoConfig* mConfig;
+ QValueList<CryptoConfigComponentGUI *> mComponentGUIs;
+ };
+
+}
+
+#endif
diff --git a/certmanager/lib/ui/cryptoconfigmodule_p.h b/certmanager/lib/ui/cryptoconfigmodule_p.h
new file mode 100644
index 000000000..22145f323
--- /dev/null
+++ b/certmanager/lib/ui/cryptoconfigmodule_p.h
@@ -0,0 +1,280 @@
+/*
+ cryptoconfigmodule_p.h
+
+ This file is part of libkleopatra
+ Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License,
+ version 2, as published by the Free Software Foundation.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef CRYPTOCONFIGMODULE_P_H
+#define CRYPTOCONFIGMODULE_P_H
+
+#include <qtabwidget.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kurl.h>
+
+class KLineEdit;
+class KIntNumInput;
+class KURLRequester;
+class QPushButton;
+class QGridLayout;
+
+namespace Kleo {
+
+ class CryptoConfig;
+ class CryptoConfigComponent;
+ class CryptoConfigGroup;
+ class CryptoConfigEntry;
+ class CryptoConfigComponentGUI;
+ class CryptoConfigGroupGUI;
+ class CryptoConfigEntryGUI;
+
+ /**
+ * A widget corresponding to a component in the crypto config
+ */
+ class CryptoConfigComponentGUI : public QWidget {
+ Q_OBJECT
+
+ public:
+ CryptoConfigComponentGUI( CryptoConfigModule* module, Kleo::CryptoConfigComponent* component,
+ QWidget* parent, const char* name = 0 );
+
+ bool save();
+ void load();
+ void defaults();
+
+ private:
+ Kleo::CryptoConfigComponent* mComponent;
+ QValueList<CryptoConfigGroupGUI *> mGroupGUIs;
+ };
+
+ /**
+ * A class managing widgets corresponding to a group in the crypto config
+ */
+ class CryptoConfigGroupGUI : public QObject {
+ Q_OBJECT
+
+ public:
+ CryptoConfigGroupGUI( CryptoConfigModule* module, Kleo::CryptoConfigGroup* group,
+ QGridLayout * layout, QWidget* parent, const char* name = 0 );
+
+ bool save();
+ void load();
+ void defaults();
+
+ private:
+ Kleo::CryptoConfigGroup* mGroup;
+ QValueList<CryptoConfigEntryGUI *> mEntryGUIs;
+ };
+
+ /**
+ * Factory for CryptoConfigEntryGUI instances
+ * Not a real factory, but can become one later.
+ */
+ class CryptoConfigEntryGUIFactory {
+ public:
+ static CryptoConfigEntryGUI* createEntryGUI(
+ CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry, const QString& entryName,
+ QGridLayout * layout, QWidget* widget, const char* name = 0 );
+ };
+
+ /**
+ * Base class for the widget managers tied to an entry in the crypto config
+ */
+ class CryptoConfigEntryGUI : public QObject {
+ Q_OBJECT
+ public:
+ CryptoConfigEntryGUI( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ const char* name = 0 );
+ virtual ~CryptoConfigEntryGUI() {}
+
+ void load() { doLoad(); mChanged = false; }
+ void save() { Q_ASSERT( mChanged ); doSave(); mChanged = false; }
+ void resetToDefault();
+
+ QString description() const;
+ bool isChanged() const { return mChanged; }
+
+ signals:
+ void changed();
+
+ protected slots:
+ void slotChanged() {
+ mChanged = true;
+ emit changed();
+ }
+
+ protected:
+ virtual void doSave() = 0;
+ virtual void doLoad() = 0;
+
+ Kleo::CryptoConfigEntry* mEntry;
+ QString mName;
+ bool mChanged;
+ };
+
+ /**
+ * A widget manager for a string entry in the crypto config
+ */
+ class CryptoConfigEntryLineEdit : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryLineEdit( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ KLineEdit* mLineEdit;
+ };
+
+ /**
+ * A widget manager for a path entry in the crypto config
+ */
+ class CryptoConfigEntryPath : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryPath( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ KURLRequester* mUrlRequester;
+ };
+
+ /**
+ * A widget manager for a directory path entry in the crypto config
+ */
+ class CryptoConfigEntryDirPath : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryDirPath( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ KURLRequester* mUrlRequester;
+ };
+
+ /**
+ * A widget manager for an URL entry in the crypto config
+ */
+ class CryptoConfigEntryURL : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryURL( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ KURLRequester * mUrlRequester;
+ };
+
+ /**
+ * A widget manager for an int/uint entry in the crypto config
+ */
+ class CryptoConfigEntrySpinBox : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntrySpinBox( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ enum { Int, UInt, ListOfNone } mKind;
+ KIntNumInput* mNumInput;
+ };
+
+ /**
+ * A widget manager for a bool entry in the crypto config
+ */
+ class CryptoConfigEntryCheckBox : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryCheckBox( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+ virtual void doSave();
+ virtual void doLoad();
+ private:
+ QCheckBox* mCheckBox;
+ };
+
+ /**
+ * A widget manager for a bool entry in the crypto config
+ */
+ class CryptoConfigEntryLDAPURL : public CryptoConfigEntryGUI {
+ Q_OBJECT
+
+ public:
+ CryptoConfigEntryLDAPURL( CryptoConfigModule* module,
+ Kleo::CryptoConfigEntry* entry,
+ const QString& entryName,
+ QGridLayout * layout,
+ QWidget* parent, const char* name = 0 );
+ virtual void doSave();
+ virtual void doLoad();
+ private slots:
+ void slotOpenDialog();
+ private:
+ void setURLList( const KURL::List& urlList );
+ QLabel* mLabel;
+ QPushButton* mPushButton;
+ KURL::List mURLList;
+ };
+}
+
+#endif // CRYPTOCONFIGMODULE_P_H
diff --git a/certmanager/lib/ui/directoryserviceswidget.cpp b/certmanager/lib/ui/directoryserviceswidget.cpp
new file mode 100644
index 000000000..76c1b3dda
--- /dev/null
+++ b/certmanager/lib/ui/directoryserviceswidget.cpp
@@ -0,0 +1,308 @@
+/*
+ directoryserviceswidget.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klar�vdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include <config.h>
+
+#include "directoryserviceswidget.h"
+#include "adddirectoryservicedialogimpl.h"
+#include "cryptplugwrapper.h"
+
+#include <klineedit.h>
+#include <kleo/cryptoconfig.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+
+#include <qbuttongroup.h>
+#include <qtoolbutton.h>
+#include <qlistview.h>
+#include <qpushbutton.h>
+
+using namespace Kleo;
+
+class QX500ListViewItem : public QListViewItem
+{
+public:
+ QX500ListViewItem( QListView* lv, QListViewItem* prev,
+ const QString& serverName,
+ const QString& portNumber,
+ const QString& dn,
+ const QString& username,
+ const QString& password )
+ : QListViewItem( lv, prev, serverName, portNumber, dn, username ) {
+ setPassword( password );
+ }
+
+ void setPassword( const QString& pass ) {
+ mPassword = pass;
+ setText( 4, pass.isEmpty() ? QString::null : QString::fromLatin1( "******" ) );
+ }
+
+ const QString& password() const { return mPassword; }
+
+ void setData( const QString& serverName,
+ const QString& portNumber,
+ const QString& dn,
+ const QString& username,
+ const QString& password ) {
+ setText( 0, serverName );
+ setText( 1, portNumber );
+ setText( 2, dn );
+ setText( 3, username );
+ setPassword( password );
+ }
+
+ void copyItem( QX500ListViewItem* item ) {
+ for ( unsigned int i = 0; i < 4 ; ++i )
+ setText( i, item->text( i ) );
+ setPassword( item->password() );
+ }
+
+private:
+ QString mPassword;
+};
+
+Kleo::DirectoryServicesWidget::DirectoryServicesWidget(
+ Kleo::CryptoConfigEntry* configEntry,
+ QWidget* parent, const char* name, WFlags fl )
+ : DirectoryServicesWidgetBase( parent, name, fl ),
+ mConfigEntry( configEntry )
+{
+ x500LV->setSorting( -1 );
+
+ // taken from kmail's configuredialog.cpp
+ upButton->setIconSet( BarIconSet( "up", KIcon::SizeSmall ) );
+ upButton->setEnabled( false ); // b/c no item is selected yet
+
+ downButton->setIconSet( BarIconSet( "down", KIcon::SizeSmall ) );
+ downButton->setEnabled( false ); // b/c no item is selected yet
+}
+
+
+/*
+ * Destroys the object and frees any allocated resources
+ */
+DirectoryServicesWidget::~DirectoryServicesWidget()
+{
+ // no need to delete child widgets, Qt does it all for us
+}
+
+
+/**
+ Enables or disables the widgets in this dialog according to the
+ capabilities of the current plugin passed as a parameter.
+*/
+void DirectoryServicesWidget::enableDisable( CryptPlugWrapper* cryptPlug ) // unused?
+{
+ // disable the whole page if the plugin does not support the use
+ // of directory services
+ setEnabled( cryptPlug->hasFeature( Feature_CertificateDirectoryService ) ||
+ cryptPlug->hasFeature( Feature_CRLDirectoryService ) );
+}
+
+
+/*
+ * protected slot, connected to selectionChanged()
+ */
+void DirectoryServicesWidget::slotServiceChanged( QListViewItem* item )
+{
+ if( item )
+ removeServicePB->setEnabled( true );
+ else
+ removeServicePB->setEnabled( false );
+ downButton->setEnabled( item && item->itemBelow() );
+ upButton->setEnabled( item && item->itemAbove() );
+}
+
+
+/*
+ * protected slot, connected to returnPressed/doubleClicked
+ */
+void DirectoryServicesWidget::slotServiceSelected( QListViewItem* item )
+{
+ AddDirectoryServiceDialogImpl* dlg = new AddDirectoryServiceDialogImpl( this );
+ dlg->serverNameED->setText( item->text( 0 ) );
+ dlg->portED->setText( item->text( 1 ) );
+ dlg->descriptionED->setText( item->text( 2 ) );
+ dlg->usernameED->setText( item->text( 3 ) );
+ QString pass = static_cast<QX500ListViewItem *>( item )->password();
+ dlg->passwordED->setText( pass );
+
+ if( dlg->exec() == QDialog::Accepted ) {
+ item->setText( 0, dlg->serverNameED->text() );
+ item->setText( 1, dlg->portED->text() );
+ item->setText( 2, dlg->descriptionED->text() );
+ item->setText( 3, dlg->usernameED->text() );
+ static_cast<QX500ListViewItem *>( item )->setPassword( dlg->passwordED->text() );
+ emit changed();
+ }
+ delete dlg;
+}
+
+
+/*
+ * protected slot
+ */
+void DirectoryServicesWidget::slotAddService()
+{
+ AddDirectoryServiceDialogImpl* dlg = new AddDirectoryServiceDialogImpl( this );
+ if( dlg->exec() == QDialog::Accepted ) {
+ QX500ListViewItem *item = new QX500ListViewItem( x500LV, x500LV->lastItem(),
+ dlg->serverNameED->text(),
+ dlg->portED->text(),
+ dlg->descriptionED->text(),
+ dlg->usernameED->text(),
+ dlg->passwordED->text() );
+ slotServiceChanged(item);
+ emit changed();
+ }
+ delete dlg;
+}
+
+/*
+ * protected slot
+ */
+void DirectoryServicesWidget::slotDeleteService()
+{
+ QListViewItem* item = x500LV->selectedItem();
+ Q_ASSERT( item );
+ if( !item )
+ return;
+ else
+ delete item;
+ x500LV->triggerUpdate();
+ item = x500LV->currentItem();
+ x500LV->setCurrentItem( item ); // seems necessary...
+ x500LV->setSelected( item, true );
+ emit changed();
+}
+
+
+void DirectoryServicesWidget::setInitialServices( const KURL::List& urls )
+{
+ x500LV->clear();
+ for( KURL::List::const_iterator it = urls.begin(); it != urls.end(); ++it ) {
+ QString dn = KURL::decode_string( (*it).query().mid( 1 ) ); // decode query and skip leading '?'
+ (void)new QX500ListViewItem( x500LV, x500LV->lastItem(),
+ (*it).host(),
+ QString::number( (*it).port() ),
+ dn,
+ (*it).user(),
+ (*it).pass());
+ }
+}
+
+KURL::List DirectoryServicesWidget::urlList() const
+{
+ KURL::List lst;
+ QListViewItemIterator it( x500LV );
+ for ( ; it.current() ; ++it ) {
+ QListViewItem* item = it.current();
+ KURL url;
+ url.setProtocol( "ldap" );
+ url.setHost( item->text( 0 ) );
+ url.setPort( item->text( 1 ).toInt() );
+ url.setPath( "/" ); // workaround KURL parsing bug
+ url.setQuery( item->text( 2 ) );
+ url.setUser( item->text( 3 ) );
+ url.setPass( static_cast<QX500ListViewItem *>( item )->password() );
+ kdDebug() << url << endl;
+ lst << url;
+ }
+ return lst;
+}
+
+void DirectoryServicesWidget::clear()
+{
+ x500LV->clear();
+ emit changed();
+}
+
+void DirectoryServicesWidget::load()
+{
+ if ( mConfigEntry ) {
+ setInitialServices( mConfigEntry->urlValueList() );
+ }
+}
+
+void DirectoryServicesWidget::save()
+{
+ if ( mConfigEntry ) {
+ mConfigEntry->setURLValueList( urlList() );
+ }
+}
+
+void DirectoryServicesWidget::defaults()
+{
+ if ( mConfigEntry ) {
+ // resetToDefault doesn't work since gpgconf doesn't know any defaults for this entry.
+ //mConfigEntry->resetToDefault();
+ //load();
+ clear(); // the default is an empty list.
+ }
+}
+
+static void swapItems( QX500ListViewItem *item, QX500ListViewItem *other )
+{
+ QString serverName = item->text( 0 );
+ QString portNumber = item->text( 1 );
+ QString dn = item->text( 2 );
+ QString username = item->text( 3 );
+ QString password = item->password();
+ item->copyItem( other );
+ other->setData( serverName, portNumber, dn, username, password );
+}
+
+void Kleo::DirectoryServicesWidget::slotMoveUp()
+{
+ QX500ListViewItem *item = static_cast<QX500ListViewItem *>( x500LV->selectedItem() );
+ if ( !item ) return;
+ QX500ListViewItem *above = static_cast<QX500ListViewItem *>( item->itemAbove() );
+ if ( !above ) return;
+ swapItems( item, above );
+ x500LV->setCurrentItem( above );
+ x500LV->setSelected( above, true );
+ emit changed();
+}
+
+void Kleo::DirectoryServicesWidget::slotMoveDown()
+{
+ QX500ListViewItem *item = static_cast<QX500ListViewItem *>( x500LV->selectedItem() );
+ if ( !item ) return;
+ QX500ListViewItem *below = static_cast<QX500ListViewItem *>( item->itemBelow() );
+ if ( !below ) return;
+ swapItems( item, below );
+ x500LV->setCurrentItem( below );
+ x500LV->setSelected( below, true );
+ emit changed();
+}
+
+#include "directoryserviceswidget.moc"
diff --git a/certmanager/lib/ui/directoryserviceswidget.h b/certmanager/lib/ui/directoryserviceswidget.h
new file mode 100644
index 000000000..02e428c95
--- /dev/null
+++ b/certmanager/lib/ui/directoryserviceswidget.h
@@ -0,0 +1,82 @@
+/*
+ directoryserviceswidget.h
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef DIRECTORYSERVICESWIDGET_H
+#define DIRECTORYSERVICESWIDGET_H
+#include "directoryserviceswidgetbase.h"
+#include <kurl.h>
+#include <kdepimmacros.h>
+
+class CryptPlugWrapper;
+namespace Kleo {
+
+class CryptoConfigEntry;
+
+class KDE_EXPORT DirectoryServicesWidget : public DirectoryServicesWidgetBase
+{
+ Q_OBJECT
+
+public:
+ DirectoryServicesWidget(
+ Kleo::CryptoConfigEntry* configEntry,
+ QWidget* parent = 0, const char* name = 0, WFlags fl = 0 );
+ ~DirectoryServicesWidget();
+
+ void load();
+ void save();
+
+ void enableDisable( CryptPlugWrapper* wrapper ); // unused?
+ void setInitialServices( const KURL::List& urls );
+ KURL::List urlList() const;
+ void clear();
+
+public slots:
+ void defaults();
+
+signals:
+ void changed();
+
+protected slots:
+ void slotServiceChanged( QListViewItem* );
+ void slotServiceSelected( QListViewItem* );
+ void slotAddService();
+ void slotDeleteService();
+ void slotMoveUp();
+ void slotMoveDown();
+
+private:
+ Kleo::CryptoConfigEntry* mConfigEntry;
+};
+
+}
+
+#endif // DIRECTORYSERVICESWIDGET_H
diff --git a/certmanager/lib/ui/directoryserviceswidgetbase.ui b/certmanager/lib/ui/directoryserviceswidgetbase.ui
new file mode 100644
index 000000000..1dabbca51
--- /dev/null
+++ b/certmanager/lib/ui/directoryserviceswidgetbase.ui
@@ -0,0 +1,342 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>DirectoryServicesWidgetBase</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>DirectoryServicesWidgetBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>576</width>
+ <height>363</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Directory Services Configuration</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>x500LA</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Plain</enum>
+ </property>
+ <property name="text">
+ <string>X.&amp;500 directory services:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>x500LV</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QListView">
+ <column>
+ <property name="text">
+ <string>Server Name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Port</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Base DN</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>User Name</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Password</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>x500LV</cstring>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Select Directory Services to Use Here</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;
+&lt;h1&gt;X.500 Directory Services&lt;/h1&gt;
+You can use X.500 directory services to retrieve certificates and certificate revocation lists that are not saved locally. Ask your local administrator if you want to make use of this feature and are unsure which directory service you can use.
+&lt;p&gt;
+If you do not use a directory service, you can still use local certificates.
+&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout1</cstring>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>upButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QToolButton">
+ <property name="name">
+ <cstring>downButton</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>51</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLayoutWidget">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>47</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>addServicePB</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add Service...</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Click to add a service</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;
+&lt;h1&gt;Add a Directory Service&lt;/h1&gt;
+By clicking this button, you can select a new directory service to be used for retrieving certificates and CRLs. You will be asked for the server name and an optional description.
+&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer11</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>47</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>removeServicePB</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Remove Service</string>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Click to remove the currently selected service</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>&lt;qt&gt;
+&lt;h1&gt;Remove Directory Service&lt;/h1&gt;
+By clicking this button, you can remove the currently selected directory service in the list above. You will have a chance to rethink your decision before the entry is deleted from the list.
+&lt;/qt&gt;</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>47</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </hbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>16</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>removeServicePB</sender>
+ <signal>clicked()</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotDeleteService()</slot>
+ </connection>
+ <connection>
+ <sender>x500LV</sender>
+ <signal>returnPressed(QListViewItem*)</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotServiceSelected(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>x500LV</sender>
+ <signal>doubleClicked(QListViewItem*)</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotServiceSelected(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>x500LV</sender>
+ <signal>selectionChanged(QListViewItem*)</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotServiceChanged(QListViewItem*)</slot>
+ </connection>
+ <connection>
+ <sender>addServicePB</sender>
+ <signal>clicked()</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotAddService()</slot>
+ </connection>
+ <connection>
+ <sender>upButton</sender>
+ <signal>clicked()</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotMoveUp()</slot>
+ </connection>
+ <connection>
+ <sender>downButton</sender>
+ <signal>clicked()</signal>
+ <receiver>DirectoryServicesWidgetBase</receiver>
+ <slot>slotMoveDown()</slot>
+ </connection>
+</connections>
+<slots>
+ <slot access="protected">slotAddService()</slot>
+ <slot access="protected">slotDeleteService()</slot>
+ <slot access="protected">slotServiceChanged( QListViewItem* )</slot>
+ <slot access="protected">slotServiceSelected( QListViewItem* )</slot>
+ <slot access="protected">slotMoveUp()</slot>
+ <slot access="protected">slotMoveDown()</slot>
+</slots>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/certmanager/lib/ui/dnattributeorderconfigwidget.cpp b/certmanager/lib/ui/dnattributeorderconfigwidget.cpp
new file mode 100644
index 000000000..54fe32af1
--- /dev/null
+++ b/certmanager/lib/ui/dnattributeorderconfigwidget.cpp
@@ -0,0 +1,309 @@
+/* -*- c++ -*-
+ dnattributeorderconfigwidget.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klar�vdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "dnattributeorderconfigwidget.h"
+
+#include "kleo/dn.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+#include <kdialog.h>
+#include <kiconloader.h>
+#include <kconfig.h>
+#include <kapplication.h>
+
+#include <qtoolbutton.h>
+#include <qlayout.h>
+#include <qheader.h>
+#include <qlabel.h>
+#include <qlistview.h>
+#include <qtooltip.h>
+
+#include <assert.h>
+
+struct Kleo::DNAttributeOrderConfigWidget::Private {
+ enum { UUp=0, Up=1, Left=2, Right=3, Down=4, DDown=5 };
+
+ QListView * availableLV;
+ QListView * currentLV;
+ QToolButton * navTB[6];
+
+ QListViewItem * placeHolderItem;
+
+ Kleo::DNAttributeMapper * mapper;
+};
+
+static void prepare( QListView * lv ) {
+ lv->setAllColumnsShowFocus( true );
+ lv->setResizeMode( QListView::LastColumn );
+ lv->header()->setClickEnabled( false );
+ lv->addColumn( QString::null );
+ lv->addColumn( i18n("Description") );
+}
+
+Kleo::DNAttributeOrderConfigWidget::DNAttributeOrderConfigWidget( DNAttributeMapper * mapper, QWidget * parent, const char * name, WFlags f )
+ : QWidget( parent, name, f ), d( 0 )
+{
+ assert( mapper );
+ d = new Private();
+ d->mapper = mapper;
+
+ QGridLayout * glay = new QGridLayout( this, 2, 3, 0, KDialog::spacingHint() );
+ glay->setColStretch( 0, 1 );
+ glay->setColStretch( 2, 1 );
+
+ int row = -1;
+
+ ++row;
+ glay->addWidget( new QLabel( i18n("Available attributes:"), this ), row, 0 );
+ glay->addWidget( new QLabel( i18n("Current attribute order:"), this ), row, 2 );
+
+
+ ++row;
+ glay->setRowStretch( row, 1 );
+
+ d->availableLV = new QListView( this );
+ prepare( d->availableLV );
+ d->availableLV->setSorting( 0 );
+ glay->addWidget( d->availableLV, row, 0 );
+
+ d->currentLV = new QListView( this );
+ prepare( d->currentLV );
+ d->currentLV->setSorting( -1 );
+ glay->addWidget( d->currentLV, row, 2 );
+
+ connect( d->availableLV, SIGNAL(clicked( QListViewItem * )),
+ SLOT(slotAvailableSelectionChanged(QListViewItem*)) );
+ connect( d->currentLV, SIGNAL(clicked(QListViewItem*)),
+ SLOT(slotCurrentOrderSelectionChanged(QListViewItem*)) );
+
+ d->placeHolderItem = new QListViewItem( d->availableLV, "_X_", i18n("All others") );
+
+ // the up/down/left/right arrow cross:
+
+ QGridLayout * xlay = new QGridLayout( 5, 3, 0, "xlay" );
+ xlay->setAlignment( AlignCenter );
+
+ static const struct {
+ const char * icon;
+ int row, col;
+ const char * tooltip;
+ const char * slot;
+ } navButtons[] = {
+ { "2uparrow", 0, 1, I18N_NOOP( "Move to top" ), SLOT(slotDoubleUpButtonClicked()) },
+ { "1uparrow", 1, 1, I18N_NOOP( "Move one up" ), SLOT(slotUpButtonClicked()) },
+ { "1leftarrow", 2, 0, I18N_NOOP( "Remove from current attribute order" ), SLOT(slotLeftButtonClicked()) },
+ { "1rightarrow", 2, 2, I18N_NOOP( "Add to current attribute order" ), SLOT(slotRightButtonClicked()) },
+ { "1downarrow", 3, 1, I18N_NOOP( "Move one down" ), SLOT(slotDownButtonClicked()) },
+ { "2downarrow", 4, 1, I18N_NOOP( "Move to bottom" ), SLOT(slotDoubleDownButtonClicked()) }
+ };
+
+ for ( unsigned int i = 0 ; i < sizeof navButtons / sizeof *navButtons ; ++i ) {
+ QToolButton * tb = d->navTB[i] = new QToolButton( this );
+ tb->setIconSet( SmallIconSet( navButtons[i].icon ) );
+ tb->setEnabled( false );
+ QToolTip::add( tb, i18n( navButtons[i].tooltip ) );
+ xlay->addWidget( tb, navButtons[i].row, navButtons[i].col );
+ connect( tb, SIGNAL(clicked()), navButtons[i].slot );
+ }
+
+ glay->addLayout( xlay, row, 1 );
+}
+
+Kleo::DNAttributeOrderConfigWidget::~DNAttributeOrderConfigWidget() {
+ delete d; d = 0;
+}
+
+void Kleo::DNAttributeOrderConfigWidget::load() {
+ // save the _X_ item:
+ takePlaceHolderItem();
+ // clear the rest:
+ d->availableLV->clear();
+ d->currentLV->clear();
+
+ const QStringList order = d->mapper->attributeOrder();
+
+ // fill the RHS listview:
+ QListViewItem * last = 0;
+ for ( QStringList::const_iterator it = order.begin() ; it != order.end() ; ++it ) {
+ const QString attr = (*it).upper();
+ if ( attr == "_X_" ) {
+ takePlaceHolderItem();
+ d->currentLV->insertItem( d->placeHolderItem );
+ d->placeHolderItem->moveItem( last );
+ last = d->placeHolderItem;
+ } else
+ last = new QListViewItem( d->currentLV, last, attr, d->mapper->name2label( attr ) );
+ }
+
+ // fill the LHS listview with what's left:
+
+ const QStringList all = Kleo::DNAttributeMapper::instance()->names();
+ for ( QStringList::const_iterator it = all.begin() ; it != all.end() ; ++it )
+ if ( order.find( *it ) == order.end() )
+ (void)new QListViewItem( d->availableLV, *it, d->mapper->name2label( *it ) );
+
+ if ( !d->placeHolderItem->listView() )
+ d->availableLV->insertItem( d->placeHolderItem );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::takePlaceHolderItem() {
+ if ( QListView * lv = d->placeHolderItem->listView() )
+ lv->takeItem( d->placeHolderItem );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::save() const {
+ QStringList order;
+ for ( QListViewItemIterator it( d->currentLV ) ; it.current() ; ++it )
+ order.push_back( it.current()->text( 0 ) );
+
+ d->mapper->setAttributeOrder( order );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::defaults() {
+ kdDebug() << "Sorry, not implemented: Kleo::DNAttributeOrderConfigWidget::defaults()" << endl;
+}
+
+
+
+void Kleo::DNAttributeOrderConfigWidget::slotAvailableSelectionChanged( QListViewItem * item ) {
+ d->navTB[Private::Right]->setEnabled( item );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotCurrentOrderSelectionChanged( QListViewItem * item ) {
+ enableDisableButtons( item );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::enableDisableButtons( QListViewItem * item ) {
+ d->navTB[Private::UUp ]->setEnabled( item && item->itemAbove() );
+ d->navTB[Private::Up ]->setEnabled( item && item->itemAbove() );
+ d->navTB[Private::Left ]->setEnabled( item );
+ d->navTB[Private::Down ]->setEnabled( item && item->itemBelow() );
+ d->navTB[Private::DDown]->setEnabled( item && item->itemBelow() );
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotUpButtonClicked() {
+ QListViewItem * item = d->currentLV->selectedItem();
+ if ( !item )
+ return;
+ QListViewItem * above = item->itemAbove();
+ if ( !above )
+ return;
+ above->moveItem( item ); // moves "above" to after "item", ie. "item" one up
+ enableDisableButtons( item );
+ emit changed();
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotDoubleUpButtonClicked() {
+ QListViewItem * item = d->currentLV->selectedItem();
+ if ( !item )
+ return;
+ if ( item == d->currentLV->firstChild() )
+ return;
+ d->currentLV->takeItem( item );
+ d->currentLV->insertItem( item );
+ d->currentLV->setSelected( item, true );
+ enableDisableButtons( item );
+ emit changed();
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotDownButtonClicked() {
+ QListViewItem * item = d->currentLV->selectedItem();
+ if ( !item )
+ return;
+ QListViewItem * below = item->itemBelow();
+ if ( !below )
+ return;
+ item->moveItem( below ); // moves "item" to after "below", ie. "item" one down
+ enableDisableButtons( item );
+ emit changed();
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotDoubleDownButtonClicked() {
+ QListViewItem * item = d->currentLV->selectedItem();
+ if ( !item )
+ return;
+ QListViewItem * last = d->currentLV->lastItem();
+ assert( last );
+ if ( item == last )
+ return;
+ item->moveItem( last ); // moves "item" to after "last", ie. to the bottom
+ enableDisableButtons( item );
+ emit changed();
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotLeftButtonClicked() {
+ QListViewItem * right = d->currentLV->selectedItem();
+ if ( !right )
+ return;
+ QListViewItem * next = right->itemBelow();
+ if ( !next )
+ next = right->itemAbove();
+ d->currentLV->takeItem( right );
+ d->availableLV->insertItem( right );
+ if ( next )
+ d->currentLV->setSelected( next, true );
+ enableDisableButtons( next );
+ emit changed();
+}
+
+void Kleo::DNAttributeOrderConfigWidget::slotRightButtonClicked() {
+ QListViewItem * left = d->availableLV->selectedItem();
+ if ( !left )
+ return;
+ QListViewItem * next = left->itemBelow();
+ if ( !next )
+ next = left->itemAbove();
+ d->availableLV->takeItem( left );
+ d->currentLV->insertItem( left );
+ if ( QListViewItem * right = d->currentLV->selectedItem() ) {
+ if ( QListViewItem * above = right->itemAbove() )
+ left->moveItem( above ); // move new item immediately before old selected
+ d->currentLV->setSelected( right, false );
+ }
+ d->currentLV->setSelected( left, true );
+ enableDisableButtons( left );
+ d->navTB[Private::Right]->setEnabled( next );
+ if ( next )
+ d->availableLV->setSelected( next, true );
+ emit changed();
+}
+
+
+
+void Kleo::DNAttributeOrderConfigWidget::virtual_hook( int, void* ) {}
+
+#include "dnattributeorderconfigwidget.moc"
diff --git a/certmanager/lib/ui/dnattributeorderconfigwidget.h b/certmanager/lib/ui/dnattributeorderconfigwidget.h
new file mode 100644
index 000000000..11299ab37
--- /dev/null
+++ b/certmanager/lib/ui/dnattributeorderconfigwidget.h
@@ -0,0 +1,87 @@
+/* -*- c++ -*-
+ dnattributeorderconfigwidget.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+ */
+
+#ifndef __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__
+#define __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__
+
+#include <qwidget.h>
+#include <kdepimmacros.h>
+namespace Kleo {
+ class DNAttributeMapper;
+}
+
+class QListViewItem;
+
+namespace Kleo {
+
+ class KDE_EXPORT DNAttributeOrderConfigWidget : public QWidget {
+ Q_OBJECT
+ public:
+ /*! Use Kleo::DNAttributeMapper::instance()->configWidget( parent, name ) instead. */
+ DNAttributeOrderConfigWidget( DNAttributeMapper * mapper, QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~DNAttributeOrderConfigWidget();
+
+ void load();
+ void save() const;
+ void defaults();
+
+ signals:
+ void changed();
+
+ //
+ // only boring stuff below...
+ //
+
+ private slots:
+ void slotAvailableSelectionChanged( QListViewItem * );
+ void slotCurrentOrderSelectionChanged( QListViewItem * );
+ void slotDoubleUpButtonClicked();
+ void slotUpButtonClicked();
+ void slotDownButtonClicked();
+ void slotDoubleDownButtonClicked();
+ void slotLeftButtonClicked();
+ void slotRightButtonClicked();
+
+ private:
+ void takePlaceHolderItem();
+ void enableDisableButtons( QListViewItem * );
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ virtual void virtual_hook( int, void* );
+ };
+
+}
+
+#endif // __KLEO_UI_DNATTRIBUTEORDERCONFIGWIDGET_H__
diff --git a/certmanager/lib/ui/kdhorizontalline.cpp b/certmanager/lib/ui/kdhorizontalline.cpp
new file mode 100644
index 000000000..83b92a19b
--- /dev/null
+++ b/certmanager/lib/ui/kdhorizontalline.cpp
@@ -0,0 +1,171 @@
+/* -*- Mode: C++ -*-
+ KD Tools - a set of useful widgets for Qt
+*/
+
+/****************************************************************************
+** Copyright (C) 2005 Klarälvdalens Datakonsult AB. All rights reserved.
+**
+** This file is part of the KD Tools library.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid commercial KD Tools licenses may use this file in
+** accordance with the KD Tools Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.klaralvdalens-datakonsult.se/?page=products for
+** information about KD Tools Commercial License Agreements.
+**
+** Contact info@klaralvdalens-datakonsult.se if any conditions of this
+** licensing are not clear to you.
+**
+** In addition, as a special exception, the copyright holders give
+** permission to link the code of this program with any edition of the
+** Qt library by Trolltech AS, Norway (or with modified versions of Qt
+** that use the same license as Qt), and distribute linked
+** combinations including the two. You must obey the GNU General
+** Public License in all respects for all of the code used other than
+** Qt. If you modify this file, you may extend this exception to your
+** version of the file, but you are not obligated to do so. If you do
+** not wish to do so, delete this exception statement from your
+** version.
+**
+**********************************************************************/
+
+#include "kdhorizontalline.h"
+
+#include <qstyle.h>
+#include <qpainter.h>
+#ifdef QT_ACCESSIBILITY_SUPPORT
+#include <qaccessible.h>
+#endif
+#include <qfontmetrics.h>
+#include <qapplication.h>
+
+KDHorizontalLine::KDHorizontalLine( QWidget * parent, const char * name, WFlags f )
+ : QFrame( parent, name, f ),
+ mAlign( Qt::AlignAuto ),
+ mLenVisible( 0 )
+{
+ QFrame::setFrameStyle( HLine | Sunken );
+}
+
+KDHorizontalLine::KDHorizontalLine( const QString & title, QWidget * parent, const char * name, WFlags f )
+ : QFrame( parent, name, f ),
+ mAlign( Qt::AlignAuto ),
+ mLenVisible( 0 )
+{
+ QFrame::setFrameStyle( HLine | Sunken );
+ setTitle( title );
+}
+
+KDHorizontalLine::~KDHorizontalLine() {}
+
+void KDHorizontalLine::setFrameStyle( int style ) {
+ QFrame::setFrameStyle( ( style & ~MShape ) | HLine ); // force HLine
+}
+
+void KDHorizontalLine::setTitle( const QString & title ) {
+ if ( mTitle == title )
+ return;
+ mTitle = title;
+ calculateFrame();
+ update();
+ updateGeometry();
+#ifdef QT_ACCESSIBILITY_SUPPORT
+ QAccessible::updateAccessibility( this, 0, QAccessible::NameChanged );
+#endif
+}
+
+void KDHorizontalLine::calculateFrame() {
+ mLenVisible = mTitle.length();
+#if 0
+ if ( mLenVisible ) {
+ const QFontMetrics fm = fontMetrics();
+ while ( mLenVisible ) {
+ const int tw = fm.width( mTitle, mLenVisible ) + 4*fm.width(QChar(' '));
+ if ( tw < width() )
+ break;
+ mLenVisible--;
+ }
+ qDebug( "mLenVisible = %d (of %d)", mLenVisible, mTitle.length() );
+ if ( mLenVisible ) { // but do we also have a visible label?
+ QRect r = rect();
+ const int va = style().styleHint( QStyle::SH_GroupBox_TextLabelVerticalAlignment, this );
+ if( va & AlignVCenter )
+ r.setTop( fm.height() / 2 ); // frame rect should be
+ else if( va & AlignTop )
+ r.setTop( fm.ascent() );
+ setFrameRect( r ); // smaller than client rect
+ return;
+ }
+ }
+ // no visible label
+ setFrameRect( QRect(0,0,0,0) ); // then use client rect
+#endif
+}
+
+QSizePolicy KDHorizontalLine::sizePolicy() const {
+ return QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
+}
+
+QSize KDHorizontalLine::sizeHint() const {
+ return minimumSizeHint();
+}
+
+QSize KDHorizontalLine::minimumSizeHint() const {
+ const int w = fontMetrics().width( mTitle, mLenVisible ) +
+ fontMetrics().width( QChar( ' ' ) );
+ const int h = fontMetrics().height();
+ return QSize( QMAX( w, indentHint() ), h ).expandedTo( qApp->globalStrut() );
+}
+
+void KDHorizontalLine::paintEvent( QPaintEvent * e ) {
+ QPainter paint( this );
+
+ if ( mLenVisible ) { // draw title
+ const QFontMetrics & fm = paint.fontMetrics();
+ const int h = fm.height();
+ const int tw = fm.width( mTitle, mLenVisible ) + fm.width(QChar(' '));
+ int x;
+ if ( mAlign & AlignHCenter ) // center alignment
+ x = frameRect().width()/2 - tw/2;
+ else if ( mAlign & AlignRight ) // right alignment
+ x = frameRect().width() - tw;
+ else if ( mAlign & AlignLeft ) // left alignment
+ x = 0;
+ else { // auto align
+ if( QApplication::reverseLayout() )
+ x = frameRect().width() - tw;
+ else
+ x = 0;
+ }
+ QRect r( x, 0, tw, h );
+ int va = style().styleHint( QStyle::SH_GroupBox_TextLabelVerticalAlignment, this );
+ if ( va & AlignTop )
+ r.moveBy( 0, fm.descent() );
+ const QColor pen( (QRgb) style().styleHint( QStyle::SH_GroupBox_TextLabelColor, this ) );
+#if QT_VERSION >= 0x030300
+ if ( !style().styleHint( QStyle::SH_UnderlineAccelerator, this ) )
+ va |= NoAccel;
+#endif
+ style().drawItem( &paint, r, ShowPrefix | AlignHCenter | va, colorGroup(),
+ isEnabled(), 0, mTitle, -1, ownPalette() ? 0 : &pen );
+ paint.setClipRegion( e->region().subtract( r ) ); // clip everything but title
+ }
+ drawFrame( &paint );
+ drawContents( &paint );
+}
+
+// static
+int KDHorizontalLine::indentHint() {
+ return 30;
+}
+
+#include "kdhorizontalline.moc"
diff --git a/certmanager/lib/ui/kdhorizontalline.h b/certmanager/lib/ui/kdhorizontalline.h
new file mode 100644
index 000000000..a79682ebd
--- /dev/null
+++ b/certmanager/lib/ui/kdhorizontalline.h
@@ -0,0 +1,82 @@
+/* -*- Mode: C++ -*-
+ KD Tools - a set of useful widgets for Qt
+*/
+
+/****************************************************************************
+** Copyright (C) 2005 Klarälvdalens Datakonsult AB. All rights reserved.
+**
+** This file is part of the KD Tools library.
+**
+** This file may be distributed and/or modified under the terms of the
+** GNU General Public License version 2 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.
+**
+** Licensees holding valid commercial KD Tools licenses may use this file in
+** accordance with the KD Tools Commercial License Agreement provided with
+** the Software.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+** See http://www.klaralvdalens-datakonsult.se/?page=products for
+** information about KD Tools Commercial License Agreements.
+**
+** Contact info@klaralvdalens-datakonsult.se if any conditions of this
+** licensing are not clear to you.
+**
+** In addition, as a special exception, the copyright holders give
+** permission to link the code of this program with any edition of the
+** Qt library by Trolltech AS, Norway (or with modified versions of Qt
+** that use the same license as Qt), and distribute linked
+** combinations including the two. You must obey the GNU General
+** Public License in all respects for all of the code used other than
+** Qt. If you modify this file, you may extend this exception to your
+** version of the file, but you are not obligated to do so. If you do
+** not wish to do so, delete this exception statement from your
+** version.
+**
+**********************************************************************/
+
+#ifndef __KDTOOLS__KDHORIZONTALLINE_H__
+#define __KDTOOLS__KDHORIZONTALLINE_H__
+
+#include <qframe.h>
+#include <qstring.h>
+
+class KDHorizontalLine : public QFrame {
+ Q_OBJECT
+ Q_PROPERTY( QString title READ title WRITE setTitle )
+public:
+ KDHorizontalLine( QWidget * parent=0, const char * name=0, WFlags f=0 );
+ KDHorizontalLine( const QString & title, QWidget * parent=0, const char * name=0, WFlags f=0 );
+ ~KDHorizontalLine();
+
+ QString title() const { return mTitle; }
+
+ /*! \reimp to hard-code the frame shape */
+ void setFrameStyle( int style );
+
+ QSize sizeHint() const;
+ QSize minimumSizeHint() const;
+ QSizePolicy sizePolicy() const;
+
+ static int indentHint();
+
+public slots:
+ virtual void setTitle( const QString & title );
+
+protected:
+ void paintEvent( QPaintEvent * );
+
+private:
+ void calculateFrame();
+
+private:
+ QString mTitle;
+ Qt::AlignmentFlags mAlign;
+ int mLenVisible;
+};
+
+#endif /* __KDTOOLS__KDHORIZONTALLINE_H__ */
+
diff --git a/certmanager/lib/ui/keyapprovaldialog.cpp b/certmanager/lib/ui/keyapprovaldialog.cpp
new file mode 100644
index 000000000..7af85a0bb
--- /dev/null
+++ b/certmanager/lib/ui/keyapprovaldialog.cpp
@@ -0,0 +1,227 @@
+/* -*- c++ -*-
+ keyapprovaldialog.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Based on kpgpui.h
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "keyapprovaldialog.h"
+
+#include "keyrequester.h"
+
+#include <cryptplugfactory.h>
+#include <kleo/cryptobackend.h>
+
+#include <klocale.h>
+#include <kglobalsettings.h>
+#include <kseparator.h>
+
+#include <qstringlist.h>
+#include <qframe.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qcombobox.h>
+#include <qscrollview.h>
+#include <qpushbutton.h>
+
+#include <gpgmepp/key.h>
+
+#include <assert.h>
+
+static Kleo::EncryptionPreference cb2pref( int i ) {
+ switch ( i ) {
+ default:
+ case 0: return Kleo::UnknownPreference;
+ case 1: return Kleo::NeverEncrypt;
+ case 2: return Kleo::AlwaysEncrypt;
+ case 3: return Kleo::AlwaysEncryptIfPossible;
+ case 4: return Kleo::AlwaysAskForEncryption;
+ case 5: return Kleo::AskWheneverPossible;
+ }
+}
+
+static int pref2cb( Kleo::EncryptionPreference p ) {
+ switch ( p ) {
+ default: return 0;
+ case Kleo::NeverEncrypt: return 1;
+ case Kleo::AlwaysEncrypt: return 2;
+ case Kleo::AlwaysEncryptIfPossible: return 3;
+ case Kleo::AlwaysAskForEncryption: return 4;
+ case Kleo::AskWheneverPossible: return 5;
+ }
+}
+
+static QStringList preferencesStrings() {
+ return QStringList() << i18n("<none>")
+ << i18n("Never Encrypt with This Key")
+ << i18n("Always Encrypt with This Key")
+ << i18n("Encrypt Whenever Encryption is Possible")
+ << i18n("Always Ask")
+ << i18n("Ask Whenever Encryption is Possible");
+}
+
+
+struct Kleo::KeyApprovalDialog::Private {
+ Private() : selfRequester( 0 ), prefsChanged( false ) {}
+
+ Kleo::KeyRequester * selfRequester;
+ QStringList addresses;
+ std::vector<Kleo::KeyRequester*> requesters;
+ std::vector<QComboBox*> preferences;
+ bool prefsChanged;
+};
+
+Kleo::KeyApprovalDialog::KeyApprovalDialog( const std::vector<Item> & recipients,
+ const std::vector<GpgME::Key> & sender,
+ QWidget * parent, const char * name,
+ bool modal )
+ : KDialogBase( parent, name, modal, i18n("Encryption Key Approval"), Ok|Cancel, Ok ),
+ d( 0 )
+{
+ assert( !recipients.empty() );
+
+ d = new Private();
+
+ QFrame *page = makeMainWidget();
+ QVBoxLayout * vlay = new QVBoxLayout( page, 0, spacingHint() );
+
+ vlay->addWidget( new QLabel( i18n("The following keys will be used for encryption:"), page ) );
+
+ QScrollView * sv = new QScrollView( page );
+ sv->setResizePolicy( QScrollView::AutoOneFit );
+ vlay->addWidget( sv );
+
+ QWidget * view = new QWidget( sv->viewport() );
+
+ QGridLayout * glay = new QGridLayout( view, 3, 2, marginHint(), spacingHint() );
+ glay->setColStretch( 1, 1 );
+ sv->addChild( view );
+
+ int row = -1;
+
+ if ( !sender.empty() ) {
+ ++row;
+ glay->addWidget( new QLabel( i18n("Your keys:"), view ), row, 0 );
+ d->selfRequester = new EncryptionKeyRequester( true, EncryptionKeyRequester::AllProtocols, view );
+ d->selfRequester->setKeys( sender );
+ glay->addWidget( d->selfRequester, row, 1 );
+ ++row;
+ glay->addMultiCellWidget( new KSeparator( Horizontal, view ), row, row, 0, 1 );
+ }
+
+ const QStringList prefs = preferencesStrings();
+
+ for ( std::vector<Item>::const_iterator it = recipients.begin() ; it != recipients.end() ; ++it ) {
+ ++row;
+ glay->addWidget( new QLabel( i18n("Recipient:"), view ), row, 0 );
+ glay->addWidget( new QLabel( it->address, view ), row, 1 );
+ d->addresses.push_back( it->address );
+
+ ++row;
+ glay->addWidget( new QLabel( i18n("Encryption keys:"), view ), row, 0 );
+ KeyRequester * req = new EncryptionKeyRequester( true, EncryptionKeyRequester::AllProtocols, view );
+ req->setKeys( it->keys );
+ glay->addWidget( req, row, 1 );
+ d->requesters.push_back( req );
+
+ ++row;
+ glay->addWidget( new QLabel( i18n("Encryption preference:"), view ), row, 0 );
+ QComboBox * cb = new QComboBox( false, view );
+ cb->insertStringList( prefs );
+ glay->addWidget( cb, row, 1 );
+ cb->setCurrentItem( pref2cb( it->pref ) );
+ connect( cb, SIGNAL(activated(int)), SLOT(slotPrefsChanged()) );
+ d->preferences.push_back( cb );
+ }
+
+ // calculate the optimal width for the dialog
+ const int dialogWidth = marginHint()
+ + sv->frameWidth()
+ + view->sizeHint().width()
+ + sv->verticalScrollBar()->sizeHint().width()
+ + sv->frameWidth()
+ + marginHint()
+ + 2;
+ // calculate the optimal height for the dialog
+ const int dialogHeight = marginHint()
+ + fontMetrics().height()
+ + spacingHint()
+ + sv->frameWidth()
+ + view->sizeHint().height()
+ + sv->horizontalScrollBar()->sizeHint().height()
+ + sv->frameWidth()
+ + spacingHint()
+ + actionButton( KDialogBase::Cancel )->sizeHint().height()
+ + marginHint()
+ + 2;
+
+ // don't make the dialog too large
+ const QRect desk = KGlobalSettings::desktopGeometry( this );
+ setInitialSize( QSize( kMin( dialogWidth, 3 * desk.width() / 4 ),
+ kMin( dialogHeight, 7 * desk.height() / 8 ) ) );
+}
+
+Kleo::KeyApprovalDialog::~KeyApprovalDialog() {
+ delete d; d = 0;
+}
+
+std::vector<GpgME::Key> Kleo::KeyApprovalDialog::senderKeys() const {
+ return d->selfRequester ? d->selfRequester->keys() : std::vector<GpgME::Key>() ;
+}
+
+std::vector<Kleo::KeyApprovalDialog::Item> Kleo::KeyApprovalDialog::items() const {
+ assert( d->requesters.size() == d->addresses.size() );
+ assert( d->requesters.size() == d->preferences.size() );
+
+ std::vector<Item> result;
+ result.reserve( d->requesters.size() );
+ QStringList::const_iterator ait = d->addresses.begin();
+ std::vector<KeyRequester*>::const_iterator rit = d->requesters.begin();
+ std::vector<QComboBox*>::const_iterator cit = d->preferences.begin();
+ while ( ait != d->addresses.end() )
+ result.push_back( Item( *ait++, (*rit++)->keys(), cb2pref( (*cit++)->currentItem() ) ) );
+ return result;
+}
+
+bool Kleo::KeyApprovalDialog::preferencesChanged() const {
+ return d->prefsChanged;
+}
+
+void Kleo::KeyApprovalDialog::slotPrefsChanged() {
+ d->prefsChanged = true;
+}
+
+#include "keyapprovaldialog.moc"
diff --git a/certmanager/lib/ui/keyapprovaldialog.h b/certmanager/lib/ui/keyapprovaldialog.h
new file mode 100644
index 000000000..224530a71
--- /dev/null
+++ b/certmanager/lib/ui/keyapprovaldialog.h
@@ -0,0 +1,92 @@
+/* -*- c++ -*-
+ keyselectiondialog.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Based on kpgpui.h
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYAPPROVALDIALOG_H__
+#define __KLEO_KEYAPPROVALDIALOG_H__
+
+#include <kleo/enum.h>
+
+#include <kdialogbase.h>
+#include <kdepimmacros.h>
+
+#include <kpgpkey.h> // for EncryptPref
+#include <gpgmepp/key.h>
+
+#include <vector>
+
+namespace GpgME {
+ class Key;
+}
+
+class QStringList;
+
+namespace Kleo {
+
+ class KDE_EXPORT KeyApprovalDialog : public KDialogBase {
+ Q_OBJECT
+ public:
+ struct Item {
+ Item() : pref( UnknownPreference ) {}
+ Item( const QString & a, const std::vector<GpgME::Key> & k,
+ EncryptionPreference p=UnknownPreference )
+ : address( a ), keys( k ), pref( p ) {}
+ QString address;
+ std::vector<GpgME::Key> keys;
+ EncryptionPreference pref;
+ };
+
+ KeyApprovalDialog( const std::vector<Item> & recipients,
+ const std::vector<GpgME::Key> & sender,
+ QWidget * parent=0, const char * name=0,
+ bool modal=true );
+ ~KeyApprovalDialog();
+
+ std::vector<Item> items() const;
+ std::vector<GpgME::Key> senderKeys() const;
+
+ bool preferencesChanged() const;
+
+ private slots:
+ void slotPrefsChanged();
+
+ private:
+ class Private;
+ Private * d;
+ };
+
+} // namespace Kleo
+
+#endif // __KLEO_KEYAPPROVALDIALOG_H__
diff --git a/certmanager/lib/ui/keylistview.cpp b/certmanager/lib/ui/keylistview.cpp
new file mode 100644
index 000000000..98534a4b7
--- /dev/null
+++ b/certmanager/lib/ui/keylistview.cpp
@@ -0,0 +1,869 @@
+/*
+ keylistview.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "keylistview.h"
+
+#include <kdebug.h>
+
+#include <qfontmetrics.h>
+#include <qtooltip.h>
+#include <qrect.h>
+#include <qheader.h>
+#include <qpoint.h>
+#include <qptrlist.h>
+#include <qpainter.h>
+#include <qfont.h>
+#include <qcolor.h>
+#include <qtimer.h>
+#include <qcstring.h>
+
+#include <gpgmepp/key.h>
+
+#include <vector>
+#include <map>
+
+#include <assert.h>
+
+static const int updateDelayMilliSecs = 500;
+
+namespace {
+
+ class ItemToolTip : public QToolTip {
+ public:
+ ItemToolTip( Kleo::KeyListView * parent );
+ protected:
+ void maybeTip( const QPoint & p );
+ private:
+ Kleo::KeyListView * mKeyListView;
+ };
+
+ ItemToolTip::ItemToolTip( Kleo::KeyListView * parent )
+ : QToolTip( parent->viewport() ), mKeyListView( parent ) {}
+
+ void ItemToolTip::maybeTip( const QPoint & p ) {
+ if ( !mKeyListView )
+ return;
+
+ const QListViewItem * item = mKeyListView->itemAt( p );
+ if ( !item )
+ return;
+
+ const QRect itemRect = mKeyListView->itemRect( item );
+ if ( !itemRect.isValid() )
+ return;
+
+ const int col = mKeyListView->header()->sectionAt( p.x() );
+ if ( col == -1 )
+ return;
+
+ const QRect headerRect = mKeyListView->header()->sectionRect( col );
+ if ( !headerRect.isValid() )
+ return;
+
+ const QRect cellRect( headerRect.left(), itemRect.top(),
+ headerRect.width(), itemRect.height() );
+
+ QString tipStr;
+ if ( const Kleo::KeyListViewItem * klvi = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) )
+ tipStr = klvi->toolTip( col );
+ else
+ tipStr = item->text( col ) ;
+
+ if ( !tipStr.isEmpty() )
+ tip( cellRect, tipStr );
+ }
+
+} // anon namespace
+
+struct Kleo::KeyListView::Private {
+ Private() : updateTimer( 0 ), itemToolTip( 0 ) {}
+
+ std::vector<GpgME::Key> keyBuffer;
+ QTimer * updateTimer;
+ QToolTip * itemToolTip;
+ std::map<QCString,KeyListViewItem*> itemMap;
+};
+
+// a list of signals where we want to replace QListViewItem with
+// Kleo:KeyListViewItem:
+static const struct {
+ const char * source;
+ const char * target;
+} signalReplacements[] = {
+ { SIGNAL(doubleClicked(QListViewItem*,const QPoint&,int)),
+ SLOT(slotEmitDoubleClicked(QListViewItem*,const QPoint&,int)) },
+ { SIGNAL(returnPressed(QListViewItem*)),
+ SLOT(slotEmitReturnPressed(QListViewItem*)) },
+ { SIGNAL(selectionChanged(QListViewItem*)),
+ SLOT(slotEmitSelectionChanged(QListViewItem*)) },
+ { SIGNAL(contextMenu(KListView*, QListViewItem*,const QPoint&)),
+ SLOT(slotEmitContextMenu(KListView*, QListViewItem*,const QPoint&)) },
+};
+static const int numSignalReplacements = sizeof signalReplacements / sizeof *signalReplacements;
+
+
+Kleo::KeyListView::KeyListView( const ColumnStrategy * columnStrategy, const DisplayStrategy * displayStrategy, QWidget * parent, const char * name, WFlags f )
+ : KListView( parent, name ),
+ mColumnStrategy( columnStrategy ),
+ mDisplayStrategy ( displayStrategy ),
+ mHierarchical( false )
+{
+ setWFlags( f );
+
+ d = new Private();
+
+ d->updateTimer = new QTimer( this );
+ connect( d->updateTimer, SIGNAL(timeout()), SLOT(slotUpdateTimeout()) );
+
+ if ( !columnStrategy ) {
+ kdWarning(5150) << "Kleo::KeyListView: need a column strategy to work with!" << endl;
+ return;
+ }
+
+ const QFontMetrics fm = fontMetrics();
+
+ for ( int col = 0 ; !columnStrategy->title( col ).isEmpty() ; ++col ) {
+ addColumn( columnStrategy->title( col ), columnStrategy->width( col, fm ) );
+ setColumnWidthMode( col, columnStrategy->widthMode( col ) );
+ }
+
+ setAllColumnsShowFocus( true );
+ setShowToolTips( false ); // we do it instead...
+
+ for ( int i = 0 ; i < numSignalReplacements ; ++i )
+ connect( this, signalReplacements[i].source, signalReplacements[i].target );
+
+ QToolTip::remove( this );
+ QToolTip::remove( viewport() ); // make double sure :)
+ d->itemToolTip = new ItemToolTip( this );
+}
+
+Kleo::KeyListView::~KeyListView() {
+ d->updateTimer->stop();
+ // need to clear here, since in ~QListView, our children won't have
+ // a valid listView() pointing to us anymore, and their dtors try to
+ // unregister from us.
+ clear();
+ assert( d->itemMap.size() == 0 );
+ // need to delete the tooltip ourselves, as ~QToolTip isn't virtual :o
+ delete d->itemToolTip; d->itemToolTip = 0;
+ delete d; d = 0;
+ delete mColumnStrategy; mColumnStrategy = 0;
+ delete mDisplayStrategy; mDisplayStrategy = 0;
+}
+
+void Kleo::KeyListView::insertItem( QListViewItem * qlvi ) {
+ //kdDebug() << "Kleo::KeyListView::insertItem( " << qlvi << " )" << endl;
+ KListView::insertItem( qlvi );
+ if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
+ registerItem( item );
+}
+
+void Kleo::KeyListView::takeItem( QListViewItem * qlvi ) {
+ //kdDebug() << "Kleo::KeyListView::takeItem( " << qlvi << " )" << endl;
+ if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
+ deregisterItem( item );
+ KListView::takeItem( qlvi );
+}
+
+
+void Kleo::KeyListView::setHierarchical( bool hier ) {
+ if ( hier == mHierarchical )
+ return;
+ mHierarchical = hier;
+ if ( hier )
+ gatherScattered();
+ else
+ scatterGathered( firstChild() );
+}
+
+void Kleo::KeyListView::slotAddKey( const GpgME::Key & key ) {
+ if ( key.isNull() )
+ return;
+
+ d->keyBuffer.push_back( key );
+ if ( !d->updateTimer->isActive() )
+ d->updateTimer->start( updateDelayMilliSecs, true /* single-shot */ );
+}
+
+void Kleo::KeyListView::slotUpdateTimeout() {
+ if ( d->keyBuffer.empty() )
+ return;
+
+ const bool wasUpdatesEnabled = viewport()->isUpdatesEnabled();
+ if ( wasUpdatesEnabled )
+ viewport()->setUpdatesEnabled( false );
+ kdDebug( 5150 ) << "Kleo::KeyListView::slotUpdateTimeout(): processing "
+ << d->keyBuffer.size() << " items en block" << endl;
+ if ( hierarchical() ) {
+ for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it )
+ doHierarchicalInsert( *it );
+ gatherScattered();
+ } else {
+ for ( std::vector<GpgME::Key>::const_iterator it = d->keyBuffer.begin() ; it != d->keyBuffer.end() ; ++it )
+ (void)new KeyListViewItem( this, *it );
+ }
+ if ( wasUpdatesEnabled )
+ viewport()->setUpdatesEnabled( true );
+ d->keyBuffer.clear();
+}
+
+void Kleo::KeyListView::clear() {
+ d->updateTimer->stop();
+ d->keyBuffer.clear();
+ KListView::clear();
+}
+
+void Kleo::KeyListView::registerItem( KeyListViewItem * item ) {
+ //kdDebug() << "registerItem( " << item << " )" << endl;
+ if ( !item )
+ return;
+ const QCString fpr = item->key().primaryFingerprint();
+ if ( !fpr.isEmpty() )
+ d->itemMap.insert( std::make_pair( fpr, item ) );
+}
+
+void Kleo::KeyListView::deregisterItem( const KeyListViewItem * item ) {
+ //kdDebug() << "deregisterItem( KeyLVI: " << item << " )" << endl;
+ if ( !item )
+ return;
+ std::map<QCString,KeyListViewItem*>::iterator it
+ = d->itemMap.find( item->key().primaryFingerprint() );
+ if ( it == d->itemMap.end() )
+ return;
+ Q_ASSERT( it->second == item );
+ if ( it->second != item )
+ return;
+ d->itemMap.erase( it );
+}
+
+void Kleo::KeyListView::doHierarchicalInsert( const GpgME::Key & key ) {
+ const QCString fpr = key.primaryFingerprint();
+ if ( fpr.isEmpty() )
+ return;
+ KeyListViewItem * item = 0;
+ if ( !key.isRoot() )
+ if ( KeyListViewItem * parent = itemByFingerprint( key.chainID() ) ) {
+ item = new KeyListViewItem( parent, key );
+ parent->setOpen( true );
+ }
+ if ( !item )
+ item = new KeyListViewItem( this, key ); // top-level (for now)
+
+ d->itemMap.insert( std::make_pair( fpr, item ) );
+}
+
+void Kleo::KeyListView::gatherScattered() {
+ KeyListViewItem * item = firstChild();
+ while ( item ) {
+ KeyListViewItem * cur = item;
+ item = item->nextSibling();
+ if ( cur->key().isRoot() )
+ continue;
+ if ( KeyListViewItem * parent = itemByFingerprint( cur->key().chainID() ) ) {
+ // found a new parent...
+ // ### todo: optimize by suppressing removing/adding the item to the itemMap...
+ takeItem( cur );
+ parent->insertItem( cur );
+ parent->setOpen( true );
+ }
+ }
+}
+
+void Kleo::KeyListView::scatterGathered( QListViewItem * start ) {
+ QListViewItem * item = start;
+ while ( item ) {
+ QListViewItem * cur = item;
+ item = item->nextSibling();
+
+ scatterGathered( cur->firstChild() );
+ assert( cur->childCount() == 0 );
+
+ // ### todo: optimize by suppressing removing/adding the item to the itemMap...
+ if ( cur->parent() )
+ cur->parent()->takeItem( cur );
+ else
+ takeItem( cur );
+ insertItem( cur );
+ }
+}
+
+Kleo::KeyListViewItem * Kleo::KeyListView::itemByFingerprint( const QCString & s ) const {
+ if ( s.isEmpty() )
+ return 0;
+ const std::map<QCString,KeyListViewItem*>::const_iterator it = d->itemMap.find( s );
+ if ( it == d->itemMap.end() )
+ return 0;
+ return it->second;
+}
+
+
+void Kleo::KeyListView::slotRefreshKey( const GpgME::Key & key ) {
+ const char * fpr = key.primaryFingerprint();
+ if ( !fpr )
+ return;
+ if ( KeyListViewItem * item = itemByFingerprint( fpr ) )
+ item->setKey ( key );
+ else
+ // none found -> add it
+ slotAddKey( key );
+}
+
+// slots for the emission of covariant signals:
+
+void Kleo::KeyListView::slotEmitDoubleClicked( QListViewItem * item, const QPoint & p, int col ) {
+ if ( !item || lvi_cast<KeyListViewItem>( item ) )
+ emit doubleClicked( static_cast<KeyListViewItem*>( item ), p, col );
+}
+
+void Kleo::KeyListView::slotEmitReturnPressed( QListViewItem * item ) {
+ if ( !item || lvi_cast<KeyListViewItem>( item ) )
+ emit returnPressed( static_cast<KeyListViewItem*>( item ) );
+}
+
+void Kleo::KeyListView::slotEmitSelectionChanged( QListViewItem * item ) {
+ if ( !item || lvi_cast<KeyListViewItem>( item ) )
+ emit selectionChanged( static_cast<KeyListViewItem*>( item ) );
+}
+
+void Kleo::KeyListView::slotEmitContextMenu( KListView*, QListViewItem * item, const QPoint & p ) {
+ if ( !item || lvi_cast<KeyListViewItem>( item ) )
+ emit contextMenu( static_cast<KeyListViewItem*>( item ), p );
+}
+
+//
+//
+// KeyListViewItem
+//
+//
+
+Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, const GpgME::Key & key )
+ : QListViewItem( parent )
+{
+ setKey( key );
+}
+
+Kleo::KeyListViewItem::KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key )
+ : QListViewItem( parent, after )
+{
+ setKey( key );
+}
+
+Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key )
+ : QListViewItem( parent )
+{
+ setKey( key );
+}
+
+Kleo::KeyListViewItem::KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key )
+ : QListViewItem( parent, after )
+{
+ setKey( key );
+}
+
+Kleo::KeyListViewItem::~KeyListViewItem() {
+ // delete the children first... When children are deleted in the
+ // QLVI dtor, they don't have listView() anymore, thus they don't
+ // call deregister( this ), leading to stale entries in the
+ // itemMap...
+ while ( QListViewItem * item = firstChild() )
+ delete item;
+ // better do this here, too, since deletion is top-down and thus
+ // we're deleted when our parent item is no longer a
+ // KeyListViewItem, but a mere QListViewItem, so our takeItem()
+ // overload is gone by that time...
+ if ( KeyListView * lv = listView() )
+ lv->deregisterItem( this );
+}
+
+void Kleo::KeyListViewItem::setKey( const GpgME::Key & key ) {
+ KeyListView * lv = listView();
+ if ( lv )
+ lv->deregisterItem( this );
+ mKey = key;
+ if ( lv )
+ lv->registerItem( this );
+
+ // the ColumnStrategy operations might be very slow, so cache their
+ // result here, where we're non-const :)
+ const Kleo::KeyListView::ColumnStrategy * cs = lv ? lv->columnStrategy() : 0 ;
+ if ( !cs )
+ return;
+ const int numCols = lv ? lv->columns() : 0 ;
+ for ( int i = 0 ; i < numCols ; ++i ) {
+ setText( i, cs->text( key, i ) );
+ if ( const QPixmap * pix = cs->pixmap( key, i ) )
+ setPixmap( i, *pix );
+ }
+ repaint();
+}
+
+QString Kleo::KeyListViewItem::toolTip( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->toolTip( key(), col )
+ : QString::null ;
+}
+
+int Kleo::KeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
+ if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
+ return QListViewItem::compare( item, col, ascending );
+ KeyListViewItem * that = static_cast<KeyListViewItem*>( item );
+ return listView()->columnStrategy()->compare( this->key(), that->key(), col );
+}
+
+void Kleo::KeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
+ if ( !ds ) {
+ QListViewItem::paintCell( p, cg, column, width, alignment );
+ return;
+ }
+ const QColor fg = ds->keyForeground( key(), cg.text() );
+ const QColor bg = ds->keyBackground( key(), cg.base() );
+ const QFont f = ds->keyFont( key(), p->font() );
+
+ QColorGroup _cg = cg;
+ p->setFont( f );
+ _cg.setColor( QColorGroup::Text, fg );
+ _cg.setColor( QColorGroup::Base, bg );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+void Kleo::KeyListViewItem::insertItem( QListViewItem * qlvi ) {
+ //kdDebug() << "Kleo::KeyListViewItem::insertItem( " << qlvi << " )" << endl;
+ QListViewItem::insertItem( qlvi );
+ if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
+ listView()->registerItem( item );
+}
+
+void Kleo::KeyListViewItem::takeItem( QListViewItem * qlvi ) {
+ //kdDebug() << "Kleo::KeyListViewItem::takeItem( " << qlvi << " )" << endl;
+ if ( KeyListViewItem * item = lvi_cast<KeyListViewItem>( qlvi ) )
+ listView()->deregisterItem( item );
+ QListViewItem::takeItem( qlvi );
+}
+
+
+//
+//
+// SubkeyKeyListViewItem
+//
+//
+
+Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey )
+ : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
+{
+
+}
+
+Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
+ : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
+{
+
+}
+
+Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey )
+ : KeyListViewItem( parent, subkey.parent() ), mSubkey( subkey )
+{
+
+}
+
+Kleo::SubkeyKeyListViewItem::SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey )
+ : KeyListViewItem( parent, after, subkey.parent() ), mSubkey( subkey )
+{
+
+}
+
+void Kleo::SubkeyKeyListViewItem::setSubkey( const GpgME::Subkey & subkey ) {
+ mSubkey = subkey;
+ setKey( subkey.parent() );
+}
+
+QString Kleo::SubkeyKeyListViewItem::text( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->subkeyText( subkey(), col )
+ : QString::null ;
+}
+
+QString Kleo::SubkeyKeyListViewItem::toolTip( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->subkeyToolTip( subkey(), col )
+ : QString::null ;
+}
+
+const QPixmap * Kleo::SubkeyKeyListViewItem::pixmap( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->subkeyPixmap( subkey(), col ) : 0 ;
+}
+
+int Kleo::SubkeyKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
+ if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
+ return KeyListViewItem::compare( item, col, ascending );
+ SubkeyKeyListViewItem * that = static_cast<SubkeyKeyListViewItem*>( item );
+ return listView()->columnStrategy()->subkeyCompare( this->subkey(), that->subkey(), col );
+}
+
+void Kleo::SubkeyKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
+ if ( !ds ) {
+ QListViewItem::paintCell( p, cg, column, width, alignment );
+ return;
+ }
+ const QColor fg = ds->subkeyForeground( subkey(), cg.text() );
+ const QColor bg = ds->subkeyBackground( subkey(), cg.base() );
+ const QFont f = ds->subkeyFont( subkey(), p->font() );
+
+ QColorGroup _cg = cg;
+ p->setFont( f );
+ _cg.setColor( QColorGroup::Text, fg );
+ _cg.setColor( QColorGroup::Base, bg );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+
+//
+//
+// UserIDKeyListViewItem
+//
+//
+
+Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userID )
+ : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
+{
+
+}
+
+Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userID )
+ : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
+{
+
+}
+
+Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userID )
+ : KeyListViewItem( parent, userID.parent() ), mUserID( userID )
+{
+
+}
+
+Kleo::UserIDKeyListViewItem::UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userID )
+ : KeyListViewItem( parent, after, userID.parent() ), mUserID( userID )
+{
+
+}
+
+void Kleo::UserIDKeyListViewItem::setUserID( const GpgME::UserID & userID ) {
+ mUserID = userID;
+ setKey( userID.parent() );
+}
+
+QString Kleo::UserIDKeyListViewItem::text( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->userIDText( userID(), col )
+ : QString::null ;
+}
+
+QString Kleo::UserIDKeyListViewItem::toolTip( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->userIDToolTip( userID(), col )
+ : QString::null ;
+}
+
+const QPixmap * Kleo::UserIDKeyListViewItem::pixmap( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->userIDPixmap( userID(), col ) : 0 ;
+}
+
+int Kleo::UserIDKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
+ if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
+ return KeyListViewItem::compare( item, col, ascending );
+ UserIDKeyListViewItem * that = static_cast<UserIDKeyListViewItem*>( item );
+ return listView()->columnStrategy()->userIDCompare( this->userID(), that->userID(), col );
+}
+
+
+void Kleo::UserIDKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
+ if ( !ds ) {
+ QListViewItem::paintCell( p, cg, column, width, alignment );
+ return;
+ }
+ const QColor fg = ds->useridForeground( userID(), cg.text() );
+ const QColor bg = ds->useridBackground( userID(), cg.base() );
+ const QFont f = ds->useridFont( userID(), p->font() );
+
+ QColorGroup _cg = cg;
+ p->setFont( f );
+ _cg.setColor( QColorGroup::Text, fg );
+ _cg.setColor( QColorGroup::Base, bg );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+
+//
+//
+// SignatureKeyListViewItem
+//
+//
+
+Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & signature )
+ : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
+{
+
+}
+
+Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
+ : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
+{
+
+}
+
+Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & signature )
+ : KeyListViewItem( parent, signature.parent().parent() ), mSignature( signature )
+{
+
+}
+
+Kleo::SignatureKeyListViewItem::SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & signature )
+ : KeyListViewItem( parent, after, signature.parent().parent() ), mSignature( signature )
+{
+
+}
+
+void Kleo::SignatureKeyListViewItem::setSignature( const GpgME::UserID::Signature & signature ) {
+ mSignature = signature;
+ setKey( signature.parent().parent() );
+}
+
+QString Kleo::SignatureKeyListViewItem::text( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->signatureText( signature(), col )
+ : QString::null ;
+}
+
+QString Kleo::SignatureKeyListViewItem::toolTip( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->signatureToolTip( signature(), col )
+ : QString::null ;
+}
+
+const QPixmap * Kleo::SignatureKeyListViewItem::pixmap( int col ) const {
+ return listView() && listView()->columnStrategy()
+ ? listView()->columnStrategy()->signaturePixmap( signature(), col ) : 0 ;
+}
+
+int Kleo::SignatureKeyListViewItem::compare( QListViewItem * item, int col, bool ascending ) const {
+ if ( !item || item->rtti() != RTTI || !listView() || !listView()->columnStrategy() )
+ return KeyListViewItem::compare( item, col, ascending );
+ SignatureKeyListViewItem * that = static_cast<SignatureKeyListViewItem*>( item );
+ return listView()->columnStrategy()->signatureCompare( this->signature(), that->signature(), col );
+}
+
+void Kleo::SignatureKeyListViewItem::paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment ) {
+ const KeyListView::DisplayStrategy * ds = listView() ? listView()->displayStrategy() : 0 ;
+ if ( !ds ) {
+ QListViewItem::paintCell( p, cg, column, width, alignment );
+ return;
+ }
+ const QColor fg = ds->signatureForeground( signature(), cg.text() );
+ const QColor bg = ds->signatureBackground( signature(), cg.base() );
+ const QFont f = ds->signatureFont( signature(), p->font() );
+
+ QColorGroup _cg = cg;
+ p->setFont( f );
+ _cg.setColor( QColorGroup::Text, fg );
+ _cg.setColor( QColorGroup::Base, bg );
+
+ QListViewItem::paintCell( p, _cg, column, width, alignment );
+}
+
+
+//
+//
+// ColumnStrategy
+//
+//
+
+Kleo::KeyListView::ColumnStrategy::~ColumnStrategy() {}
+
+int Kleo::KeyListView::ColumnStrategy::compare( const GpgME::Key & key1, const GpgME::Key & key2, int col ) const {
+ return QString::localeAwareCompare( text( key1, col ), text( key2, col ) );
+}
+
+int Kleo::KeyListView::ColumnStrategy::width( int col, const QFontMetrics & fm ) const {
+ return fm.width( title( col ) ) * 2;
+}
+
+int Kleo::KeyListView::ColumnStrategy::subkeyCompare( const GpgME::Subkey & sub1, const GpgME::Subkey & sub2, int col ) const {
+ return QString::localeAwareCompare( subkeyText( sub1, col ), subkeyText( sub2, col ) );
+}
+
+int Kleo::KeyListView::ColumnStrategy::userIDCompare( const GpgME::UserID & uid1, const GpgME::UserID & uid2, int col ) const {
+ return QString::localeAwareCompare( userIDText( uid1, col ), userIDText( uid2, col ) );
+}
+
+int Kleo::KeyListView::ColumnStrategy::signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, int col ) const {
+ return QString::localeAwareCompare( signatureText( sig1, col ), signatureText( sig2, col ) );
+}
+
+QString Kleo::KeyListView::ColumnStrategy::toolTip( const GpgME::Key & key, int col ) const {
+ return text( key, col );
+}
+
+QString Kleo::KeyListView::ColumnStrategy::subkeyToolTip( const GpgME::Subkey & sub, int col ) const {
+ return subkeyText( sub, col );
+}
+
+QString Kleo::KeyListView::ColumnStrategy::userIDToolTip( const GpgME::UserID & uid, int col ) const {
+ return userIDText( uid, col );
+}
+
+QString Kleo::KeyListView::ColumnStrategy::signatureToolTip( const GpgME::UserID::Signature & sig, int col ) const {
+ return signatureText( sig, col );
+}
+
+//
+//
+// DisplayStrategy
+//
+//
+
+Kleo::KeyListView::DisplayStrategy::~DisplayStrategy() {}
+
+
+//font
+QFont Kleo::KeyListView::DisplayStrategy::keyFont( const GpgME::Key &, const QFont & font ) const {
+ return font;
+}
+
+QFont Kleo::KeyListView::DisplayStrategy::subkeyFont( const GpgME::Subkey &, const QFont & font ) const {
+ return font;
+}
+
+QFont Kleo::KeyListView::DisplayStrategy::useridFont( const GpgME::UserID &, const QFont & font ) const {
+ return font;
+}
+
+QFont Kleo::KeyListView::DisplayStrategy::signatureFont( const GpgME::UserID::Signature &, const QFont & font ) const {
+ return font;
+}
+
+//foreground
+QColor Kleo::KeyListView::DisplayStrategy::keyForeground( const GpgME::Key &, const QColor & fg )const {
+ return fg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::subkeyForeground( const GpgME::Subkey &, const QColor & fg ) const {
+ return fg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::useridForeground( const GpgME::UserID &, const QColor & fg ) const {
+ return fg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::signatureForeground( const GpgME::UserID::Signature &, const QColor & fg ) const {
+ return fg;
+}
+
+//background
+QColor Kleo::KeyListView::DisplayStrategy::keyBackground( const GpgME::Key &, const QColor & bg )const {
+ return bg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::subkeyBackground( const GpgME::Subkey &, const QColor & bg ) const {
+ return bg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::useridBackground( const GpgME::UserID &, const QColor & bg ) const {
+ return bg;
+}
+
+QColor Kleo::KeyListView::DisplayStrategy::signatureBackground( const GpgME::UserID::Signature &, const QColor & bg ) const {
+ return bg;
+}
+
+
+//
+//
+// Collection of covariant return reimplementations of QListView(Item)
+// members:
+//
+//
+
+Kleo::KeyListView * Kleo::KeyListViewItem::listView() const {
+ return static_cast<Kleo::KeyListView*>( QListViewItem::listView() );
+}
+
+Kleo::KeyListViewItem * Kleo::KeyListViewItem::nextSibling() const {
+ return static_cast<Kleo::KeyListViewItem*>( QListViewItem::nextSibling() );
+}
+
+Kleo::KeyListViewItem * Kleo::KeyListView::firstChild() const {
+ return static_cast<Kleo::KeyListViewItem*>( KListView::firstChild() );
+}
+
+Kleo::KeyListViewItem * Kleo::KeyListView::selectedItem() const {
+ return static_cast<Kleo::KeyListViewItem*>( KListView::selectedItem() );
+}
+
+static void selectedItems( QPtrList<Kleo::KeyListViewItem> & result, QListViewItem * start ) {
+ for ( QListViewItem * item = start ; item ; item = item->nextSibling() ) {
+ if ( item->isSelected() )
+ if ( Kleo::KeyListViewItem * i = Kleo::lvi_cast<Kleo::KeyListViewItem>( item ) )
+ result.append( i );
+ selectedItems( result, item->firstChild() );
+ }
+}
+
+QPtrList<Kleo::KeyListViewItem> Kleo::KeyListView::selectedItems() const {
+ QPtrList<KeyListViewItem> result;
+ ::selectedItems( result, firstChild() );
+ return result;
+}
+
+static bool hasSelection( QListViewItem * start ) {
+ for ( QListViewItem * item = start ; item ; item = item->nextSibling() )
+ if ( item->isSelected() || hasSelection( item->firstChild() ) )
+ return true;
+ return false;
+}
+
+bool Kleo::KeyListView::hasSelection() const {
+ return ::hasSelection( firstChild() );
+}
+
+#include "keylistview.moc"
diff --git a/certmanager/lib/ui/keylistview.h b/certmanager/lib/ui/keylistview.h
new file mode 100644
index 000000000..3ef708771
--- /dev/null
+++ b/certmanager/lib/ui/keylistview.h
@@ -0,0 +1,323 @@
+/*
+ keylistview.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_KEYLISTVIEW_H__
+#define __KLEO_KEYLISTVIEW_H__
+
+#include <klistview.h>
+
+#include <gpgmepp/key.h>
+#include <kdepimmacros.h>
+
+class QPainter;
+class QColorGroup;
+class QFont;
+class QColor;
+
+namespace Kleo {
+
+ // work around moc parser bug...
+#define TEMPLATE_TYPENAME(T) template <typename T>
+ TEMPLATE_TYPENAME(T)
+ inline T * lvi_cast( QListViewItem * item ) {
+ return item && (item->rtti() & T::RTTI_MASK) == T::RTTI
+ ? static_cast<T*>( item ) : 0 ;
+ }
+
+ TEMPLATE_TYPENAME(T)
+ inline const T * lvi_cast( const QListViewItem * item ) {
+ return item && (item->rtti() & T::RTTI_MASK) == T::RTTI
+ ? static_cast<const T*>( item ) : 0 ;
+ }
+#undef TEMPLATE_TYPENAME
+
+ class KeyListView;
+
+ class KDE_EXPORT KeyListViewItem : public QListViewItem {
+ public:
+ KeyListViewItem( KeyListView * parent, const GpgME::Key & key );
+ KeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Key & key );
+ KeyListViewItem( KeyListViewItem * parent, const GpgME::Key & key );
+ KeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Key & key );
+ ~KeyListViewItem();
+
+ void setKey( const GpgME::Key & key );
+ const GpgME::Key & key() const { return mKey; }
+
+ enum { RTTI_MASK = 0xFFFFFFF0, RTTI = 0x2C1362E0 };
+
+ //
+ // only boring stuff below:
+ //
+ virtual QString toolTip( int column ) const;
+
+ /*! \reimp for covariant return */
+ KeyListView * listView() const;
+ /*! \reimp for covariant return */
+ KeyListViewItem * nextSibling() const;
+ /*! \reimp */
+ int compare( QListViewItem * other, int col, bool ascending ) const;
+ /*! \reimp to allow for key() overload above */
+ QString key( int col, bool ascending ) const { return QListViewItem::key( col, ascending ); }
+ /*! \reimp */
+ int rtti() const { return RTTI; }
+ /*! \reimp */
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+ /*! \reimp */
+ void insertItem( QListViewItem * item );
+ /*! \reimp */
+ void takeItem( QListViewItem * item );
+
+ private:
+ GpgME::Key mKey;
+ };
+
+ class KDE_EXPORT SubkeyKeyListViewItem : public KeyListViewItem {
+ public:
+ SubkeyKeyListViewItem( KeyListView * parent, const GpgME::Subkey & subkey );
+ SubkeyKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::Subkey & subkey );
+ SubkeyKeyListViewItem( KeyListViewItem * parent, const GpgME::Subkey & subkey );
+ SubkeyKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::Subkey & subkey );
+
+ void setSubkey( const GpgME::Subkey & subkey );
+ const GpgME::Subkey & subkey() const { return mSubkey; }
+
+ enum { RTTI = KeyListViewItem::RTTI + 1 };
+
+ //
+ // only boring stuff below:
+ //
+ /*! \reimp */
+ QString toolTip( int col ) const;
+ /*! \reimp */
+ QString text( int col ) const;
+ /*! \reimp */
+ const QPixmap * pixmap( int col ) const;
+ /*! \reimp */
+ int compare( QListViewItem * other, int col, bool ascending ) const;
+ /*! \reimp */
+ int rtti() const { return RTTI; }
+ /*! \reimp */
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+
+ private:
+ GpgME::Subkey mSubkey;
+ };
+
+ class KDE_EXPORT UserIDKeyListViewItem : public KeyListViewItem {
+ public:
+ UserIDKeyListViewItem( KeyListView * parent, const GpgME::UserID & userid );
+ UserIDKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID & userid );
+ UserIDKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID & userid );
+ UserIDKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID & userid );
+
+ void setUserID( const GpgME::UserID & userid );
+ const GpgME::UserID userID() const { return mUserID; }
+
+ enum { RTTI = KeyListViewItem::RTTI + 2 };
+
+ //
+ // only boring stuff below:
+ //
+ /*! \reimp */
+ QString toolTip( int col ) const;
+ /*! \reimp */
+ QString text( int col ) const;
+ /*! \reimp */
+ const QPixmap * pixmap( int col ) const;
+ /*! \reimp */
+ int compare( QListViewItem * other, int col, bool ascending ) const;
+ /*! \reimp */
+ int rtti() const { return RTTI; }
+ /*! \reimp */
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+
+ private:
+ GpgME::UserID mUserID;
+ };
+
+ class KDE_EXPORT SignatureKeyListViewItem : public KeyListViewItem {
+ public:
+ SignatureKeyListViewItem( KeyListView * parent, const GpgME::UserID::Signature & sig );
+ SignatureKeyListViewItem( KeyListView * parent, KeyListViewItem * after, const GpgME::UserID::Signature & sig );
+ SignatureKeyListViewItem( KeyListViewItem * parent, const GpgME::UserID::Signature & sig );
+ SignatureKeyListViewItem( KeyListViewItem * parent, KeyListViewItem * after, const GpgME::UserID::Signature & sig );
+
+ void setSignature( const GpgME::UserID::Signature & sig );
+ const GpgME::UserID::Signature & signature() const { return mSignature; }
+
+ enum { RTTI = KeyListViewItem::RTTI + 3 };
+
+ //
+ // only boring stuff below:
+ //
+ /*! \reimp */
+ QString toolTip( int col ) const;
+ /*! \reimp */
+ QString text( int col ) const;
+ /*! \reimp */
+ const QPixmap * pixmap( int col ) const;
+ /*! \reimp */
+ int compare( QListViewItem * other, int col, bool ascending ) const;
+ /*! \reimp */
+ int rtti() const { return RTTI; }
+ /*! \reimp */
+ void paintCell( QPainter * p, const QColorGroup & cg, int column, int width, int alignment );
+
+ private:
+ GpgME::UserID::Signature mSignature;
+ };
+
+
+ class KDE_EXPORT KeyListView : public KListView {
+ Q_OBJECT
+ friend class KeyListViewItem;
+ public:
+
+ class KDE_EXPORT ColumnStrategy {
+ public:
+ virtual ~ColumnStrategy();
+ virtual QString title( int column ) const = 0;
+ virtual int width( int column, const QFontMetrics & fm ) const;
+ virtual QListView::WidthMode widthMode( int ) const { return QListView::Manual; }
+
+ virtual QString text( const GpgME::Key & key, int column ) const = 0;
+ virtual QString toolTip( const GpgME::Key & key, int column ) const;
+ virtual const QPixmap * pixmap( const GpgME::Key &, int ) const { return 0; }
+ virtual int compare( const GpgME::Key & key1, const GpgME::Key & key2, const int column ) const;
+
+ virtual QString subkeyText( const GpgME::Subkey &, int ) const { return QString::null; }
+ virtual QString subkeyToolTip( const GpgME::Subkey & subkey, int column ) const;
+ virtual const QPixmap * subkeyPixmap( const GpgME::Subkey &, int ) const { return 0; }
+ virtual int subkeyCompare( const GpgME::Subkey & subkey1, const GpgME::Subkey & subkey2, const int column ) const;
+
+ virtual QString userIDText( const GpgME::UserID &, int ) const { return QString::null; }
+ virtual QString userIDToolTip( const GpgME::UserID & userID, int column ) const;
+ virtual const QPixmap * userIDPixmap( const GpgME::UserID &, int ) const { return 0; }
+ virtual int userIDCompare( const GpgME::UserID & userID1, const GpgME::UserID & userID2, const int column ) const;
+
+ virtual QString signatureText( const GpgME::UserID::Signature &, int ) const { return QString::null; }
+ virtual QString signatureToolTip( const GpgME::UserID::Signature & sig, int column ) const;
+ virtual const QPixmap * signaturePixmap( const GpgME::UserID::Signature &, int ) const { return 0; }
+ virtual int signatureCompare( const GpgME::UserID::Signature & sig1, const GpgME::UserID::Signature & sig2, const int column ) const;
+ };
+
+ class KDE_EXPORT DisplayStrategy {
+ public:
+ virtual ~DisplayStrategy();
+ //font
+ virtual QFont keyFont( const GpgME::Key &, const QFont & ) const;
+ virtual QFont subkeyFont( const GpgME::Subkey &, const QFont & ) const;
+ virtual QFont useridFont( const GpgME::UserID &, const QFont & ) const;
+ virtual QFont signatureFont( const GpgME::UserID::Signature & , const QFont & ) const;
+ //foreground
+ virtual QColor keyForeground( const GpgME::Key & , const QColor & ) const;
+ virtual QColor subkeyForeground( const GpgME::Subkey &, const QColor & ) const;
+ virtual QColor useridForeground( const GpgME::UserID &, const QColor & ) const;
+ virtual QColor signatureForeground( const GpgME::UserID::Signature &, const QColor & ) const;
+ //background
+ virtual QColor keyBackground( const GpgME::Key &, const QColor & ) const;
+ virtual QColor subkeyBackground( const GpgME::Subkey &, const QColor & ) const;
+ virtual QColor useridBackground( const GpgME::UserID &, const QColor & ) const;
+ virtual QColor signatureBackground( const GpgME::UserID::Signature &, const QColor & ) const;
+ };
+
+ KeyListView( const ColumnStrategy * strategy,
+ const DisplayStrategy * display=0,
+ QWidget * parent=0, const char * name=0, WFlags f=0 );
+
+ ~KeyListView();
+
+ const ColumnStrategy * columnStrategy() const { return mColumnStrategy; }
+ const DisplayStrategy * displayStrategy() const { return mDisplayStrategy; }
+
+ bool hierarchical() const { return mHierarchical; }
+ virtual void setHierarchical( bool hier );
+
+ void flushKeys() { slotUpdateTimeout(); }
+
+ bool hasSelection() const;
+
+ KeyListViewItem * itemByFingerprint( const QCString & ) const;
+
+ signals:
+ void doubleClicked( Kleo::KeyListViewItem*, const QPoint&, int );
+ void returnPressed( Kleo::KeyListViewItem* );
+ void selectionChanged( Kleo::KeyListViewItem* );
+ void contextMenu( Kleo::KeyListViewItem*, const QPoint& );
+
+ public slots:
+ virtual void slotAddKey( const GpgME::Key & key );
+ virtual void slotRefreshKey( const GpgME::Key & key );
+
+ //
+ // Only boring stuff below:
+ //
+ private slots:
+ void slotEmitDoubleClicked( QListViewItem*, const QPoint&, int );
+ void slotEmitReturnPressed( QListViewItem* );
+ void slotEmitSelectionChanged( QListViewItem* );
+ void slotEmitContextMenu( KListView*, QListViewItem*, const QPoint& );
+ void slotUpdateTimeout();
+
+ public:
+ /*! \reimp for covariant return */
+ KeyListViewItem * selectedItem() const;
+ /*! \reimp */
+ QPtrList<KeyListViewItem> selectedItems() const;
+ /*! \reimp for covariant return */
+ KeyListViewItem * firstChild() const;
+ /*! \reimp */
+ void clear();
+ /*! \reimp */
+ void insertItem( QListViewItem * );
+ /*! \reimp */
+ void takeItem( QListViewItem * );
+
+ private:
+ void doHierarchicalInsert( const GpgME::Key & );
+ void gatherScattered();
+ void scatterGathered( QListViewItem * );
+ void registerItem( KeyListViewItem * );
+ void deregisterItem( const KeyListViewItem * );
+
+ private:
+ const ColumnStrategy * mColumnStrategy;
+ const DisplayStrategy * mDisplayStrategy;
+ bool mHierarchical;
+
+ class Private;
+ Private * d;
+ };
+}
+
+#endif // __KLEO_KEYLISTVIEW_H__
diff --git a/certmanager/lib/ui/keyrequester.cpp b/certmanager/lib/ui/keyrequester.cpp
new file mode 100644
index 000000000..d537affc5
--- /dev/null
+++ b/certmanager/lib/ui/keyrequester.cpp
@@ -0,0 +1,481 @@
+/* -*- c++ -*-
+ keyrequester.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klar�vdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+
+ Based on kpgpui.cpp
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ This file is part of KPGP, the KDE PGP/GnuPG support library.
+
+ KPGP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "keyrequester.h"
+
+#include "keyselectiondialog.h"
+
+#include <kleo/keylistjob.h>
+#include <kleo/dn.h>
+#include <kleo/cryptobackendfactory.h>
+
+// gpgme++
+#include <gpgmepp/key.h>
+#include <gpgmepp/keylistresult.h>
+
+// KDE
+#include <klocale.h>
+#include <kiconloader.h>
+#include <kdialog.h>
+#include <kdebug.h>
+#include <kmessagebox.h>
+#include <kpushbutton.h>
+
+// Qt
+#include <qapplication.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qlabel.h>
+#include <qregexp.h>
+
+#include <assert.h>
+
+Kleo::KeyRequester::KeyRequester( unsigned int allowedKeys, bool multipleKeys,
+ QWidget * parent, const char * name )
+ : QWidget( parent, name ),
+ mOpenPGPBackend( 0 ),
+ mSMIMEBackend( 0 ),
+ mMulti( multipleKeys ),
+ mKeyUsage( allowedKeys ),
+ mJobs( 0 ),
+ d( 0 )
+{
+ init();
+}
+
+Kleo::KeyRequester::KeyRequester( QWidget * parent, const char * name )
+ : QWidget( parent, name ),
+ mOpenPGPBackend( 0 ),
+ mSMIMEBackend( 0 ),
+ mMulti( false ),
+ mKeyUsage( 0 ),
+ mJobs( 0 ),
+ d( 0 )
+{
+ init();
+}
+
+void Kleo::KeyRequester::init()
+{
+ QHBoxLayout * hlay = new QHBoxLayout( this, 0, KDialog::spacingHint() );
+
+ // the label where the key id is to be displayed:
+ mLabel = new QLabel( this );
+ mLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken );
+
+ // the button to unset any key:
+ mEraseButton = new KPushButton( this );
+ mEraseButton->setAutoDefault( false );
+ mEraseButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum,
+ QSizePolicy::Minimum ) );
+ mEraseButton->setIconSet( SmallIconSet( QApplication::reverseLayout() ? "locationbar_erase" : "clear_left" ) );
+ QToolTip::add( mEraseButton, i18n("Clear") );
+
+ // the button to call the KeySelectionDialog:
+ mDialogButton = new QPushButton( i18n("Change..."), this );
+ mDialogButton->setAutoDefault( false );
+
+ hlay->addWidget( mLabel, 1 );
+ hlay->addWidget( mEraseButton );
+ hlay->addWidget( mDialogButton );
+
+ connect( mEraseButton, SIGNAL(clicked()), SLOT(slotEraseButtonClicked()) );
+ connect( mDialogButton, SIGNAL(clicked()), SLOT(slotDialogButtonClicked()) );
+
+ setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding,
+ QSizePolicy::Fixed ) );
+
+ setAllowedKeys( mKeyUsage );
+}
+
+Kleo::KeyRequester::~KeyRequester() {
+
+}
+
+const std::vector<GpgME::Key> & Kleo::KeyRequester::keys() const {
+ return mKeys;
+}
+
+const GpgME::Key & Kleo::KeyRequester::key() const {
+ if ( mKeys.empty() )
+ return GpgME::Key::null;
+ else
+ return mKeys.front();
+}
+
+void Kleo::KeyRequester::setKeys( const std::vector<GpgME::Key> & keys ) {
+ mKeys.clear();
+ for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
+ if ( !it->isNull() )
+ mKeys.push_back( *it );
+ updateKeys();
+}
+
+void Kleo::KeyRequester::setKey( const GpgME::Key & key ) {
+ mKeys.clear();
+ if ( !key.isNull() )
+ mKeys.push_back( key );
+ updateKeys();
+}
+
+QString Kleo::KeyRequester::fingerprint() const {
+ if ( mKeys.empty() )
+ return QString::null;
+ else
+ return mKeys.front().primaryFingerprint();
+}
+
+QStringList Kleo::KeyRequester::fingerprints() const {
+ QStringList result;
+ for ( std::vector<GpgME::Key>::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it )
+ if ( !it->isNull() )
+ if ( const char * fpr = it->primaryFingerprint() )
+ result.push_back( fpr );
+ return result;
+}
+
+void Kleo::KeyRequester::setFingerprint( const QString & fingerprint ) {
+ startKeyListJob( fingerprint );
+}
+
+void Kleo::KeyRequester::setFingerprints( const QStringList & fingerprints ) {
+ startKeyListJob( fingerprints );
+}
+
+void Kleo::KeyRequester::updateKeys() {
+ if ( mKeys.empty() ) {
+ mLabel->clear();
+ return;
+ }
+ if ( mKeys.size() > 1 )
+ setMultipleKeysEnabled( true );
+
+ QStringList labelTexts;
+ QString toolTipText;
+ for ( std::vector<GpgME::Key>::const_iterator it = mKeys.begin() ; it != mKeys.end() ; ++it ) {
+ if ( it->isNull() )
+ continue;
+ const QString fpr = it->primaryFingerprint();
+ labelTexts.push_back( fpr.right(8) );
+ toolTipText += fpr.right(8) + ": ";
+ if ( const char * uid = it->userID(0).id() )
+ if ( it->protocol() == GpgME::Context::OpenPGP )
+ toolTipText += QString::fromUtf8( uid );
+ else
+ toolTipText += Kleo::DN( uid ).prettyDN();
+ else
+ toolTipText += i18n("<unknown>");
+ toolTipText += '\n';
+ }
+
+ mLabel->setText( labelTexts.join(", ") );
+ QToolTip::remove( mLabel );
+ QToolTip::add( mLabel, toolTipText );
+}
+
+#ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+#define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+static void showKeyListError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n( "<qt><p>An error occurred while fetching "
+ "the keys from the backend:</p>"
+ "<p><b>%1</b></p></qt>" )
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+
+ KMessageBox::error( parent, msg, i18n( "Key Listing Failed" ) );
+}
+#endif // __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+
+void Kleo::KeyRequester::startKeyListJob( const QStringList & fingerprints ) {
+ if ( !mSMIMEBackend && !mOpenPGPBackend )
+ return;
+
+ mTmpKeys.clear();
+ mJobs = 0;
+
+ unsigned int count = 0;
+ for ( QStringList::const_iterator it = fingerprints.begin() ; it != fingerprints.end() ; ++it )
+ if ( !(*it).stripWhiteSpace().isEmpty() )
+ ++count;
+
+ if ( !count ) {
+ // don't fall into the trap that an empty pattern means
+ // "return all keys" :)
+ setKey( GpgME::Key::null );
+ return;
+ }
+
+ if ( mOpenPGPBackend ) {
+ KeyListJob * job = mOpenPGPBackend->keyListJob( false ); // local, no sigs
+ if ( !job ) {
+ KMessageBox::error( this,
+ i18n("The OpenPGP backend does not support listing keys. "
+ "Check your installation."),
+ i18n("Key Listing Failed") );
+ } else {
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotKeyListResult(const GpgME::KeyListResult&)) );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotNextKey(const GpgME::Key&)) );
+
+ const GpgME::Error err = job->start( fingerprints,
+ mKeyUsage & Kleo::KeySelectionDialog::SecretKeys &&
+ !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) );
+
+ if ( err )
+ showKeyListError( this, err );
+ else
+ ++mJobs;
+ }
+ }
+
+ if ( mSMIMEBackend ) {
+ KeyListJob * job = mSMIMEBackend->keyListJob( false ); // local, no sigs
+ if ( !job ) {
+ KMessageBox::error( this,
+ i18n("The S/MIME backend does not support listing keys. "
+ "Check your installation."),
+ i18n("Key Listing Failed") );
+ } else {
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotKeyListResult(const GpgME::KeyListResult&)) );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ SLOT(slotNextKey(const GpgME::Key&)) );
+
+ const GpgME::Error err = job->start( fingerprints,
+ mKeyUsage & Kleo::KeySelectionDialog::SecretKeys &&
+ !( mKeyUsage & Kleo::KeySelectionDialog::PublicKeys ) );
+
+ if ( err )
+ showKeyListError( this, err );
+ else
+ ++mJobs;
+ }
+ }
+
+ if ( mJobs > 0 ) {
+ mEraseButton->setEnabled( false );
+ mDialogButton->setEnabled( false );
+ }
+}
+
+void Kleo::KeyRequester::slotNextKey( const GpgME::Key & key ) {
+ if ( !key.isNull() )
+ mTmpKeys.push_back( key );
+}
+
+void Kleo::KeyRequester::slotKeyListResult( const GpgME::KeyListResult & res ) {
+ if ( res.error() )
+ showKeyListError( this, res.error() );
+
+ if ( --mJobs <= 0 ) {
+ mEraseButton->setEnabled( true );
+ mDialogButton->setEnabled( true );
+
+ setKeys( mTmpKeys );
+ mTmpKeys.clear();
+ }
+}
+
+
+void Kleo::KeyRequester::slotDialogButtonClicked() {
+ KeySelectionDialog * dlg = mKeys.empty()
+ ? new KeySelectionDialog( mDialogCaption, mDialogMessage, mInitialQuery, mKeyUsage, mMulti, false, this )
+ : new KeySelectionDialog( mDialogCaption, mDialogCaption, mKeys, mKeyUsage, mMulti, false, this ) ;
+
+ if ( dlg->exec() == QDialog::Accepted ) {
+ if ( mMulti )
+ setKeys( dlg->selectedKeys() );
+ else
+ setKey( dlg->selectedKey() );
+ emit changed();
+ }
+
+ delete dlg;
+}
+
+void Kleo::KeyRequester::slotEraseButtonClicked() {
+ if ( !mKeys.empty() )
+ emit changed();
+ mKeys.clear();
+ updateKeys();
+}
+
+void Kleo::KeyRequester::setDialogCaption( const QString & caption ) {
+ mDialogCaption = caption;
+}
+
+void Kleo::KeyRequester::setDialogMessage( const QString & msg ) {
+ mDialogMessage = msg;
+}
+
+bool Kleo::KeyRequester::isMultipleKeysEnabled() const {
+ return mMulti;
+}
+
+void Kleo::KeyRequester::setMultipleKeysEnabled( bool multi ) {
+ if ( multi == mMulti ) return;
+
+ if ( !multi && !mKeys.empty() )
+ mKeys.erase( mKeys.begin() + 1, mKeys.end() );
+
+ mMulti = multi;
+ updateKeys();
+}
+
+unsigned int Kleo::KeyRequester::allowedKeys() const {
+ return mKeyUsage;
+}
+
+void Kleo::KeyRequester::setAllowedKeys( unsigned int keyUsage ) {
+ mKeyUsage = keyUsage;
+ mOpenPGPBackend = 0;
+ mSMIMEBackend = 0;
+
+ if ( mKeyUsage & KeySelectionDialog::OpenPGPKeys )
+ mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp();
+ if ( mKeyUsage & KeySelectionDialog::SMIMEKeys )
+ mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime();
+
+ if ( mOpenPGPBackend && !mSMIMEBackend ) {
+ mDialogCaption = i18n("OpenPGP Key Selection");
+ mDialogMessage = i18n("Please select an OpenPGP key to use.");
+ } else if ( !mOpenPGPBackend && mSMIMEBackend ) {
+ mDialogCaption = i18n("S/MIME Key Selection");
+ mDialogMessage = i18n("Please select an S/MIME key to use.");
+ } else {
+ mDialogCaption = i18n("Key Selection");
+ mDialogMessage = i18n("Please select an (OpenPGP or S/MIME) key to use.");
+ }
+}
+
+QPushButton * Kleo::KeyRequester::dialogButton() {
+ return mDialogButton;
+}
+
+QPushButton * Kleo::KeyRequester::eraseButton() {
+ return mEraseButton;
+}
+
+static inline unsigned int foo( bool openpgp, bool smime, bool trusted, bool valid ) {
+ unsigned int result = 0;
+ if ( openpgp )
+ result |= Kleo::KeySelectionDialog::OpenPGPKeys;
+ if ( smime )
+ result |= Kleo::KeySelectionDialog::SMIMEKeys;
+ if ( trusted )
+ result |= Kleo::KeySelectionDialog::TrustedKeys;
+ if ( valid )
+ result |= Kleo::KeySelectionDialog::ValidKeys;
+ return result;
+}
+
+static inline unsigned int encryptionKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) {
+ return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::EncryptionKeys | Kleo::KeySelectionDialog::PublicKeys;
+}
+
+static inline unsigned int signingKeyUsage( bool openpgp, bool smime, bool trusted, bool valid ) {
+ return foo( openpgp, smime, trusted, valid ) | Kleo::KeySelectionDialog::SigningKeys | Kleo::KeySelectionDialog::SecretKeys;
+}
+
+Kleo::EncryptionKeyRequester::EncryptionKeyRequester( bool multi, unsigned int proto,
+ QWidget * parent, const char * name,
+ bool onlyTrusted, bool onlyValid )
+ : KeyRequester( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi,
+ parent, name )
+{
+}
+
+Kleo::EncryptionKeyRequester::EncryptionKeyRequester( QWidget * parent, const char * name )
+ : KeyRequester( 0, false, parent, name )
+{
+}
+
+Kleo::EncryptionKeyRequester::~EncryptionKeyRequester() {}
+
+
+void Kleo::EncryptionKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid )
+{
+ KeyRequester::setAllowedKeys( encryptionKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) );
+}
+
+Kleo::SigningKeyRequester::SigningKeyRequester( bool multi, unsigned int proto,
+ QWidget * parent, const char * name,
+ bool onlyTrusted, bool onlyValid )
+ : KeyRequester( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ), multi,
+ parent, name )
+{
+}
+
+Kleo::SigningKeyRequester::SigningKeyRequester( QWidget * parent, const char * name )
+ : KeyRequester( 0, false, parent, name )
+{
+}
+
+Kleo::SigningKeyRequester::~SigningKeyRequester() {}
+
+void Kleo::SigningKeyRequester::setAllowedKeys( unsigned int proto, bool onlyTrusted, bool onlyValid )
+{
+ KeyRequester::setAllowedKeys( signingKeyUsage( proto & OpenPGP, proto & SMIME, onlyTrusted, onlyValid ) );
+}
+
+void Kleo::KeyRequester::virtual_hook( int, void* ) {}
+void Kleo::EncryptionKeyRequester::virtual_hook( int id, void * data ) {
+ KeyRequester::virtual_hook( id, data );
+}
+void Kleo::SigningKeyRequester::virtual_hook( int id, void * data ) {
+ KeyRequester::virtual_hook( id, data );
+}
+
+#include "keyrequester.moc"
diff --git a/certmanager/lib/ui/keyrequester.h b/certmanager/lib/ui/keyrequester.h
new file mode 100644
index 000000000..3de9c508b
--- /dev/null
+++ b/certmanager/lib/ui/keyrequester.h
@@ -0,0 +1,227 @@
+/* -*- c++ -*-
+ keyrequester.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+
+ Based on kpgpui.h
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ This file is part of KPGP, the KDE PGP/GnuPG support library.
+
+ KPGP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __KLEO_UI_KEYREQUESTER_H__
+#define __KLEO_UI_KEYREQUESTER_H__
+
+#include <qwidget.h>
+#include <kleo/cryptobackend.h>
+
+#include <vector>
+#include <kdepimmacros.h>
+
+namespace Kleo {
+ class KeyListView;
+ class KeyListViewItem;
+}
+
+namespace GpgME {
+ class Key;
+ class KeyListResult;
+}
+
+class QStringList;
+class QString;
+class QPushButton;
+class QLabel;
+
+namespace Kleo {
+
+ /// Base class for SigningKeyRequester and EncryptionKeyRequester
+ class KDE_EXPORT KeyRequester : public QWidget {
+ Q_OBJECT
+ public:
+ KeyRequester( unsigned int allowedKeys, bool multipleKeys=false,
+ QWidget * parent=0, const char * name=0 );
+ // Constructor for Qt Designer
+ KeyRequester( QWidget * parent=0, const char * name=0 );
+ ~KeyRequester();
+
+ const GpgME::Key & key() const;
+ /** Preferred method to set a key for
+ non-multi-KeyRequesters. Doesn't start a backend
+ KeyListJob.
+ */
+ void setKey( const GpgME::Key & key );
+
+ const std::vector<GpgME::Key> & keys() const;
+ /** Preferred method to set a key for multi-KeyRequesters. Doesn't
+ start a backend KeyListJob.
+ */
+ void setKeys( const std::vector<GpgME::Key> & keys );
+
+ QString fingerprint() const;
+ /** Set the key by fingerprint. Starts a background KeyListJob to
+ retrive the complete GpgME::Key object
+ */
+ void setFingerprint( const QString & fingerprint );
+
+ QStringList fingerprints() const;
+ /** Set the keys by fingerprint. Starts a background KeyListJob to
+ retrive the complete GpgME::Key objects
+ */
+ void setFingerprints( const QStringList & fingerprints );
+
+
+ QPushButton * eraseButton();
+ QPushButton * dialogButton();
+
+ void setDialogCaption( const QString & caption );
+ void setDialogMessage( const QString & message );
+
+ bool isMultipleKeysEnabled() const;
+ void setMultipleKeysEnabled( bool enable );
+
+ unsigned int allowedKeys() const;
+ void setAllowedKeys( unsigned int allowed );
+
+ void setInitialQuery( const QString & s ) { mInitialQuery = s; }
+ const QString & initialQuery() const { return mInitialQuery; }
+
+ signals:
+ void changed();
+
+ private:
+ void init();
+ void startKeyListJob( const QStringList & fingerprints );
+ void updateKeys();
+
+ private slots:
+ void slotNextKey( const GpgME::Key & key );
+ void slotKeyListResult( const GpgME::KeyListResult & result );
+ void slotDialogButtonClicked();
+ void slotEraseButtonClicked();
+
+ private:
+ const CryptoBackend::Protocol * mOpenPGPBackend;
+ const CryptoBackend::Protocol * mSMIMEBackend;
+ QLabel * mLabel;
+ QPushButton * mEraseButton;
+ QPushButton * mDialogButton;
+ QString mDialogCaption, mDialogMessage, mInitialQuery;
+ bool mMulti;
+ unsigned int mKeyUsage;
+ int mJobs;
+ std::vector<GpgME::Key> mKeys;
+ std::vector<GpgME::Key> mTmpKeys;
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ virtual void virtual_hook( int, void* );
+ };
+
+
+ class KDE_EXPORT EncryptionKeyRequester : public KeyRequester {
+ Q_OBJECT
+ public:
+ enum { OpenPGP = 1, SMIME = 2, AllProtocols = OpenPGP|SMIME };
+
+ /**
+ * Preferred constructor
+ */
+ EncryptionKeyRequester( bool multipleKeys=false, unsigned int proto=AllProtocols,
+ QWidget * parent=0, const char * name=0,
+ bool onlyTrusted=true, bool onlyValid=true );
+ /**
+ * Constructor for Qt designer
+ */
+ EncryptionKeyRequester( QWidget * parent=0, const char * name=0 );
+ ~EncryptionKeyRequester();
+
+ void setAllowedKeys( unsigned int proto, bool onlyTrusted=true, bool onlyValid=true );
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ virtual void virtual_hook( int, void* );
+ };
+
+
+ class KDE_EXPORT SigningKeyRequester : public KeyRequester {
+ Q_OBJECT
+ public:
+ enum { OpenPGP = 1, SMIME = 2, AllProtocols = OpenPGP|SMIME };
+
+ /**
+ * Preferred constructor
+ * @param multipleKeys whether multiple keys can be selected
+ *
+ * @param proto the allowed protocols, OpenPGP and/or SMIME
+ * @param onlyTrusted only show trusted keys
+ * @param onlyValid only show valid keys
+ */
+ SigningKeyRequester( bool multipleKeys=false, unsigned int proto=AllProtocols,
+ QWidget * parent=0, const char * name=0,
+ bool onlyTrusted=true, bool onlyValid=true );
+ /**
+ * Constructor for Qt designer
+ */
+ SigningKeyRequester( QWidget * parent=0, const char * name=0 );
+ ~SigningKeyRequester();
+
+ /*
+ * Those parameters affect the parameters given to the key selection dialog.
+ * @param proto the allowed protocols, OpenPGP and/or SMIME
+ * @param onlyTrusted only show trusted keys
+ * @param onlyValid only show valid keys
+ */
+ void setAllowedKeys( unsigned int proto, bool onlyTrusted=true, bool onlyValid=true );
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ virtual void virtual_hook( int, void* );
+ };
+
+}
+
+#endif // __KLEO_UI_KEYREQUESTER_H__
diff --git a/certmanager/lib/ui/keyselectiondialog.cpp b/certmanager/lib/ui/keyselectiondialog.cpp
new file mode 100644
index 000000000..e21cb39d4
--- /dev/null
+++ b/certmanager/lib/ui/keyselectiondialog.cpp
@@ -0,0 +1,806 @@
+/* -*- c++ -*-
+ keyselectiondialog.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarävdalens Datakonsult AB
+
+ Based on kpgpui.cpp
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "keyselectiondialog.h"
+
+#include "keylistview.h"
+#include "progressdialog.h"
+
+#include <kleo/dn.h>
+#include <kleo/keylistjob.h>
+#include <kleo/cryptobackendfactory.h>
+
+// gpgme++
+#include <gpgmepp/key.h>
+#include <gpgmepp/keylistresult.h>
+
+// KDE
+#include <klocale.h>
+#include <kapplication.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+#include <kdebug.h>
+#include <kwin.h>
+#include <kconfig.h>
+#include <kmessagebox.h>
+#include <kprocess.h>
+
+// Qt
+#include <qcheckbox.h>
+#include <qtoolbutton.h>
+#include <qlabel.h>
+#include <qpixmap.h>
+#include <qtimer.h>
+#include <qlayout.h>
+#include <qlineedit.h>
+#include <qwhatsthis.h>
+#include <qpopupmenu.h>
+#include <qregexp.h>
+#include <qpushbutton.h>
+
+#include <algorithm>
+#include <iterator>
+
+#include <string.h>
+#include <assert.h>
+
+static bool checkKeyUsage( const GpgME::Key & key, unsigned int keyUsage ) {
+
+ if ( keyUsage & Kleo::KeySelectionDialog::ValidKeys ) {
+ if ( key.isInvalid() )
+ kdDebug() << "key is invalid - ignoring" << endl;
+ if ( key.isExpired() ) {
+ kdDebug() << "key is expired" << endl;
+ return false;
+ } else if ( key.isRevoked() ) {
+ kdDebug() << "key is revoked" << endl;
+ return false;
+ } else if ( key.isDisabled() ) {
+ kdDebug() << "key is disabled" << endl;
+ return false;
+ }
+ }
+
+ if ( keyUsage & Kleo::KeySelectionDialog::EncryptionKeys &&
+ !key.canEncrypt() ) {
+ kdDebug() << "key can't encrypt" << endl;
+ return false;
+ }
+ if ( keyUsage & Kleo::KeySelectionDialog::SigningKeys &&
+ !key.canSign() ) {
+ kdDebug() << "key can't sign" << endl;
+ return false;
+ }
+ if ( keyUsage & Kleo::KeySelectionDialog::CertificationKeys &&
+ !key.canCertify() ) {
+ kdDebug() << "key can't certify" << endl;
+ return false;
+ }
+ if ( keyUsage & Kleo::KeySelectionDialog::AuthenticationKeys &&
+ !key.canAuthenticate() ) {
+ kdDebug() << "key can't authenticate" << endl;
+ return false;
+ }
+
+ if ( keyUsage & Kleo::KeySelectionDialog::SecretKeys &&
+ !( keyUsage & Kleo::KeySelectionDialog::PublicKeys ) &&
+ !key.isSecret() ) {
+ kdDebug() << "key isn't secret" << endl;
+ return false;
+ }
+
+ if ( keyUsage & Kleo::KeySelectionDialog::TrustedKeys &&
+ key.protocol() == GpgME::Context::OpenPGP &&
+ // only check this for secret keys for now.
+ // Seems validity isn't checked for secret keylistings...
+ !key.isSecret() ) {
+ std::vector<GpgME::UserID> uids = key.userIDs();
+ for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it )
+ if ( !it->isRevoked() && it->validity() >= GpgME::UserID::Marginal )
+ return true;
+ kdDebug() << "key has no UIDs with validity >= Marginal" << endl;
+ return false;
+ }
+ // X.509 keys are always trusted, else they won't be the keybox.
+ // PENDING(marc) check that this ^ is correct
+
+ return true;
+}
+
+static bool checkKeyUsage( const std::vector<GpgME::Key> & keys, unsigned int keyUsage ) {
+ for ( std::vector<GpgME::Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it )
+ if ( !checkKeyUsage( *it, keyUsage ) )
+ return false;
+ return true;
+}
+
+static inline QString time_t2string( time_t t ) {
+ QDateTime dt;
+ dt.setTime_t( t );
+ return dt.toString();
+}
+
+namespace {
+
+ class ColumnStrategy : public Kleo::KeyListView::ColumnStrategy {
+ public:
+ ColumnStrategy( unsigned int keyUsage );
+
+ QString title( int col ) const;
+ int width( int col, const QFontMetrics & fm ) const;
+
+ QString text( const GpgME::Key & key, int col ) const;
+ QString toolTip( const GpgME::Key & key, int col ) const;
+ const QPixmap * pixmap( const GpgME::Key & key, int col ) const;
+
+ private:
+ const QPixmap mKeyGoodPix, mKeyBadPix, mKeyUnknownPix, mKeyValidPix;
+ const unsigned int mKeyUsage;
+ };
+
+ ColumnStrategy::ColumnStrategy( unsigned int keyUsage )
+ : Kleo::KeyListView::ColumnStrategy(),
+ mKeyGoodPix( UserIcon( "key_ok" ) ),
+ mKeyBadPix( UserIcon( "key_bad" ) ),
+ mKeyUnknownPix( UserIcon( "key_unknown" ) ),
+ mKeyValidPix( UserIcon( "key" ) ),
+ mKeyUsage( keyUsage )
+ {
+ kdWarning( keyUsage == 0, 5150 )
+ << "KeySelectionDialog: keyUsage == 0. You want to use AllKeys instead." << endl;
+ }
+
+ QString ColumnStrategy::title( int col ) const {
+ switch ( col ) {
+ case 0: return i18n("Key ID");
+ case 1: return i18n("User ID");
+ default: return QString::null;
+ }
+ }
+
+ int ColumnStrategy::width( int col, const QFontMetrics & fm ) const {
+ if ( col == 0 ) {
+ static const char hexchars[] = "0123456789ABCDEF";
+ int maxWidth = 0;
+ for ( unsigned int i = 0 ; i < 16 ; ++i )
+ maxWidth = kMax( fm.width( QChar( hexchars[i] ) ), maxWidth );
+ return 8 * maxWidth + 2 * mKeyGoodPix.width();
+ }
+ return Kleo::KeyListView::ColumnStrategy::width( col, fm );
+ }
+
+ QString ColumnStrategy::text( const GpgME::Key & key, int col ) const {
+ switch ( col ) {
+ case 0:
+ {
+ if ( key.shortKeyID() )
+ return QString::fromUtf8( key.shortKeyID() );
+ else
+ return i18n("<unknown>");
+ }
+ break;
+ case 1:
+ {
+ const char * uid = key.userID(0).id();
+ if ( key.protocol() == GpgME::Context::OpenPGP )
+ return uid && *uid ? QString::fromUtf8( uid ) : QString::null ;
+ else // CMS
+ return Kleo::DN( uid ).prettyDN();
+ }
+ break;
+ default: return QString::null;
+ }
+ }
+
+ QString ColumnStrategy::toolTip( const GpgME::Key & key, int ) const {
+ const char * uid = key.userID(0).id();
+ const char * fpr = key.primaryFingerprint();
+ const char * issuer = key.issuerName();
+ const GpgME::Subkey subkey = key.subkey(0);
+ const QString expiry = subkey.neverExpires() ? i18n("never") : time_t2string( subkey.expirationTime() ) ;
+ const QString creation = time_t2string( subkey.creationTime() );
+ if ( key.protocol() == GpgME::Context::OpenPGP )
+ return i18n( "OpenPGP key for %1\n"
+ "Created: %2\n"
+ "Expiry: %3\n"
+ "Fingerprint: %4" )
+ .arg( uid ? QString::fromUtf8( uid ) : i18n("unknown"),
+ creation, expiry,
+ fpr ? QString::fromLatin1( fpr ) : i18n("unknown") );
+ else
+ return i18n( "S/MIME key for %1\n"
+ "Created: %2\n"
+ "Expiry: %3\n"
+ "Fingerprint: %4\n"
+ "Issuer: %5" )
+ .arg( uid ? Kleo::DN( uid ).prettyDN() : i18n("unknown"),
+ creation, expiry,
+ fpr ? QString::fromLatin1( fpr ) : i18n("unknown") )
+ .arg( issuer ? Kleo::DN( issuer ).prettyDN() : i18n("unknown") );
+ }
+
+ const QPixmap * ColumnStrategy::pixmap( const GpgME::Key & key, int col ) const {
+ if ( col != 0 )
+ return 0;
+ // this key did not undergo a validating keylisting yet:
+ if ( !( key.keyListMode() & GpgME::Context::Validate ) )
+ return &mKeyUnknownPix;
+
+ if ( !checkKeyUsage( key, mKeyUsage ) )
+ return &mKeyBadPix;
+
+ if ( key.protocol() == GpgME::Context::CMS )
+ return &mKeyGoodPix;
+
+ switch ( key.userID(0).validity() ) {
+ default:
+ case GpgME::UserID::Unknown:
+ case GpgME::UserID::Undefined:
+ return &mKeyUnknownPix;
+ case GpgME::UserID::Never:
+ return &mKeyValidPix;
+ case GpgME::UserID::Marginal:
+ case GpgME::UserID::Full:
+ case GpgME::UserID::Ultimate:
+ return &mKeyGoodPix;
+ }
+ }
+
+}
+
+
+static const int sCheckSelectionDelay = 250;
+
+Kleo::KeySelectionDialog::KeySelectionDialog( const QString & title,
+ const QString & text,
+ const std::vector<GpgME::Key> & selectedKeys,
+ unsigned int keyUsage,
+ bool extendedSelection,
+ bool rememberChoice,
+ QWidget * parent, const char * name,
+ bool modal )
+ : KDialogBase( parent, name, modal, title, Default|Ok|Cancel|Help, Ok ),
+ mOpenPGPBackend( 0 ),
+ mSMIMEBackend( 0 ),
+ mRememberCB( 0 ),
+ mSelectedKeys( selectedKeys ),
+ mKeyUsage( keyUsage ),
+ mCurrentContextMenuItem( 0 )
+{
+ init( rememberChoice, extendedSelection, text, QString::null );
+}
+
+Kleo::KeySelectionDialog::KeySelectionDialog( const QString & title,
+ const QString & text,
+ const QString & initialQuery,
+ unsigned int keyUsage,
+ bool extendedSelection,
+ bool rememberChoice,
+ QWidget * parent, const char * name,
+ bool modal )
+ : KDialogBase( parent, name, modal, title, Default|Ok|Cancel|Help, Ok ),
+ mOpenPGPBackend( 0 ),
+ mSMIMEBackend( 0 ),
+ mRememberCB( 0 ),
+ mKeyUsage( keyUsage ),
+ mSearchText( initialQuery ),
+ mCurrentContextMenuItem( 0 )
+{
+ init( rememberChoice, extendedSelection, text, initialQuery );
+}
+
+void Kleo::KeySelectionDialog::init( bool rememberChoice, bool extendedSelection,
+ const QString & text, const QString & initialQuery ) {
+ if ( mKeyUsage & OpenPGPKeys )
+ mOpenPGPBackend = Kleo::CryptoBackendFactory::instance()->openpgp();
+ if ( mKeyUsage & SMIMEKeys )
+ mSMIMEBackend = Kleo::CryptoBackendFactory::instance()->smime();
+
+ mCheckSelectionTimer = new QTimer( this );
+ mStartSearchTimer = new QTimer( this );
+
+ QFrame *page = makeMainWidget();
+ mTopLayout = new QVBoxLayout( page, 0, spacingHint() );
+
+ if ( !text.isEmpty() ) {
+ QLabel* textLabel = new QLabel( text, page );
+ textLabel->setAlignment( textLabel->alignment() | Qt::WordBreak );
+ mTopLayout->addWidget( textLabel );
+ }
+
+ QHBoxLayout * hlay = new QHBoxLayout( mTopLayout ); // inherits spacing
+ QLineEdit * le = new QLineEdit( page );
+ le->setText( initialQuery );
+ QToolButton *clearButton = new QToolButton( page );
+ clearButton->setIconSet( KGlobal::iconLoader()->loadIconSet(
+ KApplication::reverseLayout() ? "clear_left":"locationbar_erase", KIcon::Small, 0 ) );
+ hlay->addWidget( clearButton );
+ hlay->addWidget( new QLabel( le, i18n("&Search for:"), page ) );
+ hlay->addWidget( le, 1 );
+ le->setFocus();
+
+ connect( clearButton, SIGNAL( clicked() ), le, SLOT( clear() ) );
+ connect( le, SIGNAL(textChanged(const QString&)),
+ this, SLOT(slotSearch(const QString&)) );
+ connect( mStartSearchTimer, SIGNAL(timeout()), SLOT(slotFilter()) );
+
+ mKeyListView = new KeyListView( new ColumnStrategy( mKeyUsage ), 0, page, "mKeyListView" );
+ mKeyListView->setResizeMode( QListView::LastColumn );
+ mKeyListView->setRootIsDecorated( true );
+ mKeyListView->setShowSortIndicator( true );
+ mKeyListView->setSorting( 1, true ); // sort by User ID
+ mKeyListView->setShowToolTips( true );
+ if ( extendedSelection )
+ mKeyListView->setSelectionMode( QListView::Extended );
+ mTopLayout->addWidget( mKeyListView, 10 );
+
+ if ( rememberChoice ) {
+ mRememberCB = new QCheckBox( i18n("&Remember choice"), page );
+ mTopLayout->addWidget( mRememberCB );
+ QWhatsThis::add( mRememberCB,
+ i18n("<qt><p>If you check this box your choice will "
+ "be stored and you will not be asked again."
+ "</p></qt>") );
+ }
+
+ connect( mCheckSelectionTimer, SIGNAL(timeout()),
+ SLOT(slotCheckSelection()) );
+ connectSignals();
+
+ connect( mKeyListView,
+ SIGNAL(doubleClicked(Kleo::KeyListViewItem*,const QPoint&,int)),
+ SLOT(slotTryOk()) );
+ connect( mKeyListView,
+ SIGNAL(contextMenu(Kleo::KeyListViewItem*,const QPoint&)),
+ SLOT(slotRMB(Kleo::KeyListViewItem*,const QPoint&)) );
+
+ setButtonText( KDialogBase::Default, i18n("&Reread Keys") );
+ setButtonGuiItem( KDialogBase::Help, i18n("&Start Certificate Manager") );
+ connect( this, SIGNAL(defaultClicked()), this, SLOT(slotRereadKeys()) );
+ connect( this, SIGNAL(helpClicked()), this, SLOT(slotStartCertificateManager()) );
+
+ slotRereadKeys();
+ mTopLayout->activate();
+
+ if ( kapp ) {
+ KWin::setIcons( winId(), kapp->icon(), kapp->miniIcon() );
+ QSize dialogSize( 500, 400 );
+
+ KConfigGroup dialogConfig( KGlobal::config(), "Key Selection Dialog" );
+ dialogSize = dialogConfig.readSizeEntry( "Dialog size", &dialogSize );
+ resize( dialogSize );
+ }
+}
+
+Kleo::KeySelectionDialog::~KeySelectionDialog() {
+ KConfigGroup dialogConfig( KGlobal::config(), "Key Selection Dialog" );
+ dialogConfig.writeEntry( "Dialog size", size() );
+ dialogConfig.sync();
+}
+
+
+void Kleo::KeySelectionDialog::connectSignals() {
+ if ( mKeyListView->isMultiSelection() )
+ connect( mKeyListView, SIGNAL(selectionChanged()),
+ SLOT(slotSelectionChanged()) );
+ else
+ connect( mKeyListView, SIGNAL(selectionChanged(Kleo::KeyListViewItem*)),
+ SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) );
+}
+
+void Kleo::KeySelectionDialog::disconnectSignals() {
+ if ( mKeyListView->isMultiSelection() )
+ disconnect( mKeyListView, SIGNAL(selectionChanged()),
+ this, SLOT(slotSelectionChanged()) );
+ else
+ disconnect( mKeyListView, SIGNAL(selectionChanged(Kleo::KeyListViewItem*)),
+ this, SLOT(slotCheckSelection(Kleo::KeyListViewItem*)) );
+}
+
+const GpgME::Key & Kleo::KeySelectionDialog::selectedKey() const {
+ if ( mKeyListView->isMultiSelection() || !mKeyListView->selectedItem() )
+ return GpgME::Key::null;
+ return mKeyListView->selectedItem()->key();
+}
+
+QString Kleo::KeySelectionDialog::fingerprint() const {
+ return selectedKey().primaryFingerprint();
+}
+
+QStringList Kleo::KeySelectionDialog::fingerprints() const {
+ QStringList result;
+ for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
+ if ( const char * fpr = it->primaryFingerprint() )
+ result.push_back( fpr );
+ return result;
+}
+
+QStringList Kleo::KeySelectionDialog::pgpKeyFingerprints() const {
+ QStringList result;
+ for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
+ if ( it->protocol() == GpgME::Context::OpenPGP )
+ if ( const char * fpr = it->primaryFingerprint() )
+ result.push_back( fpr );
+ return result;
+}
+
+QStringList Kleo::KeySelectionDialog::smimeFingerprints() const {
+ QStringList result;
+ for ( std::vector<GpgME::Key>::const_iterator it = mSelectedKeys.begin() ; it != mSelectedKeys.end() ; ++it )
+ if ( it->protocol() == GpgME::Context::CMS )
+ if ( const char * fpr = it->primaryFingerprint() )
+ result.push_back( fpr );
+ return result;
+}
+
+void Kleo::KeySelectionDialog::slotRereadKeys() {
+ mKeyListView->clear();
+ mListJobCount = 0;
+ mTruncated = 0;
+ mSavedOffsetY = mKeyListView->contentsY();
+
+ disconnectSignals();
+ mKeyListView->setEnabled( false );
+
+ // FIXME: save current selection
+ if ( mOpenPGPBackend )
+ startKeyListJobForBackend( mOpenPGPBackend, std::vector<GpgME::Key>(), false /*non-validating*/ );
+ if ( mSMIMEBackend )
+ startKeyListJobForBackend( mSMIMEBackend, std::vector<GpgME::Key>(), false /*non-validating*/ );
+
+ if ( mListJobCount == 0 ) {
+ mKeyListView->setEnabled( true );
+ KMessageBox::information( this,
+ i18n("No backends found for listing keys. "
+ "Check your installation."),
+ i18n("Key Listing Failed") );
+ connectSignals();
+ }
+}
+
+void Kleo::KeySelectionDialog::slotHelp()
+{
+ emit helpClicked();
+}
+
+void Kleo::KeySelectionDialog::slotStartCertificateManager()
+{
+ KProcess certManagerProc;
+ certManagerProc << "kleopatra";
+
+ if( !certManagerProc.start( KProcess::DontCare ) )
+ KMessageBox::error( this, i18n( "Could not start certificate manager; "
+ "please check your installation." ),
+ i18n( "Certificate Manager Error" ) );
+ else
+ kdDebug(5006) << "\nslotStartCertManager(): certificate manager started.\n" << endl;
+}
+
+#ifndef __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+#define __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+static void showKeyListError( QWidget * parent, const GpgME::Error & err ) {
+ assert( err );
+ const QString msg = i18n( "<qt><p>An error occurred while fetching "
+ "the keys from the backend:</p>"
+ "<p><b>%1</b></p></qt>" )
+ .arg( QString::fromLocal8Bit( err.asString() ) );
+
+ KMessageBox::error( parent, msg, i18n( "Key Listing Failed" ) );
+}
+#endif // __KLEO_UI_SHOW_KEY_LIST_ERROR_H__
+
+namespace {
+ struct ExtractFingerprint {
+ QString operator()( const GpgME::Key & key ) {
+ return key.primaryFingerprint();
+ }
+ };
+}
+
+void Kleo::KeySelectionDialog::startKeyListJobForBackend( const CryptoBackend::Protocol * backend, const std::vector<GpgME::Key> & keys, bool validate ) {
+ assert( backend );
+ KeyListJob * job = backend->keyListJob( false, false, validate ); // local, w/o sigs, validation as givem
+ if ( !job )
+ return;
+
+ connect( job, SIGNAL(result(const GpgME::KeyListResult&)),
+ SLOT(slotKeyListResult(const GpgME::KeyListResult&)) );
+ connect( job, SIGNAL(nextKey(const GpgME::Key&)),
+ mKeyListView, validate ?
+ SLOT(slotRefreshKey(const GpgME::Key&)) :
+ SLOT(slotAddKey(const GpgME::Key&)) );
+
+ QStringList fprs;
+ std::transform( keys.begin(), keys.end(), std::back_inserter( fprs ), ExtractFingerprint() );
+ const GpgME::Error err = job->start( fprs, mKeyUsage & SecretKeys && !( mKeyUsage & PublicKeys ) );
+
+ if ( err )
+ return showKeyListError( this, err );
+
+ // FIXME: create a MultiProgressDialog:
+ (void)new ProgressDialog( job, validate ? i18n( "Checking selected keys..." ) : i18n( "Fetching keys..." ), this );
+ ++mListJobCount;
+}
+
+static void selectKeys( Kleo::KeyListView * klv, const std::vector<GpgME::Key> & selectedKeys ) {
+ klv->clearSelection();
+ if ( selectedKeys.empty() )
+ return;
+ for ( std::vector<GpgME::Key>::const_iterator it = selectedKeys.begin() ; it != selectedKeys.end() ; ++it )
+ if ( Kleo::KeyListViewItem * item = klv->itemByFingerprint( it->primaryFingerprint() ) )
+ item->setSelected( true );
+}
+
+void Kleo::KeySelectionDialog::slotKeyListResult( const GpgME::KeyListResult & res ) {
+ if ( res.error() )
+ showKeyListError( this, res.error() );
+ else if ( res.isTruncated() )
+ ++mTruncated;
+
+ if ( --mListJobCount > 0 )
+ return; // not yet finished...
+
+ if ( mTruncated > 0 )
+ KMessageBox::information( this,
+ i18n("<qt>One backend returned truncated output.<br>"
+ "Not all available keys are shown</qt>",
+ "<qt>%n backends returned truncated output.<br>"
+ "Not all available keys are shown</qt>",
+ mTruncated),
+ i18n("Key List Result") );
+
+ mKeyListView->flushKeys();
+
+ mKeyListView->setEnabled( true );
+ mListJobCount = mTruncated = 0;
+ mKeysToCheck.clear();
+
+ selectKeys( mKeyListView, mSelectedKeys );
+
+ slotFilter();
+
+ connectSignals();
+
+ slotSelectionChanged();
+
+ // restore the saved position of the contents
+ mKeyListView->setContentsPos( 0, mSavedOffsetY ); mSavedOffsetY = 0;
+}
+
+void Kleo::KeySelectionDialog::slotSelectionChanged() {
+ kdDebug(5150) << "KeySelectionDialog::slotSelectionChanged()" << endl;
+
+ // (re)start the check selection timer. Checking the selection is delayed
+ // because else drag-selection doesn't work very good (checking key trust
+ // is slow).
+ mCheckSelectionTimer->start( sCheckSelectionDelay );
+}
+
+namespace {
+ struct AlreadyChecked {
+ bool operator()( const GpgME::Key & key ) const {
+ return key.keyListMode() & GpgME::Context::Validate ;
+ }
+ };
+}
+
+void Kleo::KeySelectionDialog::slotCheckSelection( KeyListViewItem * item ) {
+ kdDebug(5150) << "KeySelectionDialog::slotCheckSelection()\n";
+
+ mCheckSelectionTimer->stop();
+
+ mSelectedKeys.clear();
+
+ if ( !mKeyListView->isMultiSelection() ) {
+ if ( item )
+ mSelectedKeys.push_back( item->key() );
+ }
+
+ for ( KeyListViewItem * it = mKeyListView->firstChild() ; it ; it = it->nextSibling() )
+ if ( it->isSelected() )
+ mSelectedKeys.push_back( it->key() );
+
+ mKeysToCheck.clear();
+ std::remove_copy_if( mSelectedKeys.begin(), mSelectedKeys.end(),
+ std::back_inserter( mKeysToCheck ),
+ AlreadyChecked() );
+ if ( mKeysToCheck.empty() ) {
+ enableButtonOK( !mSelectedKeys.empty() &&
+ checkKeyUsage( mSelectedKeys, mKeyUsage ) );
+ return;
+ }
+
+ // performed all fast checks - now for validating key listing:
+ startValidatingKeyListing();
+}
+
+void Kleo::KeySelectionDialog::startValidatingKeyListing() {
+ if ( mKeysToCheck.empty() )
+ return;
+
+ mListJobCount = 0;
+ mTruncated = 0;
+ mSavedOffsetY = mKeyListView->contentsY();
+
+ disconnectSignals();
+ mKeyListView->setEnabled( false );
+
+ std::vector<GpgME::Key> smime, openpgp;
+ for ( std::vector<GpgME::Key>::const_iterator it = mKeysToCheck.begin() ; it != mKeysToCheck.end() ; ++it )
+ if ( it->protocol() == GpgME::Context::OpenPGP )
+ openpgp.push_back( *it );
+ else
+ smime.push_back( *it );
+
+ if ( !openpgp.empty() ) {
+ assert( mOpenPGPBackend );
+ startKeyListJobForBackend( mOpenPGPBackend, openpgp, true /*validate*/ );
+ }
+ if ( !smime.empty() ) {
+ assert( mSMIMEBackend );
+ startKeyListJobForBackend( mSMIMEBackend, smime, true /*validate*/ );
+ }
+
+ assert( mListJobCount > 0 );
+}
+
+bool Kleo::KeySelectionDialog::rememberSelection() const {
+ return mRememberCB && mRememberCB->isChecked() ;
+}
+
+void Kleo::KeySelectionDialog::slotRMB( Kleo::KeyListViewItem * item, const QPoint & p ) {
+ if ( !item ) return;
+
+ mCurrentContextMenuItem = item;
+
+ QPopupMenu menu;
+ menu.insertItem( i18n( "Recheck Key" ), this, SLOT(slotRecheckKey()) );
+ menu.exec( p );
+}
+
+void Kleo::KeySelectionDialog::slotRecheckKey() {
+ if ( !mCurrentContextMenuItem || mCurrentContextMenuItem->key().isNull() )
+ return;
+
+ mKeysToCheck.clear();
+ mKeysToCheck.push_back( mCurrentContextMenuItem->key() );
+}
+
+void Kleo::KeySelectionDialog::slotTryOk() {
+ if ( actionButton( Ok )->isEnabled() )
+ slotOk();
+}
+
+void Kleo::KeySelectionDialog::slotOk() {
+ if ( mCheckSelectionTimer->isActive() )
+ slotCheckSelection();
+ // button could be disabled again after checking the selected key
+ if ( !actionButton( Ok )->isEnabled() )
+ return;
+ mStartSearchTimer->stop();
+ accept();
+}
+
+
+void Kleo::KeySelectionDialog::slotCancel() {
+ mCheckSelectionTimer->stop();
+ mStartSearchTimer->stop();
+ reject();
+}
+
+void Kleo::KeySelectionDialog::slotSearch( const QString & text ) {
+ mSearchText = text.stripWhiteSpace().upper();
+ slotSearch();
+}
+
+void Kleo::KeySelectionDialog::slotSearch() {
+ mStartSearchTimer->start( sCheckSelectionDelay, true /*single-shot*/ );
+}
+
+void Kleo::KeySelectionDialog::slotFilter() {
+ if ( mSearchText.isEmpty() ) {
+ showAllItems();
+ return;
+ }
+
+ // OK, so we need to filter:
+ QRegExp keyIdRegExp( "(?:0x)?[A-F0-9]{1,8}", false /*case-insens.*/ );
+ if ( keyIdRegExp.exactMatch( mSearchText ) ) {
+ if ( mSearchText.startsWith( "0X" ) )
+ // search for keyID only:
+ filterByKeyID( mSearchText.mid( 2 ) );
+ else
+ // search for UID and keyID:
+ filterByKeyIDOrUID( mSearchText );
+ } else {
+ // search in UID:
+ filterByUID( mSearchText );
+ }
+}
+
+void Kleo::KeySelectionDialog::filterByKeyID( const QString & keyID ) {
+ assert( keyID.length() <= 8 );
+ assert( !keyID.isEmpty() ); // regexp in slotFilter should prevent these
+ if ( keyID.isEmpty() )
+ showAllItems();
+ else
+ for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
+ item->setVisible( item->text( 0 ).upper().startsWith( keyID ) );
+}
+
+static bool anyUIDMatches( const Kleo::KeyListViewItem * item, QRegExp & rx ) {
+ if ( !item )
+ return false;
+
+ const std::vector<GpgME::UserID> uids = item->key().userIDs();
+ for ( std::vector<GpgME::UserID>::const_iterator it = uids.begin() ; it != uids.end() ; ++it )
+ if ( it->id() && rx.search( QString::fromUtf8( it->id() ) ) >= 0 )
+ return true;
+ return false;
+}
+
+void Kleo::KeySelectionDialog::filterByKeyIDOrUID( const QString & str ) {
+ assert( !str.isEmpty() );
+
+ // match beginnings of words:
+ QRegExp rx( "\\b" + QRegExp::escape( str ), false );
+
+ for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
+ item->setVisible( item->text( 0 ).upper().startsWith( str ) || anyUIDMatches( item, rx ) );
+
+}
+
+void Kleo::KeySelectionDialog::filterByUID( const QString & str ) {
+ assert( !str.isEmpty() );
+
+ // match beginnings of words:
+ QRegExp rx( "\\b" + QRegExp::escape( str ), false );
+
+ for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
+ item->setVisible( anyUIDMatches( item, rx ) );
+}
+
+
+void Kleo::KeySelectionDialog::showAllItems() {
+ for ( KeyListViewItem * item = mKeyListView->firstChild() ; item ; item = item->nextSibling() )
+ item->setVisible( true );
+}
+
+#include "keyselectiondialog.moc"
diff --git a/certmanager/lib/ui/keyselectiondialog.h b/certmanager/lib/ui/keyselectiondialog.h
new file mode 100644
index 000000000..f274398b1
--- /dev/null
+++ b/certmanager/lib/ui/keyselectiondialog.h
@@ -0,0 +1,179 @@
+/* -*- c++ -*-
+ keyselectiondialog.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarävdalens Datakonsult AB
+
+ Based on kpgpui.h
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_UI_KEYSELECTIONDIALOG_H__
+#define __KLEO_UI_KEYSELECTIONDIALOG_H__
+
+#include <kdialogbase.h>
+
+#include <kleo/cryptobackend.h>
+#include <gpgmepp/key.h>
+#include <kdepimmacros.h>
+#include <vector>
+
+class QVBoxLayout;
+class QCheckBox;
+class QPixmap;
+class QTimer;
+class QListViewItem;
+class QRegExp;
+class QPoint;
+
+namespace Kleo {
+ class KeyListView;
+ class KeyListViewItem;
+}
+
+namespace GpgME {
+ class KeyListResult;
+}
+
+namespace Kleo {
+
+ class KDE_EXPORT KeySelectionDialog : public KDialogBase {
+ Q_OBJECT
+ public:
+
+ enum KeyUsage {
+ PublicKeys = 1,
+ SecretKeys = 2,
+ EncryptionKeys = 4,
+ SigningKeys = 8,
+ ValidKeys = 16,
+ TrustedKeys = 32,
+ CertificationKeys = 64,
+ AuthenticationKeys = 128,
+ OpenPGPKeys = 256,
+ SMIMEKeys = 512,
+ AllKeys = PublicKeys | SecretKeys | OpenPGPKeys | SMIMEKeys,
+ ValidEncryptionKeys = AllKeys | EncryptionKeys | ValidKeys,
+ ValidTrustedEncryptionKeys = AllKeys | EncryptionKeys | ValidKeys | TrustedKeys
+ };
+
+ KeySelectionDialog( const QString & title,
+ const QString & text,
+ const std::vector<GpgME::Key> & selectedKeys=std::vector<GpgME::Key>(),
+ unsigned int keyUsage=AllKeys,
+ bool extendedSelection=false,
+ bool rememberChoice=false,
+ QWidget * parent=0, const char * name=0,
+ bool modal=true );
+ KeySelectionDialog( const QString & title,
+ const QString & text,
+ const QString & initialPattern,
+ unsigned int keyUsage=AllKeys,
+ bool extendedSelection=false,
+ bool rememberChoice=false,
+ QWidget * parent=0, const char * name=0,
+ bool modal=true );
+ ~KeySelectionDialog();
+
+ /** Returns the key ID of the selected key in single selection mode.
+ Otherwise it returns a null key. */
+ const GpgME::Key & selectedKey() const;
+
+ QString fingerprint() const;
+
+ /** Returns a list of selected key IDs. */
+ const std::vector<GpgME::Key> & selectedKeys() const { return mSelectedKeys; }
+
+ /// Return all the selected fingerprints
+ QStringList fingerprints() const;
+
+ /// Return the selected openpgp fingerprints
+ QStringList pgpKeyFingerprints() const;
+ /// Return the selected smime fingerprints
+ QStringList smimeFingerprints() const;
+
+ bool rememberSelection() const;
+ protected slots:
+ // reimplemented to avoid popping up the help, since we
+ // override the button
+ void slotHelp();
+
+ // Could be used by derived classes to insert their own widget
+ QVBoxLayout* topLayout() const { return mTopLayout; }
+
+ private slots:
+ void slotRereadKeys();
+ void slotStartCertificateManager();
+ void slotKeyListResult( const GpgME::KeyListResult & );
+ void slotSelectionChanged();
+ void slotCheckSelection() { slotCheckSelection( 0 ); }
+ void slotCheckSelection( Kleo::KeyListViewItem * );
+ void slotRMB( Kleo::KeyListViewItem *, const QPoint & );
+ void slotRecheckKey();
+ void slotTryOk();
+ void slotOk();
+ void slotCancel();
+ void slotSearch( const QString & text );
+ void slotSearch();
+ void slotFilter();
+
+ private:
+ void filterByKeyID( const QString & keyID );
+ void filterByKeyIDOrUID( const QString & keyID );
+ void filterByUID( const QString & uid );
+ void showAllItems();
+ bool anyChildMatches( const Kleo::KeyListViewItem * item, QRegExp & rx ) const;
+
+ void connectSignals();
+ void disconnectSignals();
+
+ void startKeyListJobForBackend( const Kleo::CryptoBackend::Protocol *, const std::vector<GpgME::Key> &, bool );
+ void startValidatingKeyListing();
+
+ void init( bool, bool, const QString &, const QString & );
+
+ private:
+ QVBoxLayout* mTopLayout;
+ Kleo::KeyListView * mKeyListView;
+ const Kleo::CryptoBackend::Protocol * mOpenPGPBackend;
+ const Kleo::CryptoBackend::Protocol * mSMIMEBackend;
+ QCheckBox * mRememberCB;
+ std::vector<GpgME::Key> mSelectedKeys, mKeysToCheck;
+ unsigned int mKeyUsage;
+ QTimer * mCheckSelectionTimer;
+ QTimer * mStartSearchTimer;
+ // cross-eventloop temporaries:
+ QString mSearchText;
+ Kleo::KeyListViewItem * mCurrentContextMenuItem;
+ int mTruncated, mListJobCount, mSavedOffsetY;
+ };
+
+}
+
+#endif // __KLEO_UI_KEYSELECTIONDIALOG_H__
diff --git a/certmanager/lib/ui/messagebox.cpp b/certmanager/lib/ui/messagebox.cpp
new file mode 100644
index 000000000..283d33108
--- /dev/null
+++ b/certmanager/lib/ui/messagebox.cpp
@@ -0,0 +1,265 @@
+/*
+ messagebox.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "messagebox.h"
+
+#include "kleo/job.h"
+
+#include <gpgmepp/signingresult.h>
+#include <gpgmepp/encryptionresult.h>
+
+#include <kfiledialog.h>
+#include <kdialogbase.h>
+#include <klocale.h>
+#include <ksavefile.h>
+#include <kguiitem.h>
+
+#include <qtextedit.h>
+#include <qtextstream.h>
+#include <qvbox.h>
+
+using namespace Kleo;
+using namespace GpgME;
+
+namespace {
+
+static KGuiItem KGuiItem_save() {
+ return KGuiItem( i18n("&Save to Disk..."), "filesaveas" );
+}
+
+static KGuiItem KGuiItem_copy() {
+ return KGuiItem( i18n("&Copy to Clipboard"), "editcopy", i18n("Copy Audit Log to Clipboard") );
+}
+
+static KGuiItem KGuiItem_showAuditLog() {
+ return KGuiItem( i18n("&Show Audit Log") ); // "view_log"?
+}
+
+class AuditLogViewer : public KDialogBase {
+ // Q_OBJECT
+public:
+ explicit AuditLogViewer( const QString & log, QWidget * parent=0, const char * name=0, WFlags f=0 )
+ : KDialogBase( parent, name, false, i18n("View GnuPG Audit Log"),
+ Close|User1|User2, Close, false, KGuiItem_save(), KGuiItem_copy() ),
+ m_textEdit( new QTextEdit( this, "m_textEdit" ) )
+ {
+ setWFlags( f );
+ setMainWidget( m_textEdit );
+ m_textEdit->setTextFormat( QTextEdit::RichText );
+ m_textEdit->setReadOnly( true );
+ setAuditLog( log );
+ }
+ ~AuditLogViewer() {}
+
+ void setAuditLog( const QString & log ) {
+ m_textEdit->setText( log );
+ }
+
+private:
+ void slotUser1() {
+ const QString fileName = KFileDialog::getSaveFileName( QString(), QString(),
+ this, i18n("Choose File to Save GnuPG Audit Log to") );
+ if ( fileName.isEmpty() )
+ return;
+
+ KSaveFile file( fileName );
+
+ if ( QTextStream * const s = file.textStream() ) {
+ *s << m_textEdit->text() << endl;
+ file.close();
+ }
+
+ if ( const int err = file.status() )
+ KMessageBox::error( this, i18n("Couldn't save to file \"%1\": %2")
+ .arg( file.name(), QString::fromLocal8Bit( strerror( err ) ) ),
+ i18n("File Save Error") );
+ }
+ void slotUser2() {
+ m_textEdit->selectAll();
+ m_textEdit->copy();
+ m_textEdit->selectAll( false );
+ }
+
+private:
+ QTextEdit * m_textEdit;
+};
+
+} // anon namespace
+
+// static
+void MessageBox::auditLog( QWidget * parent, const Job * job, const QString & caption ) {
+
+ if ( !job )
+ return;
+
+ if ( !GpgME::hasFeature( AuditLogFeature ) ) {
+ KMessageBox::information( parent, i18n("Your system does not have support for GnuPG Audit Logs"),
+ i18n("System Error") );
+ return;
+ }
+
+ const QString log = job->auditLogAsHtml();
+ if ( log.isEmpty() ) {
+ KMessageBox::information( parent, i18n("No GnuPG Audit Log available for this operation."),
+ i18n("No GnuPG Audit Log") );
+ return;
+ }
+
+ auditLog( parent, log, caption );
+}
+
+// static
+void MessageBox::auditLog( QWidget * parent, const QString & log, const QString & caption ) {
+ AuditLogViewer * const alv = new AuditLogViewer( "<qt>" + log + "</qt>", parent, "alv", Qt::WDestructiveClose );
+ alv->setCaption( caption );
+ alv->show();
+}
+
+// static
+void MessageBox::auditLog( QWidget * parent, const Job * job ) {
+ auditLog( parent, job, i18n("GnuPG Audit Log Viewer") );
+}
+
+// static
+void MessageBox::auditLog( QWidget * parent, const QString & log ) {
+ auditLog( parent, log, i18n("GnuPG Audit Log Viewer") );
+}
+
+static QString to_information_string( const SigningResult & result ) {
+ return result.error()
+ ? i18n("Signing failed: %1").arg( QString::fromLocal8Bit( result.error().asString() ) )
+ : i18n("Signing successful") ;
+}
+
+static QString to_error_string( const SigningResult & result ) {
+ return to_information_string( result );
+}
+
+static QString to_information_string( const EncryptionResult & result ) {
+ return result.error()
+ ? i18n("Encryption failed: %1").arg( QString::fromLocal8Bit( result.error().asString() ) )
+ : i18n("Encryption successful") ;
+}
+
+static QString to_error_string( const EncryptionResult & result ) {
+ return to_information_string( result );
+}
+
+static QString to_information_string( const SigningResult & sresult, const EncryptionResult & eresult ) {
+ return to_information_string( sresult ) + '\n' + to_information_string( eresult );
+}
+
+static QString to_error_string( const SigningResult & sresult, const EncryptionResult & eresult ) {
+ return to_information_string( sresult, eresult );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const SigningResult & result, const Job * job, int options ) {
+ information( parent, result, job, i18n("Signing Result"), options );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const SigningResult & result, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Information, to_information_string( result ), job, caption, options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const SigningResult & result, const Job * job, int options ) {
+ error( parent, result, job, i18n("Signing Error"), options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const SigningResult & result, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Critical, to_error_string( result ), job, caption, options );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const EncryptionResult & result, const Job * job, int options ) {
+ information( parent, result, job, i18n("Encryption Result"), options );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const EncryptionResult & result, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Information, to_information_string( result ), job, caption, options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const EncryptionResult & result, const Job * job, int options ) {
+ error( parent, result, job, i18n("Encryption Error"), options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const EncryptionResult & result, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Critical, to_error_string( result ), job, caption, options );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const SigningResult & sresult, const EncryptionResult & eresult, const Job * job, int options ) {
+ information( parent, sresult, eresult, job, i18n("Encryption Result"), options );
+}
+
+// static
+void MessageBox::information( QWidget * parent, const SigningResult & sresult, const EncryptionResult & eresult, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Information, to_information_string( sresult, eresult ), job, caption, options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const SigningResult & sresult, const EncryptionResult & eresult, const Job * job, int options ) {
+ error( parent, sresult, eresult, job, i18n("Encryption Error"), options );
+}
+
+// static
+void MessageBox::error( QWidget * parent, const SigningResult & sresult, const EncryptionResult & eresult, const Job * job, const QString & caption, int options ) {
+ make( parent, QMessageBox::Critical, to_error_string( sresult, eresult ), job, caption, options );
+}
+
+// static
+void MessageBox::make( QWidget * parent, QMessageBox::Icon icon, const QString & text, const Job * job, const QString & caption, int options ) {
+ KDialogBase * dialog = GpgME::hasFeature( GpgME::AuditLogFeature )
+ ? new KDialogBase( caption, KDialogBase::Yes | KDialogBase::No,
+ KDialogBase::Yes, KDialogBase::Yes,
+ parent, "error", true, true,
+ KStdGuiItem::ok(), KGuiItem_showAuditLog() )
+ : new KDialogBase( caption, KDialogBase::Yes,
+ KDialogBase::Yes, KDialogBase::Yes,
+ parent, "error", true, true,
+ KStdGuiItem::ok() ) ;
+ if ( options & KMessageBox::PlainCaption )
+ dialog->setPlainCaption( caption );
+
+ if ( KDialogBase::No == KMessageBox::createKMessageBox( dialog, icon, text, QStringList(), QString::null, 0, options ) )
+ auditLog( 0, job );
+}
diff --git a/certmanager/lib/ui/messagebox.h b/certmanager/lib/ui/messagebox.h
new file mode 100644
index 000000000..a84f86e11
--- /dev/null
+++ b/certmanager/lib/ui/messagebox.h
@@ -0,0 +1,83 @@
+/*
+ messagebox.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2007 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_UI_MESSAGEBOX_H__
+#define __KLEO_UI_MESSAGEBOX_H__
+
+#include <kmessagebox.h>
+
+namespace GpgME {
+ class SigningResult;
+ class EncryptionResult;
+ class DecryptionResult;
+ class VerificationResult;
+}
+
+namespace Kleo {
+ class Job;
+}
+
+class QWidget;
+class QString;
+
+namespace Kleo {
+
+ class MessageBox {
+ public:
+ static void information( QWidget * parent, const GpgME::SigningResult & result, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void information( QWidget * parent, const GpgME::SigningResult & result, const Kleo::Job * job, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::SigningResult & result, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::SigningResult & result, const Kleo::Job * job, int options=KMessageBox::Notify );
+
+ static void information( QWidget * parent, const GpgME::EncryptionResult & result, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void information( QWidget * parent, const GpgME::EncryptionResult & result, const Kleo::Job * job, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::EncryptionResult & result, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::EncryptionResult & result, const Kleo::Job * job, int options=KMessageBox::Notify );
+
+ static void information( QWidget * parent, const GpgME::SigningResult & sresult, const GpgME::EncryptionResult & eresult, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void information( QWidget * parent, const GpgME::SigningResult & sresult, const GpgME::EncryptionResult & eresult, const Kleo::Job * job, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::SigningResult & sresult, const GpgME::EncryptionResult & eresult, const Kleo::Job * job, const QString & caption, int options=KMessageBox::Notify );
+ static void error( QWidget * parent, const GpgME::SigningResult & sresult, const GpgME::EncryptionResult & eresult, const Kleo::Job * job, int options=KMessageBox::Notify );
+
+ static void auditLog( QWidget * parent, const Kleo::Job * job, const QString & caption );
+ static void auditLog( QWidget * parent, const Kleo::Job * job );
+ static void auditLog( QWidget * parent, const QString & log, const QString & caption );
+ static void auditLog( QWidget * parent, const QString & log );
+
+ private:
+ static void make( QWidget * parent, QMessageBox::Icon icon, const QString & text, const Kleo::Job * job, const QString & caption, int options );
+ };
+
+
+}
+
+#endif /* __KLEO_UI_MESSAGEBOX_H__ */
diff --git a/certmanager/lib/ui/passphrasedialog.cpp b/certmanager/lib/ui/passphrasedialog.cpp
new file mode 100644
index 000000000..5915387f5
--- /dev/null
+++ b/certmanager/lib/ui/passphrasedialog.cpp
@@ -0,0 +1,123 @@
+/* -*- c++ -*-
+ passphrasedialog.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+
+ Based on kpgpui.cpp
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ This file is part of KPGP, the KDE PGP/GnuPG support library.
+
+ KPGP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "passphrasedialog.h"
+
+#include <kpassdlg.h>
+#include <kiconloader.h>
+#include <klocale.h>
+
+#include <qlabel.h>
+#include <qlayout.h>
+#include <qfontmetrics.h>
+
+struct Kleo::PassphraseDialog::Private {
+ KPasswordEdit * lineedit;
+};
+
+
+Kleo::PassphraseDialog::PassphraseDialog( const QString & msg, const QString & caption,
+ QWidget * parent, const char * name, bool modal )
+ : KDialogBase( parent, name, modal, caption, Ok|Cancel, Ok ), d( 0 )
+{
+ d = new Private();
+
+ QWidget * w = new QWidget( this );
+ setMainWidget( w );
+
+ QHBoxLayout * hlay = new QHBoxLayout( w, 0, spacingHint() );
+
+ QLabel * label = new QLabel( w );
+ label->setPixmap( DesktopIcon( "pgp-keys", KIcon::SizeMedium ) );
+ hlay->addWidget( label, 0, AlignTop );
+
+ QVBoxLayout * vlay = new QVBoxLayout( hlay ); // inherits spacing
+
+ vlay->addWidget( new QLabel( msg.isEmpty() ? i18n("Please enter your passphrase:") : msg, w ) );
+
+ d->lineedit = new KPasswordEdit( KPasswordEdit::OneStar, w, "d->lineedit" );
+ d->lineedit->setMinimumWidth( fontMetrics().width("*") * 20 );
+ d->lineedit->setFocus();
+
+ vlay->addWidget( d->lineedit );
+
+ connect( d->lineedit, SIGNAL(returnPressed()), SLOT(slotOk()) );
+
+ disableResize();
+}
+
+
+Kleo::PassphraseDialog::~PassphraseDialog() {
+ delete d; d = 0;
+}
+
+const char * Kleo::PassphraseDialog::passphrase() const {
+ return d->lineedit->password();
+}
+
+void Kleo::PassphraseDialog::slotOk() {
+ const char * pass = passphrase();
+ emit finished( pass ? pass : "" );
+ KDialogBase::slotOk();
+}
+
+void Kleo::PassphraseDialog::slotCancel() {
+ emit canceled();
+ KDialogBase::slotCancel();
+}
+
+
+void Kleo::PassphraseDialog::virtual_hook( int id, void * data ) {
+ return KDialogBase::virtual_hook( id, data );
+}
+
+#include "passphrasedialog.moc"
diff --git a/certmanager/lib/ui/passphrasedialog.h b/certmanager/lib/ui/passphrasedialog.h
new file mode 100644
index 000000000..12a434e13
--- /dev/null
+++ b/certmanager/lib/ui/passphrasedialog.h
@@ -0,0 +1,91 @@
+/* -*- c++ -*-
+ passphrasedialog.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+
+
+ Based on kpgpui.h
+ Copyright (C) 2001,2002 the KPGP authors
+ See file libkdenetwork/AUTHORS.kpgp for details
+
+ This file is part of KPGP, the KDE PGP/GnuPG support library.
+
+ KPGP is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+*/
+
+#ifndef __KLEO_UI_PASSPHRASEDIALOG_H__
+#define __KLEO_UI_PASSPHRASEDIALOG_H__
+
+#include <kdialogbase.h>
+
+namespace Kleo {
+
+ class PassphraseDialog : public KDialogBase {
+ Q_OBJECT
+ public:
+ PassphraseDialog( const QString & description,
+ const QString & caption=QString::null,
+ QWidget * parent=0, const char * name=0,
+ bool modal=true );
+ ~PassphraseDialog();
+
+ const char * passphrase() const;
+
+ signals:
+ /** emitted when the user clicks Ok. \a pass is never NULL.
+ \c pass only valid inside slots connected to this signal.
+ */
+ void finished( const char * pass );
+ /** emitted when the user clicks Cancel. */
+ void canceled();
+
+ protected slots:
+ /*! \reimp */
+ void slotOk();
+ /*! \reimp */
+ void slotCancel();
+
+ private:
+ class Private;
+ Private * d;
+ protected:
+ /*! \reimp */
+ void virtual_hook( int, void* );
+ };
+
+} // namespace Kleo
+
+#endif // __KLEO_UI_PASSPHRASEDIALOG_H__
diff --git a/certmanager/lib/ui/progressbar.cpp b/certmanager/lib/ui/progressbar.cpp
new file mode 100644
index 000000000..96f51fa8a
--- /dev/null
+++ b/certmanager/lib/ui/progressbar.cpp
@@ -0,0 +1,111 @@
+/*
+ progressbar.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "config.h"
+#include "progressbar.h"
+
+#include <qtimer.h>
+#include <kdebug.h>
+
+static const int busyTimerTickInterval = 100;
+static const int busyTimerTickIncrement = 5;
+
+Kleo::ProgressBar::ProgressBar( QWidget * parent, const char * name, WFlags f )
+ : QProgressBar( 0, parent, name, f ),
+ mRealProgress( -1 )
+{
+ mBusyTimer = new QTimer( this );
+ connect( mBusyTimer, SIGNAL(timeout()), SLOT(slotBusyTimerTick()) );
+ fixup( true );
+}
+
+void Kleo::ProgressBar::slotProgress( const QString &, int cur, int tot ) {
+ setProgress( cur, tot );
+}
+
+void Kleo::ProgressBar::slotProgress( const QString &, int, int cur, int tot ) {
+ setProgress( cur, tot );
+}
+
+void Kleo::ProgressBar::setTotalSteps( int total ) {
+ kdDebug() << "Kleo::ProgressBar::setTotalSteps( " << total << " )" << endl;
+ if ( total == totalSteps() )
+ return;
+ QProgressBar::setTotalSteps( 0 );
+ fixup( false );
+}
+
+void Kleo::ProgressBar::setProgress( int p ) {
+ kdDebug() << "Kleo::ProgressBar::setProgress( " << p << " )" << endl;
+ mRealProgress = p;
+ fixup( true );
+}
+
+void Kleo::ProgressBar::reset() {
+ mRealProgress = -1;
+ fixup( true );
+}
+
+void Kleo::ProgressBar::slotBusyTimerTick() {
+ fixup( false );
+ if ( mBusyTimer->isActive() )
+ QProgressBar::setProgress( QProgressBar::progress() + busyTimerTickIncrement );
+}
+
+void Kleo::ProgressBar::fixup( bool newValue ) {
+ const int cur = QProgressBar::progress();
+ const int tot = QProgressBar::totalSteps();
+
+ kdDebug() << "Kleo::ProgressBar::startStopBusyTimer() cur = " << cur << "; tot = " << tot << "; real = " << mRealProgress << endl;
+
+ if ( ( newValue && mRealProgress < 0 ) || ( !newValue && cur < 0 ) ) {
+ kdDebug() << "(new value) switch to reset" << endl;
+ mBusyTimer->stop();
+ if ( newValue )
+ QProgressBar::reset();
+ mRealProgress = -1;
+ } else if ( tot == 0 ) {
+ kdDebug() << "(new value) switch or stay in busy" << endl;
+ if ( !mBusyTimer->isActive() ) {
+ mBusyTimer->start( busyTimerTickInterval );
+ if ( newValue )
+ QProgressBar::setProgress( mRealProgress );
+ }
+ } else {
+ kdDebug() << "(new value) normal progress" << endl;
+ mBusyTimer->stop();
+ if ( QProgressBar::progress() != mRealProgress )
+ QProgressBar::setProgress( mRealProgress );
+ }
+}
+
+#include "progressbar.moc"
diff --git a/certmanager/lib/ui/progressbar.h b/certmanager/lib/ui/progressbar.h
new file mode 100644
index 000000000..41d96796d
--- /dev/null
+++ b/certmanager/lib/ui/progressbar.h
@@ -0,0 +1,74 @@
+/*
+ progressbar.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_PROGRESSBAR_H__
+#define __KLEO_PROGRESSBAR_H__
+
+#include <qprogressbar.h>
+#include <kdepimmacros.h>
+class QTimer;
+
+namespace Kleo {
+
+ /**
+ @short A QProgressBar with self-powered busy indicator
+ */
+ class KDE_EXPORT ProgressBar : public QProgressBar {
+ Q_OBJECT
+ public:
+ ProgressBar( QWidget * parent=0, const char * name=0, WFlags f=0 );
+
+ public slots:
+ void slotProgress( const QString & message, int type, int current, int total );
+ void slotProgress( const QString & message, int current, int total );
+ /*! reimplementation to support self-powered busy indicator */
+ void setProgress( int progress );
+ /*! reimplementation to support self-powered busy indicator */
+ void setTotalSteps( int total );
+ /*! reimplementation to support self-powered busy indicator */
+ void reset();
+ /*! reimplementation to preserve visibility */
+ void setProgress( int cur, int tot ) { QProgressBar::setProgress( cur, tot ); }
+
+ private slots:
+ void slotBusyTimerTick();
+
+ private:
+ void fixup( bool );
+
+ private:
+ QTimer * mBusyTimer;
+ int mRealProgress;
+ };
+}
+
+#endif // __KLEO_PROGRESSBAR_H__
diff --git a/certmanager/lib/ui/progressdialog.cpp b/certmanager/lib/ui/progressdialog.cpp
new file mode 100644
index 000000000..bb66aca17
--- /dev/null
+++ b/certmanager/lib/ui/progressdialog.cpp
@@ -0,0 +1,98 @@
+/*
+ progressdialog.cpp
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#include "progressdialog.h"
+
+#include "progressbar.h"
+
+#include <kleo/job.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+
+#include <qtimer.h>
+
+#include <assert.h>
+
+Kleo::ProgressDialog::ProgressDialog( Job * job, const QString & baseText,
+ QWidget * creator, const char * name, WFlags f )
+ : QProgressDialog( creator, name, false, f ), mBaseText( baseText )
+{
+ assert( job );
+ setBar( new ProgressBar( this, "replacement progressbar in Kleo::ProgressDialog" ) );
+
+ setMinimumDuration( 2000 /*ms*/ );
+ setAutoReset( false );
+ setAutoClose( false );
+ setLabelText( baseText );
+ setProgress( 0, 0 ); // activate busy indicator
+
+ connect( job, SIGNAL(progress(const QString&,int,int)),
+ SLOT(slotProgress(const QString&,int,int)) );
+ connect( job, SIGNAL(done()), SLOT(slotDone()) );
+ connect( this, SIGNAL(canceled()),
+ job, SLOT(slotCancel()) );
+
+ QTimer::singleShot( minimumDuration(), this, SLOT(forceShow()) );
+}
+
+Kleo::ProgressDialog::~ProgressDialog() {
+
+}
+
+void Kleo::ProgressDialog::setMinimumDuration( int ms ) {
+ if ( 0 < ms && ms < minimumDuration() )
+ QTimer::singleShot( ms, this, SLOT(forceShow()) );
+ QProgressDialog::setMinimumDuration( ms );
+}
+
+void Kleo::ProgressDialog::slotProgress( const QString & what, int current, int total ) {
+ kdDebug(5150) << "Kleo::ProgressDialog::slotProgress( \"" << what << "\", "
+ << current << ", " << total << " )" << endl;
+ if ( mBaseText.isEmpty() )
+ setLabelText( what );
+ else if ( what.isEmpty() )
+ setLabelText( mBaseText );
+ else
+ setLabelText( i18n( "%1: %2" ).arg( mBaseText, what ) );
+ setProgress( current, total );
+}
+
+void Kleo::ProgressDialog::slotDone() {
+ kdDebug(5150) << "Kleo::ProgressDialog::slotDone()" << endl;
+ hide();
+ deleteLater();
+}
+
+
+#include "progressdialog.moc"
+
diff --git a/certmanager/lib/ui/progressdialog.h b/certmanager/lib/ui/progressdialog.h
new file mode 100644
index 000000000..0b419aabb
--- /dev/null
+++ b/certmanager/lib/ui/progressdialog.h
@@ -0,0 +1,66 @@
+/*
+ progressdialog.h
+
+ This file is part of libkleopatra, the KDE keymanagement library
+ Copyright (c) 2004 Klarälvdalens Datakonsult AB
+
+ Libkleopatra is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ Libkleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifndef __KLEO_PROGRESSDIALOG_H__
+#define __KLEO_PROGRESSDIALOG_H__
+
+#include <qprogressdialog.h>
+#include <qstring.h>
+#include <kdepimmacros.h>
+namespace Kleo {
+
+ class Job;
+
+ /**
+ @short A progress dialog for Kleo::Jobs
+ */
+ class KDE_EXPORT ProgressDialog : public QProgressDialog {
+ Q_OBJECT
+ public:
+ ProgressDialog( Job * job, const QString & baseText,
+ QWidget * creator=0, const char * name=0, WFlags f=0 );
+ ~ProgressDialog();
+
+ public slots:
+ /*! reimplementation */
+ void setMinimumDuration( int ms );
+
+ private slots:
+ void slotProgress( const QString & what, int current, int total );
+ void slotDone();
+ private:
+ QString mBaseText;
+ };
+
+}
+
+#endif // __KLEO_PROGRESSDIALOG_H__
diff --git a/certmanager/main.cpp b/certmanager/main.cpp
new file mode 100644
index 000000000..37545502d
--- /dev/null
+++ b/certmanager/main.cpp
@@ -0,0 +1,84 @@
+/*
+ main.cpp
+
+ This file is part of Kleopatra, the KDE keymanager
+ Copyright (c) 2001,2002,2004 Klarälvdalens Datakonsult AB
+
+ Kleopatra is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ Kleopatra is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+ In addition, as a special exception, the copyright holders give
+ permission to link the code of this program with any edition of
+ the Qt library by Trolltech AS, Norway (or with modified versions
+ of Qt that use the same license as Qt), and distribute linked
+ combinations including the two. You must obey the GNU General
+ Public License in all respects for all of the code used other than
+ Qt. If you modify this file, you may extend this exception to
+ your version of the file, but you are not obligated to do so. If
+ you do not wish to do so, delete this exception statement from
+ your version.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "aboutdata.h"
+#include "certmanager.h"
+
+#include <kleo/cryptobackendfactory.h>
+
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kglobal.h>
+#include <kiconloader.h>
+
+int main( int argc, char** argv )
+{
+ AboutData aboutData;
+
+ KCmdLineArgs::init(argc, argv, &aboutData);
+ static const KCmdLineOptions options[] = {
+ { "external" , I18N_NOOP("Search for external certificates initially"), 0 },
+ { "query " , I18N_NOOP("Initial query string"), 0 },
+ { "import-certificate ", I18N_NOOP("Name of certificate file to import"), 0 },
+ KCmdLineLastOption// End of options.
+ };
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+
+ KGlobal::locale()->insertCatalogue( "libkleopatra" );
+ KGlobal::iconLoader()->addAppDir( "libkleopatra" );
+
+ if( !Kleo::CryptoBackendFactory::instance()->smime() ) {
+ KMessageBox::error(0,
+ i18n( "<qt>The crypto plugin could not be initialized.<br>"
+ "Certificate Manager will terminate now.</qt>") );
+ return -2;
+ }
+
+ CertManager* manager = new CertManager( args->isSet("external"),
+ QString::fromLocal8Bit(args->getOption("query")),
+ QString::fromLocal8Bit(args->getOption("import-certificate")) );
+
+ args->clear();
+ manager->show();
+
+ return app.exec();
+}
diff --git a/certmanager/storedtransferjob.cpp b/certmanager/storedtransferjob.cpp
new file mode 100644
index 000000000..589acd702
--- /dev/null
+++ b/certmanager/storedtransferjob.cpp
@@ -0,0 +1,98 @@
+/*
+ Copyright (C) 2004 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "storedtransferjob.h"
+
+using namespace KIOext;
+
+#define KIO_ARGS QByteArray packedArgs; QDataStream stream( packedArgs, IO_WriteOnly ); stream
+
+StoredTransferJob::StoredTransferJob(const KURL& url, int command,
+ const QByteArray &packedArgs,
+ const QByteArray &_staticData,
+ bool showProgressInfo)
+ : KIO::TransferJob( url, command, packedArgs, _staticData, showProgressInfo ),
+ m_uploadOffset( 0 )
+{
+ connect( this, SIGNAL( data( KIO::Job *, const QByteArray & ) ),
+ SLOT( slotData( KIO::Job *, const QByteArray & ) ) );
+ connect( this, SIGNAL( dataReq( KIO::Job *, QByteArray & ) ),
+ SLOT( slotDataReq( KIO::Job *, QByteArray & ) ) );
+}
+
+void StoredTransferJob::setData( const QByteArray& arr )
+{
+ Q_ASSERT( m_data.isNull() ); // check that we're only called once
+ Q_ASSERT( m_uploadOffset == 0 ); // no upload started yet
+ m_data = arr;
+}
+
+void StoredTransferJob::slotData( KIO::Job *, const QByteArray &data )
+{
+ // check for end-of-data marker:
+ if ( data.size() == 0 )
+ return;
+ unsigned int oldSize = m_data.size();
+ m_data.resize( oldSize + data.size(), QGArray::SpeedOptim );
+ memcpy( m_data.data() + oldSize, data.data(), data.size() );
+}
+
+void StoredTransferJob::slotDataReq( KIO::Job *, QByteArray &data )
+{
+ // Inspired from kmail's KMKernel::byteArrayToRemoteFile
+ // send the data in 64 KB chunks
+ const int MAX_CHUNK_SIZE = 64*1024;
+ int remainingBytes = m_data.size() - m_uploadOffset;
+ if( remainingBytes > MAX_CHUNK_SIZE ) {
+ // send MAX_CHUNK_SIZE bytes to the receiver (deep copy)
+ data.duplicate( m_data.data() + m_uploadOffset, MAX_CHUNK_SIZE );
+ m_uploadOffset += MAX_CHUNK_SIZE;
+ //kdDebug() << "Sending " << MAX_CHUNK_SIZE << " bytes ("
+ // << remainingBytes - MAX_CHUNK_SIZE << " bytes remain)\n";
+ } else {
+ // send the remaining bytes to the receiver (deep copy)
+ data.duplicate( m_data.data() + m_uploadOffset, remainingBytes );
+ m_data = QByteArray();
+ m_uploadOffset = 0;
+ //kdDebug() << "Sending " << remainingBytes << " bytes\n";
+ }
+}
+
+////
+
+StoredTransferJob *KIOext::storedGet( const KURL& url, bool reload, bool showProgressInfo )
+{
+ // Send decoded path and encoded query
+ KIO_ARGS << url;
+ StoredTransferJob * job = new StoredTransferJob( url, KIO::CMD_GET, packedArgs, QByteArray(), showProgressInfo );
+ if (reload)
+ job->addMetaData("cache", "reload");
+ return job;
+}
+
+StoredTransferJob *KIOext::put( const QByteArray& arr, const KURL& url, int permissions,
+ bool overwrite, bool resume, bool showProgressInfo )
+{
+ KIO_ARGS << url << Q_INT8( overwrite ? 1 : 0 ) << Q_INT8( resume ? 1 : 0 ) << permissions;
+ StoredTransferJob * job = new StoredTransferJob( url, KIO::CMD_PUT, packedArgs, QByteArray(), showProgressInfo );
+ job->setData( arr );
+ return job;
+}
+
+#include "storedtransferjob.moc"
diff --git a/certmanager/storedtransferjob.h b/certmanager/storedtransferjob.h
new file mode 100644
index 000000000..85b591c6b
--- /dev/null
+++ b/certmanager/storedtransferjob.h
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2004 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef STOREDTRANSFERJOB_H
+#define STOREDTRANSFERJOB_H
+
+#include <kio/job.h>
+
+// To be moved to KIO?
+namespace KIOext {
+
+/**
+ * StoredTransferJob is a TransferJob (for downloading or uploading data) that
+ * also stores a QByteArray with the data, making it simpler to use than the
+ * standard TransferJob.
+ *
+ * For KIO::get it puts the data into the member QByteArray, so the user
+ * of this class can get hold of the whole data at once by calling data()
+ * when the result signal is emitted.
+ * You should only use StoredTransferJob to download data if you cannot
+ * process the data by chunks while it's being downloaded, since storing
+ * everything in a QByteArray can potentially require a lot of memory.
+ *
+ * For KIO::put the user of this class simply provides the bytearray from
+ * the start, and the job takes care of uploading it.
+ * You should only use StoredTransferJob to upload data if you cannot
+ * provide the in chunks while it's being uploaded, since storing
+ * everything in a QByteArray can potentially require a lot of memory.
+ *
+ */
+class StoredTransferJob : public KIO::TransferJob {
+ Q_OBJECT
+
+public:
+ /**
+ * Do not create a StoredTransferJob. Use storedGet() or storedPut()
+ * instead.
+ * @param url the url to get or put
+ * @param command the command to issue
+ * @param packedArgs the arguments
+ * @param _staticData additional data to transmit (e.g. in a HTTP Post)
+ * @param showProgressInfo true to show progress information to the user
+ */
+ StoredTransferJob(const KURL& url, int command,
+ const QByteArray &packedArgs,
+ const QByteArray &_staticData,
+ bool showProgressInfo);
+
+ /**
+ * Set data to be uploaded. This is for put jobs.
+ * Automatically called by KIOext::put(const QByteArray &, ...), do not call this yourself.
+ */
+ void setData( const QByteArray& arr );
+
+ /**
+ * Get hold of the downloaded data. This is for get jobs.
+ * You're supposed to call this only from the slot connected to the result() signal.
+ */
+ QByteArray data() const { return m_data; }
+
+private slots:
+ void slotData( KIO::Job *job, const QByteArray &data );
+ void slotDataReq( KIO::Job *job, QByteArray &data );
+private:
+ QByteArray m_data;
+ int m_uploadOffset;
+};
+
+ /**
+ * Get (a.k.a. read), into a single QByteArray.
+ * @see StoredTransferJob
+ *
+ * @param url the URL of the file
+ * @param reload true to reload the file, false if it can be taken from the cache
+ * @param showProgressInfo true to show progress information
+ * @return the job handling the operation.
+ */
+ StoredTransferJob *storedGet( const KURL& url, bool reload=false, bool showProgressInfo = true );
+
+ /**
+ * Put (a.k.a. write) data from a single QByteArray.
+ * @see StoredTransferJob
+ *
+ * @param url Where to write data.
+ * @param permissions May be -1. In this case no special permission mode is set.
+ * @param overwrite If true, any existing file will be overwritten.
+ * @param resume true to resume, false otherwise
+ * @param showProgressInfo true to show progress information
+ * @return the job handling the operation.
+ * @see multi_get()
+ */
+ StoredTransferJob *put( const QByteArray& arr, const KURL& url, int permissions,
+ bool overwrite, bool resume, bool showProgressInfo = true );
+
+} // namespace
+
+#endif