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/kgpg.cpp

1119 lines
42 KiB

/***************************************************************************
kgpg.cpp - description
-------------------
begin : Mon Nov 18 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. *
* *
***************************************************************************/
#include <stdlib.h>
#include <tqlabel.h>
#include <tqclipboard.h>
#include <tqfile.h>
#include <tqpopupmenu.h>
#include <tqwidget.h>
#include <tqcheckbox.h>
#include <tqmovie.h>
#include <tqcstring.h>
#include <tqhbuttongroup.h>
#include <tdeglobal.h>
#include <kactivelabel.h>
#include <tdeversion.h>
#include <tdelocale.h>
#include <tdeconfig.h>
#include <tdeapplication.h>
#include <tdemessagebox.h>
#include <kcombobox.h>
#include <tqregexp.h>
#include <tdecmdlineargs.h>
#include <tqtooltip.h>
#include <kdebug.h>
#include <kurlrequesterdlg.h>
#include <klineedit.h>
#include <tdeio/renamedlg.h>
#include <kpassivepopup.h>
#include <tqlayout.h>
#include <tqbuttongroup.h>
#include <kiconloader.h>
#include <tdetempfile.h>
#include <twin.h>
#include <kprocess.h>
#include <kprocio.h>
#include <tdeaboutapplication.h>
#include <kurlrequester.h>
#include <ktip.h>
#include <kurldrag.h>
#include <ktar.h>
#include <kzip.h>
#include <dcopclient.h>
#include <kstandarddirs.h>
#include <tdefiledialog.h>
#include <tdepopupmenu.h>
#include <tqcursor.h>
#include <kdesktopfile.h>
#include "kgpgeditor.h"
#include "kgpg.h"
#include "kgpgsettings.h"
#include "listkeys.h"
#include "keyserver.h"
#include "keyservers.h"
#include "popuppublic.h"
#include "kgpgview.h"
#include "kgpglibrary.h"
#include "kgpgwizard.h"
MyView::MyView( TQWidget *parent, const char *name )
: TQLabel( parent, name )
{
setBackgroundMode( X11ParentRelative );
openTasks=0;
TDEAction *saveDecrypt=new TDEAction(i18n("&Decrypt && Save File"),"decrypted",0,this, TQ_SLOT(decryptDroppedFile()),this,"decrypt_file");
TDEAction *showDecrypt=new TDEAction(i18n("&Show Decrypted File"),"edit",0,this, TQ_SLOT(showDroppedFile()),this,"show_file");
TDEAction *encrypt=new TDEAction(i18n("&Encrypt File"),"encrypted",0,this, TQ_SLOT(encryptDroppedFile()),this,"encrypt_file");
TDEAction *sign=new TDEAction(i18n("&Sign File"), "signature",0,this, TQ_SLOT(signDroppedFile()),this,"sign_file");
//TQToolTip::add(this,i18n("KGpg drag & drop encryption applet"));
readOptions();
resize(24,24);
setPixmap( KSystemTray::loadIcon("kgpg_docked"));
setAcceptDrops(true);
droppopup=new TQPopupMenu();
showDecrypt->plug(droppopup);
saveDecrypt->plug(droppopup);
udroppopup=new TQPopupMenu();
encrypt->plug(udroppopup);
sign->plug(udroppopup);
TQToolTip::add(this, i18n("KGpg - encryption tool"));
}
MyView::~MyView()
{
delete droppopup;
droppopup = 0;
delete udroppopup;
udroppopup = 0;
}
void MyView::clipEncrypt()
{
popupPublic *dialoguec=new popupPublic(0, "public_keys", 0,false,goDefaultKey);
connect(dialoguec,TQ_SIGNAL(selectedKey(TQStringList,TQStringList,bool,bool)),this,TQ_SLOT(encryptClipboard(TQStringList,TQStringList,bool,bool)));
dialoguec->exec();
delete dialoguec;
}
void MyView::clipDecrypt()
{
TQString clippie=kapp->clipboard()->text(clipboardMode).stripWhiteSpace();
droppedtext(clippie,false);
}
void MyView::clipSign(bool openEditor)
{
TQString clippie=kapp->clipboard()->text(clipboardMode).stripWhiteSpace();
if (!clippie.isEmpty()) {
KgpgApp *kgpgtxtedit = new KgpgApp(0, "editor",WDestructiveClose,goDefaultKey);
connect(this,TQ_SIGNAL(setFont(TQFont)),kgpgtxtedit,TQ_SLOT(slotSetFont(TQFont)));
connect(kgpgtxtedit,TQ_SIGNAL(encryptFiles(KURL::List)),this,TQ_SLOT(encryptFiles(KURL::List)));
if (!openEditor)
connect(kgpgtxtedit->view,TQ_SIGNAL(verifyFinished()),kgpgtxtedit,TQ_SLOT(closeWindow()));
kgpgtxtedit->view->editor->setText(clippie);
kgpgtxtedit->view->clearSign();
kgpgtxtedit->show();
} else
KMessageBox::sorry(this,i18n("Clipboard is empty."));
}
void MyView::encryptDroppedFolder()
{
compressionScheme=0;
kgpgfoldertmp=new KTempFile(TQString());
kgpgfoldertmp->setAutoDelete(true);
if (KMessageBox::warningContinueCancel(0,i18n("<qt>KGpg will now create a temporary archive file:<br><b>%1</b> to process the encryption. The file will be deleted after the encryption is finished.</qt>").arg(kgpgfoldertmp->name()),i18n("Temporary File Creation"),KStdGuiItem::cont(),"FolderTmpFile")==KMessageBox::Cancel)
return;
dialogue=new popupPublic(0,"Public keys",droppedUrls.first().fileName(),true,goDefaultKey);
TQHButtonGroup *bGroup = new TQHButtonGroup(dialogue->plainPage());
(void) new TQLabel(i18n("Compression method for archive:"),bGroup);
KComboBox *optionbx=new KComboBox(bGroup);
optionbx->insertItem(i18n("Zip"));
optionbx->insertItem(i18n("Gzip"));
optionbx->insertItem(i18n("Bzip2"));
bGroup->show();
connect(dialogue,TQ_SIGNAL(keyListFilled ()),dialogue,TQ_SLOT(slotSetVisible()));
connect(optionbx,TQ_SIGNAL(activated (int)),this,TQ_SLOT(slotSetCompression(int)));
connect(dialogue,TQ_SIGNAL(selectedKey(TQStringList,TQStringList,bool,bool)),this,TQ_SLOT(startFolderEncode(TQStringList,TQStringList,bool,bool)));
dialogue->CBshred->setEnabled(false);
dialogue->exec();
dialogue=0L;
}
void MyView::slotSetCompression(int cp)
{
compressionScheme=cp;
}
void MyView::startFolderEncode(TQStringList selec,TQStringList encryptOptions,bool ,bool symetric)
{
TQString extension="";
if (compressionScheme==0)
extension=".zip";
else if (compressionScheme==1)
extension=".tar.gz";
else
extension=".tar.bz2";
if (encryptOptions.find("armor")!=encryptOptions.end () )
extension+=".asc";
else if (KGpgSettings::pgpExtension())
extension+=".pgp";
else
extension+=".gpg";
KURL encryptedFile(droppedUrls.first().path()+extension);
TQFile encryptedFolder(droppedUrls.first().path()+extension);
if (encryptedFolder.exists()) {
dialogue->hide();
TDEIO::RenameDlg *over=new TDEIO::RenameDlg(0,i18n("File Already Exists"),TQString(),encryptedFile.path(),TDEIO::M_OVERWRITE);
if (over->exec()==TQDialog::Rejected)
{
delete over;
return;
}
encryptedFile=over->newDestURL();
delete over;
dialogue->show(); /////// strange, but if dialogue is hidden, the passive popup is not displayed...
}
pop = new KPassivePopup();
pop->setView(i18n("Processing folder compression and encryption"),i18n("Please wait..."),TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop));
pop->setAutoDelete(false);
pop->show();
kapp->processEvents();
dialogue->slotAccept();
dialogue=0L;
KArchive *arch;
if (compressionScheme==0)
arch=new KZip(kgpgfoldertmp->name());
else if (compressionScheme==1)
arch=new KTar(kgpgfoldertmp->name(), "application/x-gzip");
else
arch=new KTar(kgpgfoldertmp->name(), "application/x-bzip2");
if (!arch->open( IO_WriteOnly )) {
KMessageBox::sorry(0,i18n("Unable to create temporary file"));
delete arch;
return;
}
arch->addLocalDirectory (droppedUrls.first().path(),droppedUrls.first().fileName());
arch->close();
delete arch;
KgpgInterface *folderprocess=new KgpgInterface();
folderprocess->KgpgEncryptFile(selec,KURL(kgpgfoldertmp->name()),encryptedFile,encryptOptions,symetric);
connect(folderprocess,TQ_SIGNAL(encryptionfinished(KURL)),this,TQ_SLOT(slotFolderFinished(KURL)));
connect(folderprocess,TQ_SIGNAL(errormessage(TQString)),this,TQ_SLOT(slotFolderFinishedError(TQString)));
}
void MyView::slotFolderFinished(KURL)
{
delete pop;
delete kgpgfoldertmp;
}
void MyView::slotFolderFinishedError(TQString errmsge)
{
delete pop;
delete kgpgfoldertmp;
KMessageBox::sorry(0,errmsge);
}
void MyView::busyMessage(TQString mssge,bool reset)
{
if (reset) openTasks=0;
if (!mssge.isEmpty())
{
openTasks++;
TQToolTip::remove(this);
TQToolTip::add(this, mssge);
setMovie(TQMovie(locate("appdata","pics/kgpg_docked.gif")));
}
else openTasks--;
//kdDebug(2100) << "Emit message: "<<openTasks<<endl;
if (openTasks<=0)
{
setPixmap( KSystemTray::loadIcon("kgpg_docked"));
TQToolTip::remove(this);
TQToolTip::add(this, i18n("KGpg - encryption tool"));
openTasks=0;
}
}
void MyView::encryptDroppedFile()
{
TQStringList opts;
KgpgLibrary *lib=new KgpgLibrary(this,KGpgSettings::pgpExtension());
connect(lib,TQ_SIGNAL(systemMessage(TQString,bool)),this,TQ_SLOT(busyMessage(TQString,bool)));
if (KGpgSettings::fileKey()!=TQString()) {
if (KGpgSettings::allowUntrustedKeys())
opts<<"--always-trust";
if (KGpgSettings::asciiArmor())
opts<<"--armor";
if (KGpgSettings::hideUserID())
opts<<"--throw-keyid";
if (KGpgSettings::pgpCompatibility())
opts<<"--pgp6";
lib->slotFileEnc(droppedUrls,opts,TQStringList::split(" ",KGpgSettings::fileKey()),goDefaultKey);
} else
lib->slotFileEnc(droppedUrls,TQString(),TQString(),goDefaultKey);
}
void MyView::encryptFiles(KURL::List urls)
{
droppedUrls=urls;
encryptDroppedFile();
}
void MyView::shredDroppedFile()
{
KDialogBase *shredConfirm=new KDialogBase( this, "confirm_shred", true,i18n("Shred Files"),KDialogBase::Ok | KDialogBase::Cancel);
TQWidget *page = new TQWidget(shredConfirm);
shredConfirm->setMainWidget(page);
TQBoxLayout *layout=new TQBoxLayout(page,TQBoxLayout::TopToBottom,0);
layout->setAutoAdd(true);
(void) new KActiveLabel( i18n("Do you really want to <a href=\"whatsthis:%1\">shred</a> these files?").arg(i18n( "<qt><p>You must be aware that <b>shredding 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>")),page);
TDEListBox *lb=new TDEListBox(page);
lb->insertStringList(droppedUrls.toStringList());
if (shredConfirm->exec()==TQDialog::Accepted)
{
KgpgLibrary *lib=new KgpgLibrary(this);
connect(lib,TQ_SIGNAL(systemMessage(TQString,bool)),this,TQ_SLOT(busyMessage(TQString,bool)));
lib->shredprocessenc(droppedUrls);
}
delete shredConfirm;
}
void MyView::slotVerifyFile()
{
/////////////////////////////////// check file signature
if (droppedUrl.isEmpty())
return;
TQString sigfile=TQString();
////////////////////////////////////// try to find detached signature.
if (!droppedUrl.fileName().endsWith(".sig")) {
sigfile=droppedUrl.path()+".sig";
TQFile fsig(sigfile);
if (!fsig.exists()) {
sigfile=droppedUrl.path()+".asc";
TQFile fsig(sigfile);
////////////// if no .asc or .sig signature file included, assume the file is internally signed
if (!fsig.exists())
sigfile=TQString();
}
} else {
sigfile=droppedUrl.path();
droppedUrl=KURL(sigfile.left(sigfile.length()-4));
}
///////////////////////// pipe gpg command
KgpgInterface *verifyFileProcess=new KgpgInterface();
verifyFileProcess->KgpgVerifyFile(droppedUrl,KURL(sigfile));
connect (verifyFileProcess,TQ_SIGNAL(verifyquerykey(TQString)),this,TQ_SLOT(importSignature(TQString)));
}
void MyView::importSignature(TQString ID)
{
keyServer *kser=new keyServer(0,"server_dialog",false);
kser->page->kLEimportid->setText(ID);
kser->slotImport();
}
void MyView::signDroppedFile()
{
////////////////////////////////////// create a detached signature for a chosen file
if (droppedUrl.isEmpty())
return;
TQString signKeyID;
////////////////// select a private key to sign file --> listkeys.cpp
KgpgSelKey *opts=new KgpgSelKey(0,"select_secret");
if (opts->exec()==TQDialog::Accepted)
signKeyID=opts->getkeyID();
else {
delete opts;
return;
}
delete opts;
TQStringList Options;
if (KGpgSettings::asciiArmor())
Options<<"--armor";
if (KGpgSettings::pgpCompatibility())
Options<<"--pgp6";
KgpgInterface *signFileProcess=new KgpgInterface();
signFileProcess->KgpgSignFile(signKeyID,droppedUrl,Options);
}
void MyView::decryptDroppedFile()
{
//bool isFolder=false; // droppedUrls
KURL swapname;
if (!droppedUrls.first().isLocalFile()) {
showDroppedFile();
decryptNextFile();
}
TQString oldname=droppedUrls.first().fileName();
if (oldname.endsWith(".gpg") || oldname.endsWith(".asc") || oldname.endsWith(".pgp"))
oldname.truncate(oldname.length()-4);
else
oldname.append(".clear");
/*
if (oldname.endsWith(".tar.gz")) {
isFolder=true;
kgpgFolderExtract=new KTempFile(TQString(),".tar.gz");
kgpgFolderExtract->setAutoDelete(true);
swapname=KURL(kgpgFolderExtract->name());
if (KMessageBox::warningContinueCancel(0,i18n("<qt>The file to decrypt is an archive. KGpg will create a temporary unencrypted archive file:<br><b>%1</b> before processing the archive extraction. This temporary file will be deleted after the decryption is finished.</qt>").arg(kgpgFolderExtract->name()),i18n("Temporary File Creation"),KStdGuiItem::cont(),"FolderTmpDecFile")==KMessageBox::Cancel)
return;
} else*/ {
swapname=KURL(droppedUrls.first().directory(0,0)+oldname);
TQFile fgpg(swapname.path());
if (fgpg.exists()) {
TDEIO::RenameDlg *over=new TDEIO::RenameDlg(0,i18n("File Already Exists"),TQString(),swapname.path(),TDEIO::M_OVERWRITE);
if (over->exec()==TQDialog::Rejected)
{
delete over;
decryptNextFile();
return;
}
swapname=over->newDestURL();
delete over;
}
}
KgpgLibrary *lib=new KgpgLibrary(this);
lib->slotFileDec(droppedUrls.first(),swapname,KGpgSettings::customDecrypt());
connect(lib,TQ_SIGNAL(importOver(TQStringList)),this,TQ_SIGNAL(importedKeys(TQStringList)));
connect(lib,TQ_SIGNAL(systemMessage(TQString,bool)),this,TQ_SLOT(busyMessage(TQString,bool)));
// if (isFolder)
connect(lib,TQ_SIGNAL(decryptionOver()),this,TQ_SLOT(decryptNextFile()));
}
void MyView::decryptNextFile()
{
if (droppedUrls.count()>1)
{
droppedUrls.pop_front();
decryptDroppedFile();
}
}
void MyView::unArchive()
{
KTar compressedFolder(kgpgFolderExtract->name(),"application/x-gzip");
if (!compressedFolder.open( IO_ReadOnly )) {
KMessageBox::sorry(0,i18n("Unable to read temporary archive file"));
return;
}
const KArchiveDirectory *archiveDirectory=compressedFolder.directory();
//KURL savePath=KURL::getURL(droppedUrl,this,i18n(""));
KURLRequesterDlg *savePath=new KURLRequesterDlg(droppedUrl.directory(false),i18n("Extract to: "),0,"extract");
savePath->fileDialog()->setMode(KFile::Directory);
if (!savePath->exec()==TQDialog::Accepted) {
delete kgpgFolderExtract;
return;
}
archiveDirectory->KArchiveDirectory::copyTo(savePath->selectedURL().path());
compressedFolder.close();
delete savePath;
delete kgpgFolderExtract;
}
void MyView::showDroppedFile()
{
kdDebug(2100)<<"------Show dropped file"<<endl;
KgpgApp *kgpgtxtedit = new KgpgApp(0, "editor",WDestructiveClose,goDefaultKey);
kgpgtxtedit->view->editor->slotDroppedFile(droppedUrls.first());
connect(kgpgtxtedit,TQ_SIGNAL(encryptFiles(KURL::List)),this,TQ_SLOT(encryptFiles(KURL::List)));
connect(this,TQ_SIGNAL(setFont(TQFont)),kgpgtxtedit,TQ_SLOT(slotSetFont(TQFont)));
connect(kgpgtxtedit,TQ_SIGNAL(refreshImported(TQStringList)),this,TQ_SIGNAL(importedKeys(TQStringList)));
connect(kgpgtxtedit->view->editor,TQ_SIGNAL(refreshImported(TQStringList)),this,TQ_SIGNAL(importedKeys(TQStringList)));
kgpgtxtedit->show();
}
void MyView::droppedfile (KURL::List url)
{
droppedUrls=url;
droppedUrl=url.first();
if (KMimeType::findByURL(droppedUrl)->name()=="inode/directory") {
encryptDroppedFolder();
//KMessageBox::sorry(0,i18n("Sorry, only file operations are currently supported."));
return;
}
if (!droppedUrl.isLocalFile()) {
showDroppedFile();
return;
}
if ((droppedUrl.path().endsWith(".asc")) || (droppedUrl.path().endsWith(".pgp")) || (droppedUrl.path().endsWith(".gpg"))) {
switch (KGpgSettings::encryptedDropEvent()) {
case KGpgSettings::EnumEncryptedDropEvent::DecryptAndSave:
decryptDroppedFile();
break;
case KGpgSettings::EnumEncryptedDropEvent::DecryptAndOpen:
showDroppedFile();
break;
case KGpgSettings::EnumEncryptedDropEvent::Ask:
droppopup->exec(TQCursor::pos ());
kdDebug(2100)<<"Drop menu--------"<<endl;
break;
}
} else if (droppedUrl.path().endsWith(".sig")) {
slotVerifyFile();
} else
switch (KGpgSettings::unencryptedDropEvent()) {
case KGpgSettings::EnumUnencryptedDropEvent::Encrypt:
encryptDroppedFile();
break;
case KGpgSettings::EnumUnencryptedDropEvent::Sign:
signDroppedFile();
break;
case KGpgSettings::EnumUnencryptedDropEvent::Ask:
udroppopup->exec(TQCursor::pos ());
break;
}
}
void MyView::droppedtext (TQString inputText,bool allowEncrypt)
{
if (inputText.startsWith("-----BEGIN PGP MESSAGE")) {
KgpgApp *kgpgtxtedit = new KgpgApp(0, "editor",WDestructiveClose,goDefaultKey);
connect(kgpgtxtedit,TQ_SIGNAL(encryptFiles(KURL::List)),this,TQ_SLOT(encryptFiles(KURL::List)));
connect(this,TQ_SIGNAL(setFont(TQFont)),kgpgtxtedit,TQ_SLOT(slotSetFont(TQFont)));
kgpgtxtedit->view->editor->setText(inputText);
kgpgtxtedit->view->slotdecode();
kgpgtxtedit->show();
return;
}
if (inputText.startsWith("-----BEGIN PGP PUBLIC KEY")) {
int result=KMessageBox::warningContinueCancel(0,i18n("<p>The dropped text is a public key.<br>Do you want to import it ?</p>"),i18n("Warning"));
if (result==KMessageBox::Cancel)
return;
else {
KgpgInterface *importKeyProcess=new KgpgInterface();
importKeyProcess->importKey(inputText);
connect(importKeyProcess,TQ_SIGNAL(importfinished(TQStringList)),this,TQ_SIGNAL(importedKeys(TQStringList)));
return;
}
}
if (inputText.startsWith("-----BEGIN PGP SIGNED MESSAGE")) {
clipSign(false);
return;
}
if (allowEncrypt) clipEncrypt();
else KMessageBox::sorry(this,i18n("No encrypted text found."));
}
void MyView::dragEnterEvent(TQDragEnterEvent *e)
{
e->accept (KURLDrag::canDecode(e) || TQTextDrag::canDecode (e));
}
void MyView::dropEvent (TQDropEvent *o)
{
KURL::List list;
TQString text;
if ( KURLDrag::decode( o, list ) )
droppedfile(list);
else if ( TQTextDrag::decode(o, text) )
{
TQApplication::clipboard()->setText(text,clipboardMode);
droppedtext(text);
}
}
void MyView::readOptions()
{
clipboardMode=TQClipboard::Clipboard;
if ( KGpgSettings::useMouseSelection() && kapp->clipboard()->supportsSelection())
clipboardMode=TQClipboard::Selection;
if (KGpgSettings::firstRun()) {
firstRun();
} else {
TQString path = KGpgSettings::gpgConfigPath();
if (path.isEmpty()) {
if (KMessageBox::questionYesNo(0,i18n("<qt>You have not set a path to your GnuPG config file.<br>This may cause some surprising results in KGpg's execution.<br>Would you like to start KGpg's Wizard to fix this problem?</qt>"),TQString(),i18n("Start Wizard"),i18n("Do Not Start"))==KMessageBox::Yes)
startWizard();
} else {
TQStringList groups=KgpgInterface::getGpgGroupNames(path);
if (!groups.isEmpty())
KGpgSettings::setGroups(groups.join(","));
}
}
}
void MyView::firstRun()
{
KProcIO *p=new KProcIO();
*p<<"gpg"<<"--no-tty"<<"--list-secret-keys";
p->start(TDEProcess::Block); //// start gnupg so that it will create a config file
startWizard();
}
static TQString getGpgHome()
{
char *env=getenv("GNUPGHOME");
TQString gpgHome(env ? env : TQDir::homeDirPath()+"/.gnupg/");
gpgHome.replace("//", "/");
if(!gpgHome.endsWith("/"))
gpgHome.append('/');
TDEStandardDirs::makeDir(gpgHome, 0700);
return gpgHome;
}
void MyView::startWizard()
{
kdDebug(2100)<<"Starting Wizard"<<endl;
wiz=new KgpgWizard(0,"wizard");
TQString gpgHome(getGpgHome());
TQString confPath=gpgHome+"options";
if (!TQFile(confPath).exists()) {
confPath=gpgHome+"gpg.conf";
if (!TQFile(confPath).exists()) {
if (KMessageBox::questionYesNo(this,i18n("<qt><b>The GnuPG configuration file was not found</b>. Please make sure you have GnuPG installed. Should KGpg try to create a config file ?</qt>"),TQString(),i18n("Create Config"),i18n("Do Not Create"))==KMessageBox::Yes) {
confPath=gpgHome+"options";
TQFile file(confPath);
if ( file.open( IO_WriteOnly ) ) {
TQTextStream stream( &file );
stream <<"# GnuPG config file created by KGpg"<< "\n";
file.close();
}
} else {
wiz->text_optionsfound->setText(i18n("<qt><b>The GnuPG configuration file was not found</b>. Please make sure you have GnuPG installed and give the path to the config file.</qt>"));
confPath=TQString();
}
}
}
int gpgVersion=KgpgInterface::getGpgVersion();
if (gpgVersion<120) wiz->txtGpgVersion->setText(i18n("Your GnuPG version seems to be older than 1.2.0. Photo Id's and Key Groups will not work properly. Please consider upgrading GnuPG (http://gnupg.org)."));
else wiz->txtGpgVersion->setText(TQString());
wiz->kURLRequester1->setURL(confPath);
/*
wiz->kURLRequester2->setURL(TDEGlobalSettings::desktopPath());
wiz->kURLRequester2->setMode(2);*/
FILE *fp,*fp2;
TQString trustedvals="idre-";
TQString firstKey=TQString();
char line[300];
bool counter=false;
TQString currentKey;
TQMap<TQString,TQStringList> hashMap;
fp = popen("gpg --display-charset=utf-8 --no-tty --with-colon --list-secret-keys", "r");
while ( fgets( line, sizeof(line), fp)) {
TQString tst=TQString::fromUtf8(line);
kdDebug(2100) << k_funcinfo << "Read one secret key line: " << tst << endl;
if ( tst.startsWith("sec") ) {
currentKey = tst.section(':',4,4);
TQStringList lst; lst << tst;
hashMap.insert(currentKey,lst);
}
else {
hashMap.find(currentKey).data().append(tst);
}
}
pclose(fp);
TQMap<TQString,TQStringList>::Iterator ite;
for (ite = hashMap.begin(); ite != hashMap.end(); ite++) {
TDEListViewItem *item;
TQStringList::Iterator it;
TQString name,id;
for (it = ite.data().begin(); it != ite.data().end(); it++) {
TQString tst = (*it);
if (tst.startsWith("sec") ) {
if ( KgpgInterface::getGpgVersion() < 210) {
name=KgpgInterface::checkForUtf8(tst.section(':',9,9));
}
id = tst.section(':',4,4);
}
if ( tst.startsWith("uid") && KgpgInterface::getGpgVersion() >= 210 ) {
name=KgpgInterface::checkForUtf8(tst.section(':',9,9));
}
}
if (!name.isEmpty()) {
fp2 = popen("gpg --display-charset=utf-8 --no-tty --with-colon --list-keys "+TQFile::encodeName(id), "r");
while ( fgets( line, sizeof(line), fp2)) {
TQString tst2=TQString::fromUtf8(line);
if (tst2.startsWith("pub") && (trustedvals.find(tst2.section(':',1,1))==-1)) {
counter=true;
wiz->CBdefault->insertItem(id.right(8)+": "+name);
if (firstKey.isEmpty()) {
firstKey=id.right(8)+": "+name;
}
break;
}
}
pclose(fp2);
}
}
wiz->CBdefault->setCurrentItem(firstKey);
//connect(wiz->pushButton4,TQ_SIGNAL(clicked()),this,TQ_SLOT(slotGenKey()));
if (!counter)
connect(wiz->finishButton(),TQ_SIGNAL(clicked()),this,TQ_SLOT(slotGenKey()));
else {
wiz->textGenerate->hide();
wiz->setTitle(wiz->page_4,i18n("Step Three: Select your Default Private Key"));
connect(wiz->finishButton(),TQ_SIGNAL(clicked()),this,TQ_SLOT(slotSaveOptionsPath()));
}
connect(wiz->nextButton(),TQ_SIGNAL(clicked()),this,TQ_SLOT(slotWizardChange()));
connect( wiz , TQ_SIGNAL( destroyed() ) , this, TQ_SLOT( slotWizardClose()));
connect(wiz,TQ_SIGNAL(helpClicked()),this,TQ_SLOT(help()));
wiz->setFinishEnabled(wiz->page_4,true);
wiz->show();
}
void MyView::slotWizardChange()
{
if (wiz->indexOf(wiz->currentPage())==2) {
TQString defaultID=KgpgInterface::getGpgSetting("default-key",wiz->kURLRequester1->url());
if (defaultID.isEmpty())
return;
char line[300];
FILE *fp;
TQString id, name, currentKey;
TQMap<TQString,TQStringList> hashMap;
fp = popen("gpg --display-charset=utf-8 --no-tty --with-colon --list-secret-keys "+TQFile::encodeName(defaultID), "r");
while ( fgets( line, sizeof(line), fp)) {
TQString tst=TQString::fromUtf8(line);
kdDebug(2100) << k_funcinfo << "Read one secret key line: " << tst << endl;
if ( tst.startsWith("sec") ) {
currentKey = tst.section(':',4,4);
TQStringList lst; lst << tst;
hashMap.insert(currentKey,lst);
}
else {
hashMap.find(currentKey).data().append(tst);
}
}
pclose(fp);
TQMap<TQString,TQStringList>::Iterator ite;
for (ite = hashMap.begin(); ite != hashMap.end(); ite++) {
for (TQStringList::Iterator it = ite.data().begin(); it != ite.data().end(); it++) {
TQString tst = (*it);
tst=TQString::fromUtf8(line);
if ( tst.startsWith("sec") ) {
if (KgpgInterface::getGpgVersion() < 210) {
name=KgpgInterface::checkForUtf8(tst.section(':',9,9));
}
id=tst.section(':',4,4).right(8);
}
if ( (tst.startsWith("uid") && KgpgInterface::getGpgVersion() >= 210) ) {
name=KgpgInterface::checkForUtf8(tst.section(':',9,9));
}
}
}
wiz->CBdefault->setCurrentItem(id+": "+name);
}
}
void MyView::installShred()
{
KURL path;
path.setPath(TDEGlobalSettings::desktopPath());
path.addPath("shredder.desktop");
KDesktopFile configl2(path.path(), false);
if (configl2.isImmutable() ==false) {
configl2.setGroup("Desktop Entry");
configl2.writeEntry("Type", "Application");
configl2.writeEntry("Name",i18n("Shredder"));
configl2.writeEntry("Icon","editshred");
configl2.writeEntry("Exec","kgpg -X %U");
}
}
void MyView::slotSaveOptionsPath()
{
tqWarning("Save wizard settings...");
if (wiz->checkBox1->isChecked()) installShred();
KGpgSettings::setAutoStart( wiz->checkBox2->isChecked() );
KGpgSettings::setGpgConfigPath( wiz->kURLRequester1->url() );
KGpgSettings::setFirstRun( false );
TQString defaultID=wiz->CBdefault->currentText().section(':',0,0);
/* if (!defaultID.isEmpty()) {
KGpgSettings::setDefaultKey(defaultID);
}*/
KGpgSettings::writeConfig();
emit updateDefault("0x"+defaultID);
if (wiz)
delete wiz;
}
void MyView::slotWizardClose()
{
wiz=0L;
}
void MyView::slotGenKey()
{
slotSaveOptionsPath();
emit createNewKey();
}
void MyView::about()
{
TDEAboutApplication dialog(kapp->aboutData());//_aboutData);
dialog.exec();
}
void MyView::help()
{
kapp->invokeHelp(0,"kgpg");
}
kgpgapplet::kgpgapplet(TQWidget *parent, const char *name)
: KSystemTray(parent,name)
{
w=new MyView(this);
w->show();
TDEPopupMenu *conf_menu=contextMenu();
KgpgEncryptClipboard = new TDEAction(i18n("&Encrypt Clipboard"), "kgpg", 0,w, TQ_SLOT(clipEncrypt()),actionCollection(),"clip_encrypt");
KgpgDecryptClipboard = new TDEAction(i18n("&Decrypt Clipboard"), 0, 0,w, TQ_SLOT(clipDecrypt()),actionCollection(),"clip_decrypt");
KgpgSignClipboard = new TDEAction(i18n("&Sign/Verify Clipboard"), "signature", 0,w, TQ_SLOT(clipSign()),actionCollection(),"clip_sign");
TDEAction *KgpgOpenEditor;
if (KGpgSettings::leftClick()==KGpgSettings::EnumLeftClick::KeyManager)
KgpgOpenEditor = new TDEAction(i18n("&Open Editor"), "edit", 0,parent, TQ_SLOT(slotOpenEditor()),actionCollection(),"kgpg_editor");
else
KgpgOpenEditor = new TDEAction(i18n("&Open Key Manager"), "kgpg", 0,this, TQ_SLOT(slotOpenKeyManager()),actionCollection(),"kgpg_editor");
TDEAction *KgpgOpenServer = new TDEAction(i18n("&Key Server Dialog"), "network", 0,this, TQ_SLOT(slotOpenServerDialog()),actionCollection(),"kgpg_server");
TDEAction *KgpgPreferences=KStdAction::preferences(this, TQ_SLOT(showOptions()), actionCollection());
connect (conf_menu,TQ_SIGNAL(aboutToShow()),this,TQ_SLOT(checkMenu()));
KgpgEncryptClipboard->plug(conf_menu);
KgpgDecryptClipboard->plug(conf_menu);
KgpgSignClipboard->plug(conf_menu);
KgpgOpenEditor->plug(conf_menu);
KgpgOpenServer->plug(conf_menu);
conf_menu->insertSeparator();
KgpgPreferences->plug(conf_menu);
}
void kgpgapplet::checkMenu()
{
KgpgDecryptClipboard->setEnabled(false);
if ((kapp->clipboard()->text(w->clipboardMode).isEmpty()))
{
KgpgEncryptClipboard->setEnabled(false);
KgpgSignClipboard->setEnabled(false);
}
else
{
KgpgEncryptClipboard->setEnabled(true);
if (kapp->clipboard()->text(w->clipboardMode).stripWhiteSpace().startsWith("-----BEGIN"))
KgpgDecryptClipboard->setEnabled(true);
KgpgSignClipboard->setEnabled(true);
}
}
void kgpgapplet::showOptions()
{
TQByteArray data;
if (!kapp->dcopClient()->send("kgpg", "KeyInterface", "showOptions()",data))
kdDebug(2100) <<"there was some error using DCOP."<<endl;
}
void kgpgapplet::slotOpenKeyManager()
{
TQByteArray data;
if (!kapp->dcopClient()->send("kgpg", "KeyInterface", "showKeyManager()",data))
kdDebug(2100) <<"there was some error using DCOP."<<endl;
}
void kgpgapplet::slotOpenServerDialog()
{
TQByteArray data;
if (!kapp->dcopClient()->send("kgpg", "KeyInterface", "showKeyServer()",data))
kdDebug(2100) <<"there was some error using DCOP."<<endl;
}
kgpgapplet::~kgpgapplet()
{
delete w;
w = 0L;
}
KgpgAppletApp::KgpgAppletApp()
: KUniqueApplication()//, kgpg_applet( 0 )
{
running=false;
}
KgpgAppletApp::~KgpgAppletApp()
{
delete s_keyManager;
s_keyManager=0L;
delete kgpg_applet;
kgpg_applet = 0L;
}
void KgpgAppletApp::slotHandleQuit()
{
s_keyManager->keysList2->saveLayout(TDEGlobal::config(),"KeyView");
KGpgSettings::setPhotoProperties(s_keyManager->photoProps->currentItem());
KGpgSettings::setShowTrust(s_keyManager->sTrust->isChecked());
KGpgSettings::setShowExpi(s_keyManager->sExpi->isChecked());
KGpgSettings::setShowCreat(s_keyManager->sCreat->isChecked());
KGpgSettings::setShowSize(s_keyManager->sSize->isChecked());
KGpgSettings::writeConfig();
KSimpleConfig ("kgpgrc").sync();
quit();
}
void KgpgAppletApp::wizardOver(TQString defaultKeyId)
{
if (defaultKeyId.length()==10)
s_keyManager->slotSetDefaultKey(defaultKeyId);
s_keyManager->show();
s_keyManager->raise();
}
int KgpgAppletApp::newInstance()
{
kdDebug(2100)<<"New instance"<<endl;
args = TDECmdLineArgs::parsedArgs();
if (running) {
kdDebug(2100)<<"Already running"<<endl;
kgpg_applet->show();
} else {
kdDebug(2100) << "Starting KGpg"<<endl;
running=true;
s_keyManager=new listKeys(0, "key_manager");
TQString gpgPath= KGpgSettings::gpgConfigPath();
if (!gpgPath.isEmpty() && KURL(gpgPath).directory(false)!=TQDir::homeDirPath()+"/.gnupg/")
setenv("GNUPGHOME", TQFile::encodeName(KURL::fromPathOrURL(gpgPath).directory(false)), 1);
s_keyManager->refreshkey();
if (KGpgSettings::leftClick()==KGpgSettings::EnumLeftClick::KeyManager)
kgpg_applet=new kgpgapplet(s_keyManager,"kgpg_systrayapplet");
else
{
kgpg_applet=new kgpgapplet(s_keyManager->s_kgpgEditor,"kgpg_systrayapplet");
}
connect(s_keyManager,TQ_SIGNAL(encryptFiles(KURL::List)),kgpg_applet->w,TQ_SLOT(encryptFiles(KURL::List)));
connect(s_keyManager,TQ_SIGNAL(installShredder()),kgpg_applet->w,TQ_SLOT(installShred()));
connect(s_keyManager->s_kgpgEditor,TQ_SIGNAL(encryptFiles(KURL::List)),kgpg_applet->w,TQ_SLOT(encryptFiles(KURL::List)));
connect( kgpg_applet, TQ_SIGNAL(quitSelected()), this, TQ_SLOT(slotHandleQuit()));
connect(s_keyManager,TQ_SIGNAL(readAgainOptions()),kgpg_applet->w,TQ_SLOT(readOptions()));
connect(kgpg_applet->w,TQ_SIGNAL(updateDefault(TQString)),this,TQ_SLOT(wizardOver(TQString)));
connect(kgpg_applet->w,TQ_SIGNAL(createNewKey()),s_keyManager,TQ_SLOT(slotgenkey()));
connect(s_keyManager,TQ_SIGNAL(fontChanged(TQFont)),kgpg_applet->w,TQ_SIGNAL(setFont(TQFont)));
connect(kgpg_applet->w,TQ_SIGNAL(importedKeys(TQStringList)),s_keyManager->keysList2,TQ_SLOT(slotReloadKeys(TQStringList)));
kgpg_applet->show();
if (!gpgPath.isEmpty()) {
if ((KgpgInterface::getGpgBoolSetting("use-agent",gpgPath)) && (!getenv("GPG_AGENT_INFO")))
KMessageBox::sorry(0,i18n("<qt>The use of <b>GnuPG Agent</b> is enabled in GnuPG's configuration file (%1).<br>"
"However, the agent does not seem to be running. This could result in problems with signing/decryption.<br>"
"Please disable GnuPG Agent from KGpg settings, or fix the agent.</qt>").arg(gpgPath));
}
}
goHome=s_keyManager->actionCollection()->action("go_default_key")->shortcut();
kgpg_applet->w->goDefaultKey=goHome;
//////////////////////// parsing of command line args
if (args->isSet("k")!=0) {
s_keyManager->show();
KWin::setOnDesktop( s_keyManager->winId() , KWin::currentDesktop() ); //set on the current desktop
KWin::deIconifyWindow( s_keyManager->winId()); //de-iconify window
s_keyManager->raise(); // set on top
} else
if (args->count()>0) {
kdDebug(2100) << "KGpg: found files"<<endl;
urlList.clear();
for (int ct=0;ct<args->count();ct++)
urlList.append(args->url(ct));
if (urlList.empty())
return 0;
kgpg_applet->w->droppedUrl=urlList.first();
bool directoryInside=false;
TQStringList lst=urlList.toStringList();
for ( TQStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
if (KMimeType::findByURL(KURL( *it ))->name()=="inode/directory")
directoryInside=true;
}
if ((directoryInside) && (lst.count()>1)) {
KMessageBox::sorry(0,i18n("Unable to perform requested operation.\nPlease select only one folder, or several files, but do not mix files and folders."));
return 0;
}
kgpg_applet->w->droppedUrls=urlList;
if (args->isSet("e")!=0) {
if (!directoryInside)
kgpg_applet->w->encryptDroppedFile();
else
kgpg_applet->w->encryptDroppedFolder();
} else if (args->isSet("X")!=0) {
if (!directoryInside)
kgpg_applet->w->shredDroppedFile();
else
KMessageBox::sorry(0,i18n("Cannot shred folder."));
} else if (args->isSet("s")!=0) {
if (!directoryInside)
kgpg_applet->w->showDroppedFile();
else
KMessageBox::sorry(0,i18n("Cannot decrypt and show folder."));
} else if (args->isSet("S")!=0) {
if (!directoryInside)
kgpg_applet->w->signDroppedFile();
else
KMessageBox::sorry(0,i18n("Cannot sign folder."));
} else if (args->isSet("V")!=0) {
if (!directoryInside)
kgpg_applet->w->slotVerifyFile();
else
KMessageBox::sorry(0,i18n("Cannot verify folder."));
} else if (kgpg_applet->w->droppedUrl.fileName().endsWith(".sig"))
kgpg_applet->w->slotVerifyFile();
else
kgpg_applet->w->decryptDroppedFile();
}
return 0;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void MyView::encryptClipboard(TQStringList selec,TQStringList encryptOptions,bool,bool symmetric)
{
if (kapp->clipboard()->text(clipboardMode).isEmpty()) {
KPassivePopup::message(i18n("Clipboard is empty."),TQString(),TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop),this);
return;
}
if (KGpgSettings::pgpCompatibility())
encryptOptions<<"--pgp6";
encryptOptions<<"--armor";
if (symmetric) selec.clear();
KgpgInterface *txtEncrypt=new KgpgInterface();
connect (txtEncrypt,TQ_SIGNAL(txtencryptionfinished(TQString)),this,TQ_SLOT(slotSetClip(TQString)));
connect (txtEncrypt,TQ_SIGNAL(txtencryptionstarted()),this,TQ_SLOT(slotPassiveClip()));
txtEncrypt->KgpgEncryptText(kapp->clipboard()->text(clipboardMode),selec,encryptOptions);
}
void MyView::slotPassiveClip()
{
TQString newtxt=kapp->clipboard()->text(clipboardMode);
if (newtxt.length()>300)
newtxt=TQString(newtxt.left(250).stripWhiteSpace())+"...\n"+TQString(newtxt.right(40).stripWhiteSpace());
newtxt.replace(TQRegExp("<"),"&lt;"); ///// disable html tags
newtxt.replace(TQRegExp("\n"),"<br>");
pop = new KPassivePopup( this);
pop->setView(i18n("Encrypted following text:"),newtxt,TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop));
pop->setTimeout(3200);
pop->show();
TQRect qRect(TQApplication::desktop()->screenGeometry());
int iXpos=qRect.width()/2-pop->width()/2;
int iYpos=qRect.height()/2-pop->height()/2;
pop->move(iXpos,iYpos);
}
void MyView::slotSetClip(TQString newtxt)
{
if (newtxt.isEmpty()) return;
TQApplication::clipboard()->setText(newtxt,clipboardMode);//,TQClipboard::Clipboard); QT 3.1 only
}
/////////////////////////////////////////////////////////////////////////////
#include "kgpg.moc"