2 Copyright (C) 2015-2024 Ben Kibbey <bjk@luxsci.net>
4 This file is part of qpwmc.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
21 #include <QMessageBox>
22 #include "pwmdFileOptionsWidget.h"
23 #include "pwmdPasswordDialog.h"
26 static int lastCacheTimeout
;
28 PwmdFileOptionsWidget::PwmdFileOptionsWidget (QWidget
*p
) : QFrame (p
)
34 _decryptKeyFile
= QString ();
35 _filename
= QString ();
38 connect (ui
.pb_changePassphrase
, SIGNAL (clicked()), this,
39 SLOT (slotChangePassword ()));
40 connect (ui
.pb_clearCache
, SIGNAL (clicked ()), this,
41 SLOT (slotClearCacheEntry ()));
42 connect (ui
.pb_updateCacheTimeout
, SIGNAL (clicked ()), this,
43 SLOT (slotUpdateCacheTimeout ()));
44 ui
.pb_updateCacheTimeout
->setEnabled (false);
45 connect (ui
.sp_cacheTimeout
, SIGNAL (valueChanged (int)), this,
46 SLOT (slotCacheTimeoutChanged (int)));
47 connect (ui
.ck_notCached
, SIGNAL (stateChanged (int)), this,
48 SLOT (slotNotCachedChanged (int)));
49 connect (ui
.ck_noTimeout
, SIGNAL (stateChanged (int)), this,
50 SLOT (slotNoTimeoutChanged (int)));
53 PwmdFileOptionsWidget::~PwmdFileOptionsWidget ()
58 PwmdFileOptionsWidget::decryptKeyFile ()
60 return _decryptKeyFile
;
63 /* 'opened' is true when called from PwmdFileOptionsDialog. */
65 PwmdFileOptionsWidget::setFilename (QString s
, bool opened
)
68 ui
.l_filename
->setText (s
.isEmpty () ? "-" : _filename
);
72 ui
.pb_changePassphrase
->setText (tr ("&Key file..."));
77 pwm
->command (new PwmdCommandQueueItem (PwmdCmdIdFileGetConfig
, "GETCONFIG",
78 Pwmd::inquireCallback
,
79 new PwmdInquireData (QString ("%1 cache_timeout").arg (_filename
))),
82 PwmdInquireData
*inq
= new PwmdInquireData (_filename
);
83 PwmdCommandQueueItem
*item
= new PwmdCommandQueueItem (PwmdCmdIdFileIsCached
,
85 Pwmd::inquireCallback
, inq
);
86 item
->addError (GPG_ERR_SOURCE_USER_1
, GPG_ERR_ENOENT
);
87 pwm
->command (item
, true);
92 connect (ui
.ck_lock
, SIGNAL (stateChanged (int)), this,
93 SLOT (slotLock (int)));
95 item
= new PwmdCommandQueueItem (PwmdCmdIdFileKeyInfo
, "KEYINFO",
96 Pwmd::inquireCallback
, 0);
97 item
->addError (GPG_ERR_SOURCE_USER_1
, GPG_ERR_NO_DATA
);
98 pwm
->command (item
, true);
100 pwm
->command (new PwmdCommandQueueItem (PwmdCmdIdFileClientInfo
,
101 "GETINFO", Pwmd::inquireCallback
,
102 new PwmdInquireData ("--verbose CLIENTS")));
107 ui
.sp_cacheTimeout
->setEnabled (pwm
->state () == Pwmd::Opened
108 && pwm
->filename () == s
);
109 ui
.ck_noTimeout
->setEnabled (ui
.sp_cacheTimeout
->isEnabled ());
110 ui
.ck_notCached
->setEnabled (ui
.sp_cacheTimeout
->isEnabled ());
111 ui
.pb_updateCacheTimeout
->setEnabled (ui
.sp_cacheTimeout
->isEnabled ());
115 PwmdFileOptionsWidget::lock ()
117 return ui
.ck_lock
->isChecked ();
121 PwmdFileOptionsWidget::slotLock (int n
)
123 bool b
= n
== Qt::Checked
? true : false;
124 PwmdInquireData
*inq
= new PwmdInquireData();
125 inq
->setUserBool (b
);
126 PwmdCommandQueueItem
*cmd
= new PwmdCommandQueueItem (PwmdCmdIdFileLock
,
127 b
? "LOCK" : "UNLOCK",
130 cmd
->addError (GPG_ERR_SOURCE_USER_1
, GPG_ERR_NOT_LOCKED
);
132 if (!pwm
->command (cmd
))
137 PwmdFileOptionsWidget::setHandle (Pwmd
*p
)
140 connect (pwm
, SIGNAL (statusMessage (QString
, void *)), this, SLOT (slotStatusMessage (QString
, void *)));
141 connect (pwm
, SIGNAL (commandResult (PwmdCommandQueueItem
*, QString
, gpg_error_t
, bool)), this, SLOT (slotCommandResult (PwmdCommandQueueItem
*, QString
, gpg_error_t
, bool)));
145 PwmdFileOptionsWidget::setLocked (bool b
)
147 ui
.ck_lock
->disconnect (this);
148 ui
.ck_lock
->setChecked (b
);
149 connect (ui
.ck_lock
, SIGNAL (stateChanged (int)), this, SLOT (slotLock (int)));
153 PwmdFileOptionsWidget::isCachedFinalize (gpg_error_t rc
)
155 if (gpg_err_code (rc
) == GPG_ERR_ENOENT
)
156 ui
.pb_changePassphrase
->setEnabled (false);
158 ui
.l_cached
->setText (rc
? tr ("no") : tr ("yes"));
159 ui
.pb_clearCache
->setEnabled (rc
? false : true);
163 PwmdFileOptionsWidget::cacheTimeoutFinalize (const QString
&result
)
165 int n
= result
.toInt();
167 lastCacheTimeout
= n
;
168 ui
.sp_cacheTimeout
->setValue (n
);
169 slotCacheTimeoutChanged (n
);
173 showErrorMsg (gpg_error_t rc
, const QString
&str
)
177 m
.setText (QApplication::
178 tr ("There was an error while communicating with pwmd."));
179 m
.setInformativeText (QString ("ERR %1: %2: %3").arg (rc
).arg (gpg_strsource (rc
), str
));
180 m
.setIcon (QMessageBox::Critical
);
185 PwmdFileOptionsWidget::refreshClientInfoFinalize (const QString
&line
)
187 QStringList list
= line
.split ("\n");
188 unsigned t
= list
.count();
190 for (unsigned i
= 0; i
< t
; i
++)
192 if (list
.at (i
).isEmpty())
195 ClientInfo
*ci
= ClientInfo::parseLine (list
.at (i
));
196 if (ci
->filename () == _filename
&& ci
->self ())
198 ui
.ck_lock
->disconnect (this);
199 ui
.ck_lock
->setChecked (ci
->locked ());
200 connect (ui
.ck_lock
, SIGNAL (stateChanged (int)), this, SLOT (slotLock (int)));
210 PwmdFileOptionsWidget::slotCommandResult (PwmdCommandQueueItem
*item
,
211 QString result
, gpg_error_t rc
,
214 if ((item
->id () >= 0 && item
->id () <= PwmdCmdIdClientMax
)
215 || item
->id () >= PwmdCmdIdFileMax
)
223 case PwmdCmdIdInternalConnect
:
224 case PwmdCmdIdInternalConnectHost
:
225 case PwmdCmdIdInternalOpen
:
226 case PwmdCmdIdInternalSave
:
229 case PwmdCmdIdInternalPassword
:
230 (void)pwmd_setopt (pwm
->handle (), PWMD_OPTION_LOCAL_PINENTRY
, 0);
231 (void)pwmd_setopt (pwm
->handle (), PWMD_OPTION_OVERRIDE_INQUIRE
, 0);
233 case PwmdCmdIdFileIsCached
:
234 isCachedFinalize (rc
);
236 case PwmdCmdIdFileGetConfig
:
237 cacheTimeoutFinalize (result
);
239 case PwmdCmdIdFileCacheTimeout
:
240 updateCacheTimeoutFinalize (rc
);
242 case PwmdCmdIdFileClearCache
:
243 clearCacheEntryFinalize (rc
);
245 case PwmdCmdIdFileKeyInfo
:
246 keyInfoFinalize (rc
, result
);
248 case PwmdCmdIdFileClientInfo
:
250 refreshClientInfoFinalize (result
);
252 case PwmdCmdIdFileLock
:
253 if (rc
&& gpg_err_code (rc
) != GPG_ERR_NOT_LOCKED
)
255 ui
.ck_lock
->disconnect (this);
256 ui
.ck_lock
->setChecked (!ui
.ck_lock
->isChecked ());
257 connect (ui
.ck_lock
, SIGNAL (stateChanged (int)), this, SLOT (slotLock (int)));
260 emit
clientLockStateChanged (ui
.ck_lock
->isChecked ());
266 if (rc
&& !item
->checkError (rc
) && !queued
)
268 if (item
->error () && !item
->errorString().isEmpty ())
269 showErrorMsg (item
->error (), item
->errorString ());
271 Pwmd::showError (rc
, pwm
);
278 PwmdFileOptionsWidget::keyInfoFinalize (gpg_error_t rc
, const QString
&result
)
284 if (gpg_err_code (rc
) == GPG_ERR_NO_DATA
)
287 list
= result
.split ("\n");
289 for (int n
= 0; n
< list
.count(); n
++)
291 if (list
.at(n
).at(0) != 'S')
298 ui
.pb_changePassphrase
->setEnabled (!_sym
);
302 PwmdFileOptionsWidget::slotStatusMessage (QString line
, void *data
)
305 if (line
.contains ("CACHE"))
307 PwmdCommandQueueItem
*item
= new PwmdCommandQueueItem (PwmdCmdIdFileIsCached
, QString("ISCACHED %1").arg (pwm
->filename()));
308 item
->addError (GPG_ERR_SOURCE_USER_1
, GPG_ERR_ENOENT
);
314 PwmdFileOptionsWidget::clearCacheEntryFinalize (gpg_error_t rc
)
317 ui
.l_cached
->setText (tr ("no"));
318 ui
.pb_clearCache
->setEnabled (!rc
? false : true);
322 PwmdFileOptionsWidget::slotClearCacheEntry ()
324 pwm
->command (new PwmdCommandQueueItem (PwmdCmdIdFileClearCache
, QString ("CLEARCACHE %1").arg (_filename
)));
328 PwmdFileOptionsWidget::updateCacheTimeoutFinalize (gpg_error_t rc
)
332 lastCacheTimeout
= ui
.sp_cacheTimeout
->value ();
333 ui
.ck_notCached
->setChecked (ui
.sp_cacheTimeout
->value () == 0);
334 ui
.ck_noTimeout
->setChecked (ui
.sp_cacheTimeout
->value () == -1);
337 ui
.pb_updateCacheTimeout
->setEnabled (!!rc
);
339 emit
commandsFinished ();
343 PwmdFileOptionsWidget::slotUpdateCacheTimeout ()
345 pwm
->command (new PwmdCommandQueueItem (PwmdCmdIdFileCacheTimeout
, QString ("CACHETIMEOUT %1").arg (ui
.sp_cacheTimeout
->value())));
349 PwmdFileOptionsWidget::updateCacheTimeout ()
351 if (ui
.pb_updateCacheTimeout
->isEnabled ())
354 slotUpdateCacheTimeout ();
362 PwmdFileOptionsWidget::slotCacheTimeoutChanged (int n
)
364 ui
.pb_updateCacheTimeout
->setEnabled (lastCacheTimeout
!= n
);
365 ui
.ck_noTimeout
->setChecked (n
== -1);
366 ui
.ck_notCached
->setChecked (n
== 0);
370 PwmdFileOptionsWidget::slotNotCachedChanged (int n
)
372 bool b
= n
== Qt::Checked
? true : false;
374 ui
.ck_noTimeout
->setChecked (!b
&& ui
.sp_cacheTimeout
->value () == -1);
376 ui
.sp_cacheTimeout
->setValue (0);
380 PwmdFileOptionsWidget::slotNoTimeoutChanged (int n
)
382 bool b
= n
== Qt::Checked
? true : false;
384 ui
.ck_notCached
->setChecked (!b
&& ui
.sp_cacheTimeout
->value () == 0);
386 ui
.sp_cacheTimeout
->setValue (-1);
389 /* Also used to select a filename during PwmdOpenDialog. */
391 PwmdFileOptionsWidget::slotChangePassword ()
393 PwmdPasswordDialog
*d
= new PwmdPasswordDialog (this);
396 d
->setDecryptKeyFile (_decryptKeyFile
);
398 d
->setSymmetric (_sym
);
399 d
->setHasSigners (_sign
);
400 d
->setNewFile (false);
406 if (d
->useKeyFile ())
410 _decryptKeyFile
= d
->decryptKeyFile ();
415 PwmdInquireData
*inq
= new PwmdInquireData
;
417 inq
->setHandle (pwm
->handle());
418 inq
->setKeyFile (d
->decryptKeyFile ());
421 inq
->setEncryptKeyFile (d
->signKeyFile ());
423 inq
->setEncryptKeyFile (d
->encryptKeyFile ());
425 inq
->setSignKeyFile (d
->signKeyFile ());
426 rc
= pwmd_setopt (pwm
->handle (), PWMD_OPTION_LOCAL_PINENTRY
, 1);
428 rc
= pwmd_setopt (pwm
->handle (), PWMD_OPTION_OVERRIDE_INQUIRE
, 1);
431 pwm
->passwd (0, Pwmd::inquireCallback
, inq
);
435 rc
= pwmd_setopt (pwm
->handle (), PWMD_OPTION_LOCAL_PINENTRY
, 0);
437 rc
= pwmd_setopt (pwm
->handle (), PWMD_OPTION_OVERRIDE_INQUIRE
, 0);
444 Pwmd::showError (rc
, pwm
);