You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeutils/kgpg/popuppublic.cpp

523 lines
18 KiB

/***************************************************************************
popuppublic.cpp - description
-------------------
begin : Sat Jun 29 2002
copyright : (C) 2002 by Jean-Baptiste Mardelle
email : bj@altern.org
updated to handle gpg21 : Sun Jul 30 10:18:29 CEST 2017
copyright : (C) 2017 by Emanoil Kotsev
email : deloptes@yahoo.com
***************************************************************************/
/***************************************************************************
* *
* 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; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
//////////////////////////////////////////////////////// code for choosing a public key from a list for encryption
#include <tqlayout.h>
#include <tqpushbutton.h>
#include <tqptrlist.h>
#include <tqwhatsthis.h>
#include <tqpainter.h>
#include <tqiconset.h>
#include <tqbuttongroup.h>
#include <tqcheckbox.h>
#include <tqhbuttongroup.h>
#include <tqtoolbutton.h>
#include <tqtextcodec.h>
#include <tdeversion.h>
#include <tdelistview.h>
#include <kprocess.h>
#include <kprocio.h>
#include <tdelocale.h>
#include <tdeaccel.h>
#if KDE_IS_VERSION( 3, 2, 90 )
#include <tdelistviewsearchline.h>
#endif
#include <kactivelabel.h>
#include <tdeaction.h>
#include <kdebug.h>
#include <kiconloader.h>
#include <klineedit.h>
#include "popuppublic.h"
#include "kgpgsettings.h"
#include "kgpgview.h"
#include "kgpg.h"
///////////////// tdelistviewitem special
class UpdateViewItem2 : public TDEListViewItem
{
public:
UpdateViewItem2(TQListView *parent, TQString name,TQString mail,TQString id,bool isDefault);
virtual void paintCell(TQPainter *p, const TQColorGroup &cg,int col, int width, int align);
virtual TQString key(int c,bool ) const;
bool def;
};
UpdateViewItem2::UpdateViewItem2(TQListView *parent, TQString name,TQString mail,TQString id,bool isDefault)
: TDEListViewItem(parent)
{
def=isDefault;
setText(0,name);
setText(1,mail);
setText(2,id);
}
void UpdateViewItem2::paintCell(TQPainter *p, const TQColorGroup &cg,int column, int width, int alignment)
{
if ((def) && (column<2)) {
TQFont font(p->font());
font.setBold(true);
p->setFont(font);
}
TDEListViewItem::paintCell(p, cg, column, width, alignment);
}
TQString UpdateViewItem2 :: key(int c,bool ) const
{
return text(c).lower();
}
/////////////// main view
popupPublic::popupPublic(TQWidget *parent, const char *name,TQString sfile,bool filemode,TDEShortcut goDefaultKey):
KDialogBase( Plain, i18n("Select Public Key"), Details | Ok | Cancel, Ok, parent, name,true)
{
TQWidget *page = plainPage();
TQVBoxLayout *vbox=new TQVBoxLayout(page,0,spacingHint());
vbox->setAutoAdd(true);
setButtonText(KDialogBase::Details,i18n("Options"));
if (KGpgSettings::allowCustomEncryptionOptions())
customOptions=KGpgSettings::customEncryptionOptions();
TDEIconLoader *loader = TDEGlobal::iconLoader();
keyPair=loader->loadIcon("kgpg_key2",TDEIcon::Small,20);
keySingle=loader->loadIcon("kgpg_key1",TDEIcon::Small,20);
keyGroup=loader->loadIcon("kgpg_key3",TDEIcon::Small,20);
if (filemode) setCaption(i18n("Select Public Key for %1").arg(sfile));
fmode=filemode;
TQHButtonGroup *hBar=new TQHButtonGroup(page);
//hBar->setFrameStyle(TQFrame::NoFrame);
hBar->setMargin(0);
#if KDE_IS_VERSION( 3, 2, 90 )
TQToolButton *clearSearch = new TQToolButton(hBar);
clearSearch->setTextLabel(i18n("Clear Search"), true);
clearSearch->setIconSet(SmallIconSet(TQApplication::reverseLayout() ? "clear_left"
: "locationbar_erase"));
(void) new TQLabel(i18n("Search: "),hBar);
TDEListViewSearchLine* listViewSearch = new TDEListViewSearchLine(hBar);
connect(clearSearch, TQT_SIGNAL(pressed()), listViewSearch, TQT_SLOT(clear()));
#endif
keysList = new TDEListView( page );
keysList->addColumn(i18n("Name"));
keysList->addColumn(i18n("Email"));
keysList->addColumn(i18n("ID"));
#if KDE_IS_VERSION( 3, 2, 90 )
listViewSearch->setListView(keysList);
#endif
keysList->setRootIsDecorated(false);
page->setMinimumSize(540,200);
keysList->setShowSortIndicator(true);
keysList->setFullWidth(true);
keysList->setAllColumnsShowFocus(true);
keysList->setSelectionModeExt(TDEListView::Extended);
keysList->setColumnWidthMode(0,TQListView::Manual);
keysList->setColumnWidthMode(1,TQListView::Manual);
keysList->setColumnWidth(0,210);
keysList->setColumnWidth(1,210);
boutonboxoptions=new TQButtonGroup(5,Qt::Vertical ,page,0);
TDEActionCollection *actcol=new TDEActionCollection(this);
(void) new TDEAction(i18n("&Go to Default Key"),goDefaultKey, TQT_TQOBJECT(this), TQT_SLOT(slotGotoDefaultKey()),actcol,"go_default_key");
CBarmor=new TQCheckBox(i18n("ASCII armored encryption"),boutonboxoptions);
CBuntrusted=new TQCheckBox(i18n("Allow encryption with untrusted keys"),boutonboxoptions);
CBhideid=new TQCheckBox(i18n("Hide user id"),boutonboxoptions);
setDetailsWidget(boutonboxoptions);
TQWhatsThis::add
(keysList,i18n("<b>Public keys list</b>: select the key that will be used for encryption."));
TQWhatsThis::add
(CBarmor,i18n("<b>ASCII encryption</b>: makes it possible to open the encrypted file/message in a text editor"));
TQWhatsThis::add
(CBhideid,i18n("<b>Hide user ID</b>: Do not put the keyid into encrypted packets. This option hides the receiver "
"of the message and is a countermeasure against traffic analysis. It may slow down the decryption process because "
"all available secret keys are tried."));
TQWhatsThis::add
(CBuntrusted,i18n("<b>Allow encryption with untrusted keys</b>: when you import a public key, it is usually "
"marked as untrusted and you cannot use it unless you sign it in order to make it 'trusted'. Checking this "
"box enables you to use any key, even if it has not be signed."));
if (filemode) {
TQWidget *parentBox=new TQWidget(boutonboxoptions);
TQHBoxLayout *shredBox=new TQHBoxLayout(parentBox,0);
//shredBox->setFrameStyle(TQFrame::NoFrame);
//shredBox->setMargin(0);
CBshred=new TQCheckBox(i18n("Shred source file"),parentBox);
TQWhatsThis::add
(CBshred,i18n("<b>Shred source file</b>: permanently remove source file. No recovery will be possible"));
TQString shredWhatsThis = i18n( "<qt><b>Shred source file:</b><br /><p>Checking this option will shred (overwrite several times before erasing) the files you have encrypted. This way, it is almost impossible that the source file is recovered.</p><p><b>But you must be aware that this is not secure</b> on all file systems, and that parts of the file may have been saved in a temporary file or in the spooler of your printer if you previously opened it in an editor or tried to print it. Only works on files (not on folders).</p></qt>");
KActiveLabel *warn= new KActiveLabel( i18n("<a href=\"whatsthis:%1\">Read this before using shredding</a>").arg(shredWhatsThis),parentBox );
shredBox->addWidget(CBshred);
shredBox->addWidget(warn);
}
CBsymmetric=new TQCheckBox(i18n("Symmetrical encryption"),boutonboxoptions);
TQWhatsThis::add
(CBsymmetric,i18n("<b>Symmetrical encryption</b>: encryption does not use keys. You just need to give a password "
"to encrypt/decrypt the file"));
TQObject::connect(CBsymmetric,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(isSymetric(bool)));
CBarmor->setChecked( KGpgSettings::asciiArmor() );
CBuntrusted->setChecked( KGpgSettings::allowUntrustedKeys() );
CBhideid->setChecked( KGpgSettings::hideUserID() );
if (filemode) CBshred->setChecked( KGpgSettings::shredSource() );
if (KGpgSettings::allowCustomEncryptionOptions()) {
TQHButtonGroup *bGroup = new TQHButtonGroup(page);
//bGroup->setFrameStyle(TQFrame::NoFrame);
(void) new TQLabel(i18n("Custom option:"),bGroup);
KLineEdit *optiontxt=new KLineEdit(bGroup);
optiontxt->setText(customOptions);
TQWhatsThis::add
(optiontxt,i18n("<b>Custom option</b>: for experienced users only, allows you to enter a gpg command line option, like: '--armor'"));
TQObject::connect(optiontxt,TQT_SIGNAL(textChanged ( const TQString & )),this,TQT_SLOT(customOpts(const TQString & )));
}
TQObject::connect(keysList,TQT_SIGNAL(doubleClicked(TQListViewItem *,const TQPoint &,int)),this,TQT_SLOT(slotOk()));
// TQObject::connect(this,TQT_SIGNAL(okClicked()),this,TQT_SLOT(crypte()));
TQObject::connect(CBuntrusted,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(refresh(bool)));
char line[200]="\0";
FILE *fp2;
seclist=TQString();
fp2 = popen("gpg --no-secmem-warning --no-tty --with-colon --list-secret-keys ", "r");
while ( fgets( line, sizeof(line), fp2))
{
TQString readLine=TQString::fromUtf8(line);
if (readLine.startsWith("sec")) seclist+=", 0x"+readLine.section(":",4,4).right(8);
}
pclose(fp2);
trusted=CBuntrusted->isChecked();
refreshkeys();
setMinimumSize(550,200);
updateGeometry();
keysList->setFocus();
show();
}
popupPublic::~popupPublic()
{}
void popupPublic::slotAccept()
{
accept();
}
void popupPublic::enable()
{
TQListViewItem *current = keysList->firstChild();
if (current==NULL)
return;
current->setVisible(true);
while ( current->nextSibling() ) {
current = current->nextSibling();
current->setVisible(true);
}
keysList->ensureItemVisible(keysList->currentItem());
}
void popupPublic::sort()
{
bool reselect=false;
TQListViewItem *current = keysList->firstChild();
if (current==NULL)
return;
if ((untrustedList.find(current->text(2))!=untrustedList.end()) && (!current->text(2).isEmpty())){
if (current->isSelected()) {
current->setSelected(false);
reselect=true;
}
current->setVisible(false);
}
while ( current->nextSibling() ) {
current = current->nextSibling();
if ((untrustedList.find(current->text(2))!=untrustedList.end()) && (!current->text(2).isEmpty())) {
if (current->isSelected()) {
current->setSelected(false);
reselect=true;
}
current->setVisible(false);
}
}
if (reselect || !keysList->currentItem()->isVisible()) {
TQListViewItem *firstvisible;
firstvisible=keysList->firstChild();
while (firstvisible->isVisible()!=true) {
firstvisible=firstvisible->nextSibling();
if (firstvisible==NULL)
return;
}
keysList->setSelected(firstvisible,true);
keysList->setCurrentItem(firstvisible);
keysList->ensureItemVisible(firstvisible);
}
}
void popupPublic::isSymetric(bool state)
{
keysList->setEnabled(!state);
CBuntrusted->setEnabled(!state);
CBhideid->setEnabled(!state);
}
void popupPublic::customOpts(const TQString &str)
{
customOptions=str;
}
void popupPublic::slotGotoDefaultKey()
{
TQListViewItem *myDefaulKey = keysList->findItem(KGpgSettings::defaultKey(),2);
keysList->clearSelection();
keysList->setCurrentItem(myDefaulKey);
keysList->setSelected(myDefaulKey,true);
keysList->ensureItemVisible(myDefaulKey);
}
void popupPublic::refresh(bool state)
{
if (state)
enable();
else
sort();
}
void popupPublic::refreshkeys()
{
keysList->clear();
currentKey = TQString();
hashMap.clear();
TQStringList groups= TQStringList::split(",", KGpgSettings::groups());
if (!groups.isEmpty())
{
for ( TQStringList::Iterator it = groups.begin(); it != groups.end(); ++it )
{
if (!TQString(*it).isEmpty())
{
UpdateViewItem2 *item=new UpdateViewItem2(keysList,TQString(*it),TQString(),TQString(),false);
item->setPixmap(0,keyGroup);
}
}
}
KProcIO *encid=new KProcIO(TQTextCodec::codecForLocale());
*encid << "gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--with-colon"<<"--list-keys";
///////// when process ends, update dialog infos
TQObject::connect(encid, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotpreselect()));
TQObject::connect(encid, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotprocread(KProcIO *)));
encid->start(TDEProcess::NotifyOnExit,true);
}
void popupPublic::slotpreselect()
{
TQListViewItem *it=NULL;
if (!keysList->firstChild()) return;
if (fmode) it=keysList->findItem(KGpgSettings::defaultKey(),2);
if (!trusted)
sort();
if (fmode)
{
keysList->clearSelection();
keysList->setSelected(it,true);
keysList->setCurrentItem(it);
keysList->ensureItemVisible(it);
}
emit keyListFilled();
}
void popupPublic::slotSetVisible()
{
keysList->ensureItemVisible(keysList->currentItem());
}
void popupPublic::slotprocread(KProcIO *p)
{
// kdDebug(2100) << k_funcinfo << endl;
///////////////////////////////////////////////////////////////// extract encryption keys
TQString tst;
TQString defaultKey = KGpgSettings::defaultKey().right(8);
while (p->readln(tst)!=-1) {
// kdDebug(2100) << k_funcinfo << "Read one public key line: " << tst << endl;
if ( tst.startsWith("pub") ) {
currentKey = tst.section(':',4,4);
TQStringList lst; lst << tst;
hashMap.insert(currentKey,tst);
}
else {
hashMap.find(currentKey).data().append(tst);
}
}
TQMap<TQString,TQStringList>::Iterator ite;
for (ite = hashMap.begin(); ite != hashMap.end(); ite++) {
TQStringList::Iterator it;
TQString fullname,keyname,keymail,val,id;
bool dead;
for (it = ite.data().begin(); it != ite.data().end(); it++) {
TQString line = (*it);
if (line.startsWith("pub")) {
TQStringList keyString=TQStringList::split(":",line,true);
dead=false;
const TQString trust=keyString[1];
val=keyString[6];
id=TQString("0x"+keyString[4].right(8));
if (val.isEmpty()) {
val=i18n("Unlimited");
}
TQString tr;
switch( trust[0] ) {
case 'o':
untrustedList<<id;
break;
case 'i':
dead=true;
break;
case 'd':
dead=true;
break;
case 'r':
dead=true;
break;
case 'e':
dead=true;
break;
case 'q':
untrustedList<<id;
break;
case 'n':
untrustedList<<id;
break;
case 'm':
untrustedList<<id;
break;
case 'f':
break;
case 'u':
break;
default:
untrustedList<<id;
break;
}
if (keyString[11].find('D')!=-1) {
dead=true;
}
fullname=keyString[9];
}
if ( line.startsWith("uid") && fullname.isEmpty() ) {
fullname = line.section(':',9,9);
}
}
if (fullname.find("<")!=-1) {
keymail=fullname.section('<',-1,-1);
keymail.truncate(keymail.length()-1);
keyname=fullname.section('<',0,0);
//if (keyname.find("(")!=-1) {
// keyname=keyname.section('(',0,0);
//}
}
else {
keymail=TQString();
keyname=fullname;//.section('(',0,0);
}
if ((!dead) && (!fullname.isEmpty())) {
bool isDefaultKey=false;
if (id.right(8)==defaultKey) {
isDefaultKey=true;
}
UpdateViewItem2 *item=new UpdateViewItem2(keysList,keyname,keymail,id,isDefaultKey);
//TDEListViewItem *sub= new TDEListViewItem(item,i18n("ID: %1, trust: %2, validity: %3").arg(id).arg(tr).arg(val));
//sub->setSelectable(false);
if (seclist.find(fullname,0,FALSE)!=-1) {
item->setPixmap(0,keyPair);
}
else {
item->setPixmap(0,keySingle);
}
}
}
}
void popupPublic::slotOk()
{
////// emit selected data
kdDebug(2100)<<"Ok pressed"<<endl;
TQStringList selectedKeys;
TQString userid;
TQPtrList<TQListViewItem> list=keysList->selectedItems();
for ( uint i = 0; i < list.count(); ++i )
if ( list.at(i) && list.at(i)->isVisible()) {
if (!list.at(i)->text(2).isEmpty()) selectedKeys<<list.at(i)->text(2);
else selectedKeys<<list.at(i)->text(0);
}
if (selectedKeys.isEmpty() && !CBsymmetric->isChecked())
return;
if (CBsymmetric->isChecked()) selectedKeys=NULL;
// kdDebug(2100)<<"Selected Key:"<<selectedKeys<<endl;
TQStringList returnOptions;
if (CBuntrusted->isChecked())
returnOptions<<"--always-trust";
if (CBarmor->isChecked())
returnOptions<<"--armor";
if (CBhideid->isChecked())
returnOptions<<"--throw-keyid";
if ((KGpgSettings::allowCustomEncryptionOptions()) && (!customOptions.stripWhiteSpace().isEmpty()))
returnOptions.operator+ (TQStringList::split(TQString(" "),customOptions.simplifyWhiteSpace()));
//hide();
if (fmode)
emit selectedKey(selectedKeys,returnOptions,CBshred->isChecked(),CBsymmetric->isChecked());
else
emit selectedKey(selectedKeys,returnOptions,false,CBsymmetric->isChecked());
accept();
}
#include "popuppublic.moc"