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.
2167 lines
80 KiB
2167 lines
80 KiB
/***************************************************************************
|
|
kgpginterface.cpp - description
|
|
-------------------
|
|
begin : Mon Jul 8 2002
|
|
copyright : (C) 2002 by Jean-Baptiste Mardelle
|
|
email : bj@altern.org
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* 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 <stdio.h>
|
|
|
|
#include <qdialog.h>
|
|
#include <qclipboard.h>
|
|
#include <qlayout.h>
|
|
#include <qregexp.h>
|
|
#include <qstring.h>
|
|
#include <qlabel.h>
|
|
#include <qapplication.h>
|
|
#include <kio/netaccess.h>
|
|
#include <qcheckbox.h>
|
|
|
|
#include <kmessagebox.h>
|
|
#include <klocale.h>
|
|
#include <kpassdlg.h>
|
|
#include <kmdcodec.h>
|
|
#include <klineedit.h>
|
|
#include <kcharsets.h>
|
|
#include <kpassivepopup.h>
|
|
#include <kiconloader.h>
|
|
#include <kaction.h>
|
|
#include <qtextcodec.h>
|
|
#include <kprocess.h>
|
|
#include <kprocio.h>
|
|
#include <kconfig.h>
|
|
#include <qfile.h>
|
|
#include <kled.h>
|
|
#include <kdebug.h>
|
|
#include <ktempfile.h>
|
|
|
|
#include "kgpginterface.h"
|
|
#include "listkeys.h"
|
|
#include "detailedconsole.h"
|
|
|
|
KgpgInterface::KgpgInterface()
|
|
{}
|
|
|
|
|
|
int KgpgInterface::getGpgVersion()
|
|
{
|
|
FILE *fp;
|
|
QString readResult,gpgString;
|
|
char buffer[200];
|
|
bool readLine=true;
|
|
|
|
QString gpgcmd="gpg --version";
|
|
|
|
fp = popen(QFile::encodeName(gpgcmd), "r");
|
|
while ( fgets( buffer, sizeof(buffer), fp)) {
|
|
readResult=buffer;
|
|
if (readLine) {
|
|
gpgString=readResult.stripWhiteSpace().section(' ',-1);
|
|
readLine=false;
|
|
}
|
|
}
|
|
pclose(fp);
|
|
return (100*gpgString.section('.',0,0).toInt()+10*gpgString.section('.',1,1).toInt()+gpgString.section('.',2,2).toInt());
|
|
}
|
|
|
|
void KgpgInterface::updateIDs(QString txtString)
|
|
{
|
|
int cut=txtString.find(' ',22,false);
|
|
txtString.remove(0,cut);
|
|
if (txtString.find("(",0,false)!=-1)
|
|
txtString=txtString.section('(',0,0)+txtString.section(')',-1);
|
|
txtString.replace(QRegExp("<"),"<");
|
|
if (userIDs.find(txtString)==-1)
|
|
{
|
|
if (!userIDs.isEmpty())
|
|
userIDs+=i18n(" or ");
|
|
userIDs+=txtString;
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::KgpgEncryptFile(QStringList encryptKeys,KURL srcUrl,KURL destUrl, QStringList Options, bool symetrical)
|
|
{
|
|
sourceFile=srcUrl;
|
|
message=QString::null;
|
|
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
|
|
*proc<<"--output"<<QFile::encodeName(destUrl.path());
|
|
|
|
if (!symetrical) {
|
|
*proc<<"-e";
|
|
for ( QStringList::Iterator it = encryptKeys.begin(); it != encryptKeys.end(); ++it )
|
|
*proc<<"--recipient"<< *it;
|
|
} else //////////// symetrical encryption, prompt for password
|
|
*proc<<"-c";
|
|
|
|
*proc<<QFile::encodeName(srcUrl.path());
|
|
|
|
///////// when process ends, update dialog infos
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(encryptfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(readencprocess(KProcIO *)));
|
|
proc->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
|
|
KgpgInterface::~KgpgInterface()
|
|
{}
|
|
|
|
|
|
void KgpgInterface::encryptfin(KProcess *)
|
|
{
|
|
if (message.find("END_ENCRYPTION")!=-1)
|
|
emit encryptionfinished(sourceFile);
|
|
else {
|
|
emit errormessage(message);
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::readencprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1) {
|
|
if (required.find("BEGIN_ENCRYPTION",0,false)!=-1)
|
|
emit processstarted(sourceFile.path());
|
|
if (required.find("GET_")!=-1) {
|
|
if (required.find("openfile.overwrite.okay")!=-1)
|
|
p->writeStdin("Yes");
|
|
else if ((required.find("passphrase.enter")!=-1)) {
|
|
QCString passphrase;
|
|
int code=KPasswordDialog::getNewPassword(passphrase,i18n("Enter passphrase for your file (symmetrical encryption):"));
|
|
if (code!=QDialog::Accepted) {
|
|
p->deleteLater();
|
|
emit processaborted(true);
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
} else {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
}
|
|
}
|
|
message+=required+"\n";
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// File decryption
|
|
|
|
void KgpgInterface::KgpgDecryptFile(KURL srcUrl,KURL destUrl,QStringList Options)
|
|
{
|
|
message=QString::null;
|
|
step=3;
|
|
decryptUrl=srcUrl.path();
|
|
userIDs=QString::null;
|
|
anonymous=false;
|
|
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
|
|
if (!destUrl.fileName().isEmpty()) // a filename was entered
|
|
*proc<<"-o"<<QFile::encodeName(destUrl.path());
|
|
|
|
*proc<<"-d"<<QFile::encodeName(srcUrl.path());
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(decryptfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(readdecprocess(KProcIO *)));
|
|
proc->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::decryptfin(KProcess *)
|
|
{
|
|
if ((message.find("DECRYPTION_OKAY")!=-1) && (message.find("END_DECRYPTION")!=-1)) //&& (message.find("GOODMDC")!=-1)
|
|
emit decryptionfinished();
|
|
else
|
|
emit errormessage(message);
|
|
}
|
|
|
|
|
|
void KgpgInterface::readdecprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1) {
|
|
if (required.find("BEGIN_DECRYPTION",0,false)!=-1)
|
|
emit processstarted(decryptUrl);
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("ENC_TO")!=-1) {
|
|
if (required.find("0000000000000000")!=-1)
|
|
anonymous=true;
|
|
}
|
|
if (required.find("GET_")!=-1) {
|
|
if (required.find("openfile.overwrite.okay")!=-1)
|
|
p->writeStdin("Yes");
|
|
else if ((required.find("passphrase.enter")!=-1)) {
|
|
if (userIDs.isEmpty())
|
|
userIDs=i18n("[No user id found]");
|
|
userIDs.replace(QRegExp("<"),"<");
|
|
QCString passphrase;
|
|
QString passdlgmessage;
|
|
if (anonymous)
|
|
passdlgmessage=i18n("<b>No user id found</b>. Trying all secret keys.<br>");
|
|
if ((step<3) && (!anonymous))
|
|
passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);
|
|
|
|
passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
|
|
int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
|
|
if (code!=QDialog::Accepted) {
|
|
p->deleteLater();
|
|
emit processaborted(true);
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
userIDs=QString::null;
|
|
if (step>1) step--;
|
|
else step=3;
|
|
} else {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
}
|
|
}
|
|
message+=required+"\n";
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// Text encryption
|
|
|
|
|
|
void KgpgInterface::KgpgEncryptText(QString text,QStringList userIDs, QStringList Options)
|
|
{
|
|
message=QString::null;
|
|
//QTextCodec *codec = KGlobal::charsets()->codecForName(KGlobal::locale()->encoding());
|
|
QTextCodec *codec =QTextCodec::codecForLocale ();
|
|
if (codec->canEncode(text)) txtToEncrypt=text;
|
|
else txtToEncrypt=text.utf8();
|
|
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=1"<<"--utf8-strings";
|
|
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
|
|
if (!userIDs.isEmpty())
|
|
{
|
|
*proc<<"-e";
|
|
for ( QStringList::Iterator it = userIDs.begin(); it != userIDs.end(); ++it )
|
|
*proc<<"--recipient"<< *it;
|
|
}
|
|
else
|
|
*proc<<"-c";
|
|
|
|
///////// when process ends, update dialog infos
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(txtencryptfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(txtreadencprocess(KProcIO *)));
|
|
proc->start(KProcess::NotifyOnExit,false);
|
|
emit txtencryptionstarted();
|
|
}
|
|
|
|
|
|
void KgpgInterface::txtencryptfin(KProcess *)
|
|
{
|
|
if (!message.isEmpty())
|
|
emit txtencryptionfinished(message);
|
|
else
|
|
emit txtencryptionfinished(QString::null);
|
|
}
|
|
|
|
void KgpgInterface::txtreadencprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1) {
|
|
if (required.find("BEGIN_ENCRYPTION",0,false)!=-1)
|
|
{
|
|
p->writeStdin(txtToEncrypt,false);
|
|
txtToEncrypt=QString::null;
|
|
p->closeWhenDone();
|
|
}
|
|
else
|
|
if ((required.find("passphrase.enter")!=-1))
|
|
{
|
|
QCString passphrase;
|
|
QString passdlgmessage=i18n("Enter passphrase (symmetrical encryption)");
|
|
int code=KPasswordDialog::getNewPassword(passphrase,passdlgmessage);
|
|
if (code!=QDialog::Accepted)
|
|
{
|
|
p->deleteLater();
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
}
|
|
else
|
|
if (!required.startsWith("[GNUPG:]")) message+=required+"\n";
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// Text decryption
|
|
|
|
void KgpgInterface::KgpgDecryptText(QString text,QStringList Options)
|
|
{
|
|
gpgOutput=QString::null;
|
|
log=QString::null;
|
|
|
|
message=QString::null;
|
|
userIDs=QString::null;
|
|
step=3;
|
|
anonymous=false;
|
|
decfinished=false;
|
|
decok=false;
|
|
badmdc=false;
|
|
KProcess *proc=new KProcess();
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=2"<<"--no-batch"<<"--utf8-strings";
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
*proc<<"-d";
|
|
|
|
///////// when process ends, update dialog infos
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(txtdecryptfin(KProcess *)));
|
|
connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)),this, SLOT(getOutput(KProcess *, char *, int)));
|
|
connect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)),this, SLOT(getCmdOutput(KProcess *, char *, int)));
|
|
proc->start(KProcess::NotifyOnExit,KProcess::All);
|
|
proc->writeStdin(text.utf8(), text.length());
|
|
}
|
|
|
|
void KgpgInterface::txtdecryptfin(KProcess *)
|
|
{
|
|
if ((decok) && (!badmdc))
|
|
emit txtdecryptionfinished(message);
|
|
|
|
else if (badmdc)
|
|
{
|
|
KMessageBox::sorry(0,i18n("Bad MDC detected. The encrypted text has been manipulated."));
|
|
emit txtdecryptionfailed(log);
|
|
}
|
|
else
|
|
emit txtdecryptionfailed(log);
|
|
}
|
|
|
|
|
|
void KgpgInterface::getOutput(KProcess *, char *data, int )
|
|
{
|
|
message.append(QString::fromUtf8(data));
|
|
}
|
|
|
|
|
|
void KgpgInterface::getCmdOutput(KProcess *p, char *data, int )
|
|
{
|
|
gpgOutput.append(QString::fromUtf8(data));
|
|
log.append(data);
|
|
|
|
int pos;
|
|
while ((pos=gpgOutput.find("\n"))!=-1)
|
|
{
|
|
QString required=gpgOutput.left(pos);
|
|
gpgOutput.remove(0,pos+2);
|
|
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("ENC_TO")!=-1)
|
|
{
|
|
if (required.find("0000000000000000")!=-1)
|
|
anonymous=true;
|
|
}
|
|
|
|
if (required.find("GET_")!=-1)
|
|
{
|
|
if ((required.find("passphrase.enter")!=-1))
|
|
{
|
|
if (userIDs.isEmpty())
|
|
userIDs=i18n("[No user id found]");
|
|
QCString passphrase;
|
|
QString passdlgmessage;
|
|
if (anonymous)
|
|
passdlgmessage=i18n("<b>No user id found</b>. Trying all secret keys.<br>");
|
|
if ((step<3) && (!anonymous))
|
|
passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);
|
|
passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
|
|
int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
|
|
if (code!=QDialog::Accepted)
|
|
{
|
|
p->deleteLater();
|
|
emit processaborted(true);
|
|
return;
|
|
}
|
|
passphrase.append("\n");
|
|
p->writeStdin(passphrase,passphrase.length());
|
|
userIDs=QString::null;
|
|
if (step>1) step--;
|
|
else step=3;
|
|
}
|
|
else
|
|
{
|
|
p->writeStdin("quit",4);
|
|
p->closeStdin();
|
|
}
|
|
}
|
|
|
|
if (required.find("BEGIN_DECRYPTION")!=-1)
|
|
{
|
|
p->closeStdin();
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("END_DECRYPTION")!=-1) decfinished=true;
|
|
if (required.find("DECRYPTION_OKAY")!=-1) decok=true;
|
|
if (required.find("DECRYPTION_FAILED")!=-1) decok=false;
|
|
if (required.find("BADMDC")!=-1) badmdc=true;
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////// Text signing
|
|
|
|
|
|
void KgpgInterface::KgpgSignText(QString text,QString userIDs, QStringList Options)
|
|
{
|
|
message=QString::null;
|
|
step=4;
|
|
QString txtprocess;
|
|
QTextCodec *codec =QTextCodec::codecForLocale ();
|
|
if (codec->canEncode(text)) txtprocess=text;
|
|
else txtprocess=text.utf8();
|
|
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=1"<<"--utf8-strings";
|
|
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
*proc<<"--clearsign"<<"-u"<<userIDs;
|
|
|
|
///////// when process ends, update dialog infos
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(txtsignfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(txtsignprocess(KProcIO *)));
|
|
|
|
//emit txtsigningstarted();
|
|
|
|
proc->start(KProcess::NotifyOnExit,false);
|
|
/*if (useAgent)
|
|
{
|
|
kdDebug(2100)<<"Using Agent+++++++++++++"<<endl;
|
|
//KMessageBox::sorry(0,"using agent");
|
|
proc->writeStdin(txtprocess,true);
|
|
proc->closeWhenDone();
|
|
}
|
|
else*/
|
|
message=txtprocess;
|
|
}
|
|
|
|
|
|
void KgpgInterface::txtsignfin(KProcess *)
|
|
{
|
|
if (!message.isEmpty())
|
|
emit txtSignOver(message);
|
|
else
|
|
emit txtSignOver(QString::null);
|
|
}
|
|
|
|
void KgpgInterface::txtsignprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1) {
|
|
// kdDebug(2100)<<"SIGNING: "<<required<<endl;
|
|
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("GOOD_PASSPHRASE")!=-1)
|
|
{
|
|
p->writeStdin(message,true);
|
|
message=QString::null;
|
|
p->closeWhenDone();
|
|
}
|
|
|
|
if ((required.find("passphrase.enter")!=-1))
|
|
{
|
|
if (step>1) step--;
|
|
else step=3;
|
|
if (userIDs.isEmpty())
|
|
userIDs=i18n("[No user id found]");
|
|
QCString passphrase;
|
|
QString passdlgmessage;
|
|
if (step<3)
|
|
passdlgmessage=i18n("<b>Bad passphrase</b>. You have %1 tries left.<br>").arg(step);
|
|
passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
|
|
int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
|
|
if (code!=QDialog::Accepted)
|
|
{
|
|
p->deleteLater();
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
}
|
|
else
|
|
if (!required.startsWith("[GNUPG:]")) message+=required+"\n";
|
|
}
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////// decrypt file to text
|
|
|
|
void KgpgInterface::KgpgDecryptFileToText(KURL srcUrl,QStringList Options)
|
|
{
|
|
|
|
message=QString::null;
|
|
userIDs=QString::null;
|
|
step=3;
|
|
anonymous=false;
|
|
decfinished=false;
|
|
decok=false;
|
|
badmdc=false;
|
|
|
|
KProcess *proc=new KProcess();
|
|
*proc<<"gpg"<<"--no-tty"<<"--utf8-strings"<<"--no-secmem-warning"<<"--command-fd=0"<<"--status-fd=2"<<"--no-batch"<<"-o"<<"-";
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it ) {
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
}
|
|
*proc<<"-d"<<QFile::encodeName(srcUrl.path());
|
|
|
|
///////// when process ends, update dialog infos
|
|
|
|
connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(txtdecryptfin(KProcess *)));
|
|
connect(proc, SIGNAL(receivedStdout(KProcess *, char *, int)),this, SLOT(getOutput(KProcess *, char *, int)));
|
|
connect(proc, SIGNAL(receivedStderr(KProcess *, char *, int)),this, SLOT(getCmdOutput(KProcess *, char *, int)));
|
|
proc->start(KProcess::NotifyOnExit,KProcess::All);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////// verify text
|
|
|
|
|
|
void KgpgInterface::KgpgVerifyText(QString text)
|
|
{
|
|
|
|
QTextCodec *codec =QTextCodec::codecForLocale ();
|
|
if (!codec->canEncode(text)) text=text.utf8();
|
|
signmiss=false;
|
|
signID=QString::null;
|
|
message=QString::null;
|
|
KProcIO *verifyproc=new KProcIO(QTextCodec::codecForLocale());
|
|
*verifyproc<<"gpg"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings"<<"--verify";
|
|
connect(verifyproc, SIGNAL(processExited(KProcess *)),this, SLOT(slotverifyresult(KProcess *)));
|
|
connect(verifyproc, SIGNAL(readReady(KProcIO *)),this, SLOT(slotverifyread(KProcIO *)));
|
|
verifyproc->start(KProcess::NotifyOnExit,true);
|
|
verifyproc->writeStdin (text);
|
|
verifyproc->closeWhenDone();
|
|
}
|
|
|
|
|
|
void KgpgInterface::slotverifyresult(KProcess*)
|
|
{
|
|
if (signmiss) emit missingSignature(signID);
|
|
else {
|
|
if (signID.isEmpty()) signID=i18n("No signature found.");
|
|
emit verifyOver(signID,message);
|
|
}
|
|
//kdDebug(2100) << "GPG VERIFY OVER________"<<endl;
|
|
}
|
|
|
|
void KgpgInterface::slotverifyread(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1)
|
|
{
|
|
message+=required+"\n";
|
|
required=required.section("]",1,-1).stripWhiteSpace();
|
|
if (required.startsWith("GOODSIG"))
|
|
{
|
|
QString userName=required.section(" ",2,-1).replace(QRegExp("<"),"<");
|
|
userName=checkForUtf8(userName);
|
|
signID=i18n("<qt>Good signature from:<br><b>%1</b><br>Key ID: %2</qt>").arg(userName).arg("0x"+required.section(" ",1,1).right(8));
|
|
}
|
|
if (required.startsWith("BADSIG"))
|
|
{
|
|
signID=i18n("<qt><b>Bad signature</b> from:<br>%1<br>Key ID: %2<br><br><b>Text is corrupted.</b></qt>").arg(required.section(" ",2,-1).replace(QRegExp("<"),"<")).arg("0x"+required.section(" ",1,1).right(8));
|
|
}
|
|
if (required.startsWith("NO_PUBKEY"))
|
|
{
|
|
signID="0x"+required.section(" ",1,1).right(8);
|
|
signmiss=true;
|
|
}
|
|
if (required.startsWith("UNEXPECTED") || required.startsWith("NODATA"))
|
|
signID=i18n("No signature found.");
|
|
if (required.startsWith("TRUST_UNDEFINED"))
|
|
signID+=i18n("The signature is valid, but the key is untrusted");
|
|
if (required.startsWith("TRUST_ULTIMATE"))
|
|
signID+=i18n("The signature is valid, and the key is ultimately trusted");
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////// MD5
|
|
|
|
Md5Widget::Md5Widget(QWidget *parent, const char *name,KURL url):KDialogBase( parent, name, true,i18n("MD5 Checksum"),Apply | Close)
|
|
{
|
|
setButtonApply(i18n("Compare MD5 with Clipboard"));
|
|
mdSum=QString::null;
|
|
QFile f(url.path());
|
|
f.open( IO_ReadOnly);
|
|
KMD5 checkfile;
|
|
checkfile.reset();
|
|
checkfile.update(f);
|
|
mdSum=checkfile.hexDigest().data();
|
|
f.close();
|
|
QWidget *page = new QWidget(this);
|
|
|
|
resize( 360, 150 );
|
|
QGridLayout *MyDialogLayout = new QGridLayout( page, 1, 1, 5, 6, "MyDialogLayout");
|
|
|
|
QLabel *TextLabel1 = new QLabel( page, "TextLabel1" );
|
|
TextLabel1->setText(i18n("MD5 sum for <b>%1</b> is:").arg(url.fileName()));
|
|
MyDialogLayout->addWidget( TextLabel1, 0, 0 );
|
|
|
|
KLineEdit *KRestrictedLine1 = new KLineEdit(mdSum,page);
|
|
KRestrictedLine1->setReadOnly(true);
|
|
KRestrictedLine1->setPaletteBackgroundColor(QColor(255,255,255));
|
|
MyDialogLayout->addWidget( KRestrictedLine1, 1, 0 );
|
|
|
|
|
|
QHBoxLayout *Layout4 = new QHBoxLayout( 0, 0, 6, "Layout4");
|
|
|
|
KLed1=new KLed(QColor(80,80,80),KLed::Off,KLed::Sunken,KLed::Circular,page,"KLed1");
|
|
KLed1->off();
|
|
KLed1->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)0, (QSizePolicy::SizeType)0, 0, 0, KLed1->sizePolicy().hasHeightForWidth() ) );
|
|
Layout4->addWidget( KLed1 );
|
|
|
|
TextLabel1_2 = new QLabel( page, "TextLabel1_2" );
|
|
TextLabel1_2->setText(i18n( "<b>Unknown status</b>" ) );
|
|
Layout4->addWidget( TextLabel1_2 );
|
|
|
|
MyDialogLayout->addLayout( Layout4, 2, 0 );
|
|
QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding );
|
|
MyDialogLayout->addItem( spacer, 3, 0 );
|
|
|
|
page->show();
|
|
page->resize(page->minimumSize());
|
|
setMainWidget(page);
|
|
|
|
|
|
}
|
|
|
|
Md5Widget::~Md5Widget()
|
|
{}
|
|
|
|
void Md5Widget::slotApply()
|
|
{
|
|
QClipboard *cb = QApplication::clipboard();
|
|
QString text;
|
|
// Copy text from the clipboard (paste)
|
|
text = cb->text(QClipboard::Clipboard);
|
|
if ( !text.isEmpty() ) {
|
|
text=text.stripWhiteSpace();
|
|
while (text.find(' ')!=-1)
|
|
text.remove(text.find(' '),1);
|
|
if (text==mdSum) {
|
|
TextLabel1_2->setText(i18n("<b>Correct checksum</b>, file is ok."));
|
|
KLed1->setColor(QColor(0,255,0));
|
|
KLed1->on();
|
|
}//KMessageBox::sorry(0,"OK");
|
|
else if (text.length()!=mdSum.length())
|
|
KMessageBox::sorry(0,i18n("Clipboard content is not a MD5 sum."));
|
|
else {
|
|
TextLabel1_2->setText(i18n("<b>Wrong checksum, FILE CORRUPTED</b>"));
|
|
KLed1->setColor(QColor(255,0,0));
|
|
KLed1->on();
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////// signatures
|
|
|
|
|
|
void KgpgInterface::KgpgSignFile(QString keyID,KURL srcUrl,QStringList Options)
|
|
{
|
|
////////////////////////////////////// create a detached signature for a chosen file
|
|
message=QString::null;
|
|
step=3;
|
|
///////////// create gpg command
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
keyID=keyID.stripWhiteSpace();
|
|
*proc<<"gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--utf8-strings"<<"--status-fd=2"<<"--command-fd=0"<<"-u"<<keyID.local8Bit();
|
|
for ( QStringList::Iterator it = Options.begin(); it != Options.end(); ++it )
|
|
if (!QFile::encodeName(*it).isEmpty()) *proc<< QFile::encodeName(*it);
|
|
|
|
*proc<<"--output"<<QFile::encodeName(srcUrl.path()+".sig");
|
|
*proc<<"--detach-sig"<<QFile::encodeName(srcUrl.path());
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(signfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(readsignprocess(KProcIO *)));
|
|
proc->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
|
|
|
|
void KgpgInterface::signfin(KProcess *)
|
|
{
|
|
if (message.find("SIG_CREATED")!=-1)
|
|
KMessageBox::information(0,i18n("The signature file %1 was successfully created.").arg(file.fileName()));
|
|
else if (message.find("BAD_PASSPHRASE")!=-1)
|
|
KMessageBox::sorry(0,i18n("Bad passphrase, signature was not created."));
|
|
else
|
|
KMessageBox::sorry(0,message);
|
|
emit signfinished();
|
|
}
|
|
|
|
|
|
void KgpgInterface::readsignprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1) {
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("GET_")!=-1) {
|
|
if (required.find("openfile.overwrite.okay")!=-1)
|
|
p->writeStdin("Yes");
|
|
else if ((required.find("passphrase.enter")!=-1)) {
|
|
if (userIDs.isEmpty())
|
|
userIDs=i18n("[No user id found]");
|
|
QCString passphrase;
|
|
QString passdlgmessage;
|
|
if (step<3)
|
|
passdlgmessage=i18n("<b>Bad passphrase</b>. you have %1 tries left.<br>").arg(step);
|
|
passdlgmessage+=i18n("Enter passphrase for <b>%1</b>").arg(userIDs);
|
|
int code=KPasswordDialog::getPassword(passphrase,passdlgmessage);
|
|
if (code!=QDialog::Accepted) {
|
|
p->deleteLater();
|
|
emit signfinished();
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
userIDs=QString::null;
|
|
if (step>1) step--;
|
|
else step=3;
|
|
} else {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
}
|
|
}
|
|
message+=required+"\n";
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
void KgpgInterface::KgpgVerifyFile(KURL sigUrl,KURL srcUrl)
|
|
{
|
|
////////////////////////////////////// verify signature for a chosen file
|
|
message=QString::null;
|
|
signID=QString::null;
|
|
signmiss=false;
|
|
///////////// create gpg command
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
file=sigUrl;
|
|
*proc<<"gpg"<<"--no-tty"<<"--utf8-strings"<<"--no-secmem-warning"<<"--status-fd=2"<<"--verify";
|
|
if (!srcUrl.isEmpty())
|
|
*proc<<QFile::encodeName(srcUrl.path());
|
|
*proc<<QFile::encodeName(sigUrl.path());
|
|
|
|
QObject::connect(proc, SIGNAL(processExited(KProcess *)),this,SLOT(verifyfin(KProcess *)));
|
|
QObject::connect(proc,SIGNAL(readReady(KProcIO *)),this,SLOT(readprocess(KProcIO *)));
|
|
proc->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
|
|
void KgpgInterface::readprocess(KProcIO *p)
|
|
{
|
|
QString required;
|
|
while (p->readln(required,true)!=-1)
|
|
{
|
|
message+=required+"\n";
|
|
if (required.find("GET_")!=-1) {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
}
|
|
required=required.section("]",1,-1).stripWhiteSpace();
|
|
if (required.startsWith("UNEXPECTED") || required.startsWith("NODATA"))
|
|
signID=i18n("No signature found.");
|
|
if (required.startsWith("GOODSIG"))
|
|
{
|
|
signID=i18n("<qt>Good signature from:<br><b>%1</b><br>Key ID: %2</qt>").arg(required.section(" ",2,-1).replace(QRegExp("<"),"<")).arg("0x"+required.section(" ",1,1).right(8));
|
|
}
|
|
if (required.startsWith("BADSIG"))
|
|
{
|
|
signID=i18n("<qt><b>BAD signature</b> from:<br> %1<br>Key id: %2<br><br>"
|
|
"<b>The file is corrupted!</b></qt>").arg(required.section(" ",2,-1).replace(QRegExp("<"),"<")).arg("0x"+required.section(" ",1,1).right(8));
|
|
}
|
|
if (required.startsWith("NO_PUBKEY"))
|
|
{
|
|
signmiss=true;
|
|
signID="0x"+required.section(" ",1,1).right(8);
|
|
}
|
|
if (required.startsWith("TRUST_UNDEFINED"))
|
|
signID+=i18n("The signature is valid, but the key is untrusted");
|
|
if (required.startsWith("TRUST_ULTIMATE"))
|
|
signID+=i18n("The signature is valid, and the key is ultimately trusted");
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgInterface::verifyfin(KProcess *)
|
|
{
|
|
if (!signmiss) {
|
|
if (signID.isEmpty()) signID=i18n("No signature found.");
|
|
(void) new KDetailedInfo(0,"verify_result",signID,message);
|
|
}
|
|
else {
|
|
if (KMessageBox::questionYesNo(0,i18n("<qt><b>Missing signature:</b><br>Key id: %1<br><br>"
|
|
"Do you want to import this key from a keyserver?</qt>").arg(signID),file.fileName(),QString::null, i18n("Import"), i18n("Do Not Import"))==KMessageBox::Yes)
|
|
emit verifyquerykey(signID);
|
|
}
|
|
emit verifyfinished();
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////// sign a key
|
|
|
|
void KgpgInterface::KgpgSignKey(QString keyID,QString signKeyID,QString signKeyMail,bool local,int checking)
|
|
{
|
|
signKeyMail.replace(QRegExp("<"),"<");
|
|
konsChecked=checking;
|
|
konsLocal=local;
|
|
konsSignKey=signKeyID;
|
|
konsKeyID=keyID;
|
|
errMessage=QString::null;
|
|
if (checkuid(keyID)>0)
|
|
{
|
|
openSignConsole();
|
|
return;
|
|
}
|
|
|
|
signSuccess=0;
|
|
step=1;
|
|
output=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--utf8-strings"<<"--command-fd=0"<<"--status-fd=2"<<"-u"<<signKeyID;
|
|
*conprocess<<"--edit-key"<<keyID;
|
|
if (local) *conprocess<<"lsign";
|
|
else *conprocess<<"sign";
|
|
QObject::connect(conprocess,SIGNAL(readReady(KProcIO *)),this,SLOT(sigprocess(KProcIO *)));
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(signover(KProcess *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::sigprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
|
|
while (p->readln(required,true)!=-1)
|
|
{
|
|
|
|
output+=required+"\n";
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (signSuccess==4) {
|
|
if (required.find("GET_")!=-1)
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
|
|
if ((required.find("GOOD_PASSPHRASE")!=-1)) {
|
|
signSuccess=3;
|
|
step=2;
|
|
}
|
|
|
|
if (required.find("sign_uid.expire")!=-1) {
|
|
p->writeStdin("Never");
|
|
required=QString::null;
|
|
}
|
|
if (required.find("sign_uid.class")!=-1) {
|
|
p->writeStdin(QString::number(konsChecked));
|
|
required=QString::null;
|
|
}
|
|
if (required.find("sign_uid.okay")!=-1) {
|
|
p->writeStdin("Y");
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("sign_all.okay")!=-1) {
|
|
p->writeStdin("Y");
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString signpass;
|
|
int code=KPasswordDialog::getPassword(signpass,i18n("<qt>%1 Enter passphrase for <b>%2</b>:</qt>")
|
|
.arg(errMessage).arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
signSuccess=4; ///// aborted by user mode
|
|
required=QString::null;
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(signpass,true);
|
|
required=QString::null;
|
|
// step=2;
|
|
}
|
|
if ((step==2) && (required.find("keyedit.prompt")!=-1)) {
|
|
p->writeStdin("save");
|
|
required=QString::null;
|
|
}
|
|
if (required.find("BAD_PASSPHRASE")!=-1) {
|
|
errMessage=i18n("<b>Bad passphrase</b>. Try again.</br>");
|
|
required=QString::null;
|
|
signSuccess=2; ///// bad passphrase
|
|
}
|
|
if (required.find("GET_")!=-1) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
if (signSuccess!=2)
|
|
signSuccess=1; ///// switching to console mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgInterface::signover(KProcess *)
|
|
{
|
|
if (signSuccess>1)
|
|
emit signatureFinished(signSuccess); //// signature successful or bad passphrase
|
|
else {
|
|
KDetailedConsole *q=new KDetailedConsole(0,"sign_error",i18n("<qt>Signing key <b>%1</b> with key <b>%2</b> failed.<br>"
|
|
"Do you want to try signing the key in console mode?</qt>").arg(konsKeyID).arg(konsSignKey),output);
|
|
if (q->exec()==QDialog::Accepted)
|
|
openSignConsole();
|
|
else
|
|
emit signatureFinished(0);
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::openSignConsole()
|
|
{
|
|
KProcess conprocess;
|
|
KConfig *config = KGlobal::config();
|
|
config->setGroup("General");
|
|
conprocess<< config->readPathEntry("TerminalApplication","konsole");
|
|
conprocess<<"-e"<<"gpg";
|
|
conprocess<<"--no-secmem-warning"<<"--expert"<<"-u"<<konsSignKey;
|
|
if (!konsLocal)
|
|
conprocess<<"--sign-key"<<konsKeyID;
|
|
else
|
|
conprocess<<"--lsign-key"<<konsKeyID;
|
|
conprocess.start(KProcess::Block);
|
|
emit signatureFinished(3);
|
|
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////// delete signature
|
|
|
|
|
|
void KgpgInterface::KgpgDelSignature(QString keyID,QString signKeyID)
|
|
{
|
|
if (checkuid(keyID)>0) {
|
|
KMessageBox::sorry(0,i18n("This key has more than one user ID.\nEdit the key manually to delete signature."));
|
|
return;
|
|
}
|
|
|
|
message=signKeyID.remove(0,2);
|
|
deleteSuccess=false;
|
|
step=0;
|
|
|
|
FILE *fp;
|
|
QString encResult;
|
|
char buffer[200];
|
|
signb=0;
|
|
sigsearch=0;
|
|
|
|
QString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --list-sigs "+keyID;
|
|
fp = popen(QFile::encodeName(gpgcmd), "r");
|
|
while ( fgets( buffer, sizeof(buffer), fp)) {
|
|
encResult=buffer;
|
|
if (encResult.startsWith("sig")) {
|
|
if (encResult.find(message)!=-1)
|
|
break;
|
|
signb++;
|
|
} else if (encResult.startsWith("rev"))
|
|
signb++;
|
|
}
|
|
pclose(fp);
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--utf8-strings"<<"--command-fd=0"<<"--status-fd=2";
|
|
*conprocess<<"--edit-key"<<keyID<<"uid 1"<<"delsig";
|
|
QObject::connect(conprocess,SIGNAL(readReady(KProcIO *)),this,SLOT(delsigprocess(KProcIO *)));
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(delsignover(KProcess *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
|
|
void KgpgInterface::delsigprocess(KProcIO *p)
|
|
{
|
|
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1)
|
|
{
|
|
if (required.find("keyedit.delsig")!=-1){
|
|
|
|
if ((sigsearch==signb) && (step==0)) {
|
|
p->writeStdin("Y");
|
|
step=1;
|
|
} else
|
|
p->writeStdin("n");
|
|
sigsearch++;
|
|
required=QString::null;
|
|
}
|
|
if ((step==1) && (required.find("keyedit.prompt")!=-1)) {
|
|
p->writeStdin("save");
|
|
required=QString::null;
|
|
deleteSuccess=true;
|
|
}
|
|
if (required.find("GET_LINE")!=-1) {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
deleteSuccess=false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::delsignover(KProcess *)
|
|
{
|
|
emit delsigfinished(deleteSuccess);
|
|
}
|
|
|
|
/////////////////////////////////////////////////// check if a key has more than one id
|
|
|
|
int KgpgInterface::checkuid(QString KeyID)
|
|
{
|
|
FILE *fp;
|
|
QString encResult;
|
|
char buffer[200];
|
|
int uidcnt=0;
|
|
|
|
QString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --list-sigs "+KeyID;
|
|
////////// encode with untrusted keys or armor if checked by user
|
|
fp = popen(QFile::encodeName(gpgcmd), "r");
|
|
while (fgets(buffer, sizeof(buffer), fp)) {
|
|
encResult=buffer;
|
|
if (encResult.startsWith("uid"))
|
|
uidcnt++;
|
|
}
|
|
pclose(fp);
|
|
return uidcnt;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////// change key expiration
|
|
|
|
|
|
void KgpgInterface::KgpgKeyExpire(QString keyID,QDate date,bool unlimited)
|
|
{
|
|
expSuccess=0;
|
|
step=0;
|
|
if (unlimited)
|
|
expirationDelay=0;
|
|
else
|
|
expirationDelay=QDate::currentDate().daysTo(date);
|
|
output=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"expire";
|
|
QObject::connect(conprocess,SIGNAL(readReady(KProcIO *)),this,SLOT(expprocess(KProcIO *)));
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(expover(KProcess *)));
|
|
conprocess->start(KProcess::NotifyOnExit,KProcess::AllOutput);
|
|
|
|
}
|
|
|
|
void KgpgInterface::expprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if ((required.find("GOOD_PASSPHRASE")!=-1)) {
|
|
expSuccess=3;
|
|
step=2;
|
|
}
|
|
|
|
if (required.find("keygen.valid")!=-1) {
|
|
p->writeStdin(QString::number(expirationDelay));
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString signpass;
|
|
int code=KPasswordDialog::getPassword(signpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
expSuccess=3; ///// aborted by user mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(signpass,true);
|
|
required=QString::null;
|
|
// step=2;
|
|
}
|
|
if ((step==2) && (required.find("keyedit.prompt")!=-1)) {
|
|
p->writeStdin("save");
|
|
p->closeWhenDone();
|
|
required=QString::null;
|
|
}
|
|
if ((step==2) && (required.find("keyedit.save.okay")!=-1)) {
|
|
p->writeStdin("YES");
|
|
p->closeWhenDone();
|
|
required=QString::null;
|
|
}
|
|
if (required.find("BAD_PASSPHRASE")!=-1) {
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
expSuccess=2; ///// bad passphrase
|
|
}
|
|
if ((required.find("GET_")!=-1) && (expSuccess!=2)) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
expSuccess=1; ///// switching to console mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void KgpgInterface::expover(KProcess *)
|
|
{
|
|
if ((expSuccess==3) || (expSuccess==2))
|
|
emit expirationFinished(expSuccess); //// signature successful or bad passphrase
|
|
else {
|
|
KDetailedConsole *q=new KDetailedConsole(0,"sign_error",i18n("<qt><b>Changing expiration failed.</b><br>"
|
|
"Do you want to try changing the key expiration in console mode?</qt>"),output);
|
|
if (q->exec()==QDialog::Accepted)
|
|
KMessageBox::sorry(0,"work in progress...");
|
|
//openSignConsole();
|
|
else
|
|
emit expirationFinished(0);
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////// change key trust
|
|
|
|
|
|
void KgpgInterface::KgpgTrustExpire(QString keyID,int keyTrust)
|
|
{
|
|
trustValue=keyTrust+1;
|
|
/* Don't know=1; Do NOT trust=2; Marginally=3; Fully=4; Ultimately=5; */
|
|
|
|
output=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"trust";
|
|
QObject::connect(conprocess,SIGNAL(readReady(KProcIO *)),this,SLOT(trustprocess(KProcIO *)));
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(trustover(KProcess *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
|
|
}
|
|
|
|
void KgpgInterface::trustprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
if (required.find("edit_ownertrust.set_ultimate.okay")!=-1) {
|
|
p->writeStdin("YES");
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("edit_ownertrust.value")!=-1) {
|
|
p->writeStdin(QString::number(trustValue));
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("keyedit.prompt")!=-1) {
|
|
p->writeStdin("save");
|
|
p->closeWhenDone();
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("GET_")!=-1) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
expSuccess=1; ///// switching to console mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void KgpgInterface::trustover(KProcess *)
|
|
{
|
|
emit trustfinished();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////// change passphrase
|
|
|
|
|
|
void KgpgInterface::KgpgChangePass(QString keyID)
|
|
{
|
|
step=1;
|
|
output=QString::null;
|
|
message=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<<"gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--no-use-agent"<<"--command-fd=0"<<"--status-fd=2"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"passwd";
|
|
QObject::connect(conprocess,SIGNAL(readReady(KProcIO *)),this,SLOT(passprocess(KProcIO *)));
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(passover(KProcess *)));
|
|
conprocess->start(KProcess::NotifyOnExit,KProcess::AllOutput);
|
|
|
|
}
|
|
|
|
void KgpgInterface::passprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if ((step>2) && (required.find("keyedit.prompt")!=-1)) {
|
|
if (step==3)
|
|
{
|
|
emit passwordChanged();
|
|
p->writeStdin("save");
|
|
}
|
|
else p->writeStdin("quit");
|
|
required=QString::null;
|
|
}
|
|
|
|
if ((required.find("GOOD_PASSPHRASE")!=-1) && (step==2))
|
|
step=3;
|
|
|
|
if ((required.find("BAD_PASSPHRASE")!=-1) && (step==2)) {
|
|
step=1;
|
|
message=i18n("<b>Bad passphrase</b>. Try again<br>");
|
|
}
|
|
|
|
if ((required.find("passphrase.enter")!=-1)) {
|
|
if (userIDs.isEmpty())
|
|
userIDs=i18n("[No user id found]");
|
|
userIDs.replace(QRegExp("<"),"<");
|
|
|
|
if (step==1) {
|
|
QCString passphrase;
|
|
int code=KPasswordDialog::getPassword(passphrase,i18n("<qt>%1 Enter passphrase for <b>%2</b></qt>")
|
|
.arg(message).arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
p->writeStdin("quit");
|
|
// p->closeWhenDone();
|
|
emit processaborted(true);
|
|
p->deleteLater();
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
step=2;
|
|
}
|
|
|
|
if (step==3) {
|
|
QCString passphrase;
|
|
int code=KPasswordDialog::getNewPassword(passphrase,i18n("<qt>Enter new passphrase for <b>%1</b><br>If you forget this passphrase, all your encrypted files and messages will be lost !<br></qt>").arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
step=4;
|
|
p->writeStdin("quit");
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
emit processaborted(true);
|
|
return;
|
|
}
|
|
p->writeStdin(passphrase,true);
|
|
userIDs=QString::null;
|
|
}
|
|
|
|
required=QString::null;
|
|
}
|
|
|
|
|
|
if (required.find("GET_")!=-1) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void KgpgInterface::passover(KProcess *)
|
|
{
|
|
//emit trustfinished();
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////// key export
|
|
|
|
QString KgpgInterface::getKey(QStringList IDs, bool attributes)
|
|
{
|
|
keyString=QString::null;
|
|
KProcIO *proc=new KProcIO(QTextCodec::codecForLocale());
|
|
*proc<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--utf8-strings";
|
|
*proc<<"--export"<<"--armor";
|
|
if (!attributes)
|
|
*proc<<"--export-options"<<"no-include-attributes";
|
|
|
|
for ( QStringList::Iterator it = IDs.begin(); it != IDs.end(); ++it )
|
|
*proc << *it;
|
|
QObject::connect(proc, SIGNAL(readReady(KProcIO *)),this, SLOT(slotReadKey(KProcIO *)));
|
|
proc->start(KProcess::Block,false);
|
|
return keyString;
|
|
}
|
|
|
|
|
|
void KgpgInterface::slotReadKey(KProcIO *p)
|
|
{
|
|
QString outp;
|
|
while (p->readln(outp)!=-1)
|
|
if (!outp.startsWith("gpg:")) keyString+=outp+"\n";
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////// key import
|
|
|
|
void KgpgInterface::importKeyURL(KURL url)
|
|
{
|
|
///////////// import a key
|
|
|
|
if( KIO::NetAccess::download( url, tempKeyFile,0) ) {
|
|
message=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--utf8-strings"<<"--import";
|
|
*conprocess<<"--allow-secret-key-import";
|
|
*conprocess<<tempKeyFile;
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(importURLover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(importprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::importKey(QString keystr)
|
|
{
|
|
///////////// import a key
|
|
message=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--no-secmem-warning"<<"--status-fd=2"<<"--import";
|
|
*conprocess<<"--allow-secret-key-import";
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(importover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(importprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
conprocess->writeStdin(keystr, true);
|
|
conprocess->closeWhenDone();
|
|
}
|
|
|
|
void KgpgInterface::importover(KProcess *)
|
|
{
|
|
QStringList importedKeysIds;
|
|
QStringList messageList;
|
|
QString resultMessage;
|
|
bool secretImport=false;
|
|
kdDebug(2100)<<"Importing is over"<<endl;
|
|
QString parsedOutput=message;
|
|
QStringList importedKeys;
|
|
|
|
while (parsedOutput.find("IMPORTED")!=-1) {
|
|
parsedOutput.remove(0,parsedOutput.find("IMPORTED")+8);
|
|
importedKeys<<parsedOutput.section("\n",0,0).stripWhiteSpace();
|
|
importedKeysIds<<parsedOutput.stripWhiteSpace().section(' ',0,0);
|
|
}
|
|
|
|
|
|
if (message.find("IMPORT_RES")!=-1) {
|
|
parsedOutput=message.section("IMPORT_RES",-1,-1).stripWhiteSpace();
|
|
messageList=QStringList::split(" ",parsedOutput,true);
|
|
|
|
resultMessage=i18n("<qt>%n key processed.<br></qt>","<qt>%n keys processed.<br></qt>",messageList[0].toULong());
|
|
if (messageList[4]!="0")
|
|
resultMessage+=i18n("<qt>One key unchanged.<br></qt>","<qt>%n keys unchanged.<br></qt>",messageList[4].toULong());
|
|
if (messageList[7]!="0")
|
|
resultMessage+=i18n("<qt>One signature imported.<br></qt>","<qt>%n signatures imported.<br></qt>",messageList[7].toULong());
|
|
if (messageList[1]!="0")
|
|
resultMessage+=i18n("<qt>One key without ID.<br></qt>","<qt>%n keys without ID.<br></qt>",messageList[1].toULong());
|
|
if (messageList[3]!="0")
|
|
resultMessage+=i18n("<qt>One RSA key imported.<br></qt>","<qt>%n RSA keys imported.<br></qt>",messageList[3].toULong());
|
|
if (messageList[5]!="0")
|
|
resultMessage+=i18n("<qt>One user ID imported.<br></qt>","<qt>%n user IDs imported.<br></qt>",messageList[5].toULong());
|
|
if (messageList[6]!="0")
|
|
resultMessage+=i18n("<qt>One subkey imported.<br></qt>","<qt>%n subkeys imported.<br></qt>",messageList[6].toULong());
|
|
if (messageList[8]!="0")
|
|
resultMessage+=i18n("<qt>One revocation certificate imported.<br></qt>","<qt>%n revocation certificates imported.<br></qt>",messageList[8].toULong());
|
|
if (messageList[9]!="0")
|
|
{
|
|
resultMessage+=i18n("<qt>One secret key processed.<br></qt>","<qt>%n secret keys processed.<br></qt>",messageList[9].toULong());
|
|
secretImport=true;
|
|
}
|
|
if (messageList[10]!="0")
|
|
resultMessage+=i18n("<qt><b>One secret key imported.</b><br></qt>","<qt><b>%n secret keys imported.</b><br></qt>",messageList[10].toULong());
|
|
if (messageList[11]!="0")
|
|
resultMessage+=i18n("<qt>One secret key unchanged.<br></qt>","<qt>%n secret keys unchanged.<br></qt>",messageList[11].toULong());
|
|
if (messageList[12]!="0")
|
|
resultMessage+=i18n("<qt>One secret key not imported.<br></qt>","<qt>%n secret keys not imported.<br></qt>",messageList[12].toULong());
|
|
if (messageList[2]!="0")
|
|
resultMessage+=i18n("<qt><b>One key imported:</b><br></qt>","<qt><b>%n keys imported:</b><br></qt>",messageList[2].toULong());
|
|
|
|
if (secretImport) resultMessage+=i18n("<qt><br><b>You have imported a secret key.</b> <br>"
|
|
"Please note that imported secret keys are not trusted by default.<br>"
|
|
"To fully use this secret key for signing and encryption, you must edit the key (double click on it) and set its trust to Full or Ultimate.</qt>");
|
|
} else
|
|
resultMessage=i18n("No key imported... \nCheck detailed log for more infos");
|
|
|
|
if (messageList[8]!="0") importedKeysIds="ALL";
|
|
if ((messageList[9]!="0") && (importedKeysIds.isEmpty())) // orphaned secret key imported
|
|
emit refreshOrphaned();
|
|
emit importfinished(importedKeysIds);
|
|
|
|
(void) new KDetailedInfo(0,"import_result",resultMessage,message,importedKeys);
|
|
}
|
|
|
|
void KgpgInterface::importURLover(KProcess *p)
|
|
{
|
|
KIO::NetAccess::removeTempFile(tempKeyFile);
|
|
importover(p);
|
|
//KMessageBox::information(0,message);
|
|
//emit importfinished();
|
|
}
|
|
|
|
void KgpgInterface::importprocess(KProcIO *p)
|
|
{
|
|
QString outp;
|
|
while (p->readln(outp)!=-1) {
|
|
if (outp.find("http-proxy")==-1)
|
|
message+=outp+"\n";
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////// User ID's
|
|
|
|
|
|
void KgpgInterface::KgpgAddUid(QString keyID,QString name,QString email,QString comment)
|
|
{
|
|
uidName=name;
|
|
uidComment=comment;
|
|
uidEmail=email;
|
|
output=QString::null;
|
|
addSuccess=true;
|
|
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"adduid";
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(adduidover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(adduidprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::adduidover(KProcess *)
|
|
{
|
|
if (addSuccess) emit addUidFinished();
|
|
else emit addUidError(output);
|
|
}
|
|
|
|
void KgpgInterface::adduidprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("keygen.name")!=-1) {
|
|
p->writeStdin(uidName);
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("keygen.email")!=-1) {
|
|
p->writeStdin(uidEmail);
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("keygen.comment")!=-1) {
|
|
p->writeStdin(uidComment);
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString delpass;
|
|
int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>")
|
|
.arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
//addSuccess=false;
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(delpass,true);
|
|
required=QString::null;
|
|
|
|
}
|
|
|
|
if (required.find("keyedit.prompt")!=-1) {
|
|
p->writeStdin("save");
|
|
required=QString::null;
|
|
}
|
|
|
|
if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
kdDebug(2100)<<"unknown request"<<endl;
|
|
addSuccess=false; ///// switching to console mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// photo id's
|
|
|
|
void KgpgInterface::KgpgGetPhotoList(QString keyID)
|
|
{
|
|
photoList.clear();
|
|
output=QString::null;
|
|
photoCount=1;
|
|
userIDs=keyID;
|
|
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0";
|
|
*conprocess<<"--with-colon"<<"--list-keys"<<keyID;
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(photoreadover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(photoreadprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::photoreadprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
if (required.startsWith("uat") || required.startsWith("uid")) photoCount++;
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgInterface::photoreadover(KProcess *)
|
|
{
|
|
for (int i=1;i<photoCount+1;i++)
|
|
if (isPhotoId(i)) photoList+=QString::number(i);
|
|
|
|
emit signalPhotoList(photoList);
|
|
}
|
|
|
|
bool KgpgInterface::isPhotoId(int uid)
|
|
{
|
|
KTempFile *kgpginfotmp=new KTempFile();
|
|
kgpginfotmp->setAutoDelete(true);
|
|
QString pgpgOutput="cp %i "+kgpginfotmp->name();
|
|
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
*conprocess<<"--photo-viewer"<<QFile::encodeName(pgpgOutput)<<"--edit-key"<<userIDs<<"uid"<<QString::number(uid)<<"showphoto";
|
|
conprocess->start(KProcess::Block);
|
|
if (kgpginfotmp->file()->size()>0)
|
|
{
|
|
kgpginfotmp->unlink();
|
|
return true;
|
|
}
|
|
kgpginfotmp->unlink();
|
|
return false;
|
|
}
|
|
|
|
void KgpgInterface::KgpgDeletePhoto(QString keyID,QString uid)
|
|
{
|
|
delSuccess=true;
|
|
output=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"uid"<<uid<<"deluid";
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(delphotoover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(delphotoprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::delphotoover(KProcess *)
|
|
{
|
|
if (delSuccess) emit delPhotoFinished();
|
|
else emit delPhotoError(output);
|
|
}
|
|
|
|
void KgpgInterface::delphotoprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("keyedit.remove.uid.okay")!=-1) {
|
|
p->writeStdin("YES");
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString delpass;
|
|
int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
//deleteSuccess=false;
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(delpass,true);
|
|
required=QString::null;
|
|
|
|
}
|
|
|
|
if (required.find("keyedit.prompt")!=-1) {
|
|
p->writeStdin("save");
|
|
required=QString::null;
|
|
}
|
|
|
|
if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
kdDebug(2100)<<"unknown request"<<endl;
|
|
delSuccess=false;
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgInterface::KgpgAddPhoto(QString keyID,QString imagePath)
|
|
{
|
|
photoUrl=imagePath;
|
|
output=QString::null;
|
|
addSuccess=true;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
*conprocess<<"--edit-key"<<keyID<<"addphoto";
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(addphotoover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(addphotoprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::addphotoover(KProcess *)
|
|
{
|
|
if (addSuccess) emit addPhotoFinished();
|
|
else emit addPhotoError(output);
|
|
}
|
|
|
|
void KgpgInterface::addphotoprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if (required.find("photoid.jpeg.add")!=-1) {
|
|
p->writeStdin(photoUrl);
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("photoid.jpeg.size")!=-1) {
|
|
if (KMessageBox::questionYesNo(0,i18n("This image is very large. Use it anyway?"), QString::null, i18n("Use Anyway"), i18n("Do Not Use"))==KMessageBox::Yes)
|
|
p->writeStdin("Yes");
|
|
else
|
|
{
|
|
p->writeStdin("No");
|
|
p->writeStdin("");
|
|
p->writeStdin("quit");
|
|
}
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString delpass;
|
|
int code=KPasswordDialog::getPassword(delpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
//deleteSuccess=false;
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(delpass,true);
|
|
required=QString::null;
|
|
|
|
}
|
|
|
|
if (required.find("keyedit.prompt")!=-1) {
|
|
p->writeStdin("save");
|
|
required=QString::null;
|
|
}
|
|
|
|
if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
kdDebug(2100)<<"unknown request"<<endl;
|
|
p->writeStdin("quit");
|
|
addSuccess=false;
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// key revocation
|
|
|
|
void KgpgInterface::KgpgRevokeKey(QString keyID,QString revokeUrl,int reason,QString description)
|
|
{
|
|
revokeReason=reason;
|
|
revokeSuccess=false;
|
|
revokeDescription=description;
|
|
certificateUrl=revokeUrl;
|
|
output=QString::null;
|
|
KProcIO *conprocess=new KProcIO(QTextCodec::codecForLocale());
|
|
*conprocess<< "gpg"<<"--no-tty"<<"--status-fd=2"<<"--logger-fd=2"<<"--command-fd=0"<<"--utf8-strings";
|
|
if (!revokeUrl.isEmpty())
|
|
*conprocess<<"-o"<<revokeUrl;
|
|
*conprocess<<"--gen-revoke"<<keyID;
|
|
QObject::connect(conprocess, SIGNAL(processExited(KProcess *)),this, SLOT(revokeover(KProcess *)));
|
|
QObject::connect(conprocess, SIGNAL(readReady(KProcIO *)),this, SLOT(revokeprocess(KProcIO *)));
|
|
conprocess->start(KProcess::NotifyOnExit,true);
|
|
}
|
|
|
|
void KgpgInterface::revokeover(KProcess *)
|
|
{
|
|
if (!revokeSuccess)
|
|
KMessageBox::detailedSorry(0,i18n("Creation of the revocation certificate failed..."),output);
|
|
else {
|
|
output=output.section("-----BEGIN",1);
|
|
output.prepend("-----BEGIN");
|
|
output=output.section("BLOCK-----",0);
|
|
emit revokecertificate(output);
|
|
if (!certificateUrl.isEmpty())
|
|
emit revokeurl(certificateUrl);
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::revokeprocess(KProcIO *p)
|
|
{
|
|
QString required=QString::null;
|
|
while (p->readln(required,true)!=-1) {
|
|
output+=required+"\n";
|
|
|
|
if (required.find("USERID_HINT",0,false)!=-1)
|
|
updateIDs(required);
|
|
|
|
if ((required.find("GOOD_PASSPHRASE")!=-1))
|
|
revokeSuccess=true;
|
|
|
|
if ((required.find("gen_revoke.okay")!=-1) || (required.find("ask_revocation_reason.okay")!=-1) || (required.find("openfile.overwrite.okay")!=-1)) {
|
|
p->writeStdin("YES");
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("ask_revocation_reason.code")!=-1) {
|
|
p->writeStdin(QString::number(revokeReason));
|
|
required=QString::null;
|
|
}
|
|
|
|
if (required.find("passphrase.enter")!=-1) {
|
|
QCString signpass;
|
|
int code=KPasswordDialog::getPassword(signpass,i18n("<qt>Enter passphrase for <b>%1</b>:</qt>").arg(userIDs));
|
|
if (code!=QDialog::Accepted) {
|
|
expSuccess=3; ///// aborted by user mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
return;
|
|
}
|
|
p->writeStdin(signpass,true);
|
|
required=QString::null;
|
|
|
|
}
|
|
if (required.find("ask_revocation_reason.text")!=-1) {
|
|
// kdDebug(2100)<<"description"<<endl;
|
|
p->writeStdin(revokeDescription);
|
|
revokeDescription=QString::null;
|
|
required=QString::null;
|
|
}
|
|
if ((required.find("GET_")!=-1)) /////// gpg asks for something unusal, turn to konsole mode
|
|
{
|
|
kdDebug(2100)<<"unknown request"<<endl;
|
|
expSuccess=1; ///// switching to console mode
|
|
p->writeStdin("quit");
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// parsing of ./gnupg/options file
|
|
|
|
QString KgpgInterface::getGpgSetting(QString name,QString configFile)
|
|
{
|
|
name=name.stripWhiteSpace()+" ";
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
result=result.stripWhiteSpace();
|
|
result.remove(0,name.length());
|
|
result=result.stripWhiteSpace();
|
|
return result.section(" ",0,0);
|
|
}
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
}
|
|
return QString::null;
|
|
}
|
|
|
|
QString KgpgInterface::getGpgMultiSetting(QString name,QString configFile)
|
|
{
|
|
// get GnuPG setting for item that can have multiple entries (eg. encrypt-to)
|
|
|
|
QString parsedResult=QString::null;
|
|
|
|
name=name.stripWhiteSpace()+" ";
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
result=result.stripWhiteSpace();
|
|
result.remove(0,name.length());
|
|
if (parsedResult!=QString::null)
|
|
parsedResult+=" "+result.stripWhiteSpace();
|
|
else
|
|
parsedResult+=result.stripWhiteSpace();
|
|
//return result.section(" ",0,0);
|
|
}
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
}
|
|
return parsedResult;
|
|
}
|
|
|
|
void KgpgInterface::delGpgGroup(QString name, QString configFile)
|
|
{
|
|
QString textToWrite;
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith("group ")) {
|
|
QString result2=result.stripWhiteSpace();
|
|
result2.remove(0,6);
|
|
result2=result2.stripWhiteSpace();
|
|
if (result2.startsWith(name) && (result2.remove(0,name.length()).stripWhiteSpace().startsWith("=")))
|
|
result=QString::null;
|
|
}
|
|
if (result!=QString::null) textToWrite+=result+"\n";
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
if (qfile.open(IO_WriteOnly)) {
|
|
QTextStream t( &qfile);
|
|
t << textToWrite;
|
|
qfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::setGpgGroupSetting(QString name,QStringList values, QString configFile)
|
|
{
|
|
QString textToWrite;
|
|
bool found=false;
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
kdDebug(2100)<<"Changing group: "<<name<<endl;
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith("group ")) {
|
|
QString result2=result.stripWhiteSpace();
|
|
result2.remove(0,6);
|
|
result2=result2.stripWhiteSpace();
|
|
if (result2.startsWith(name) && (result2.remove(0,name.length()).stripWhiteSpace().startsWith("="))) {
|
|
// kdDebug(2100)<<"Found group: "<<name<<endl;
|
|
//kdDebug(2100)<<"New values: "<<values<<endl;
|
|
result=QString("group %1=%2").arg(name).arg(values.join(" "));
|
|
found=true;
|
|
}
|
|
}
|
|
textToWrite+=result+"\n";
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
if (!found)
|
|
textToWrite+="\n"+QString("group %1=%2").arg(name).arg(values.join(" "));
|
|
|
|
if (qfile.open(IO_WriteOnly)) {
|
|
QTextStream t( &qfile);
|
|
t << textToWrite;
|
|
qfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
QStringList KgpgInterface::getGpgGroupSetting(QString name,QString configFile)
|
|
{
|
|
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
result=result.stripWhiteSpace();
|
|
if (result.startsWith("group ")) {
|
|
kdDebug(2100)<<"Found 1 group"<<endl;
|
|
result.remove(0,6);
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
kdDebug(2100)<<"Found group: "<<name<<endl;
|
|
result=result.section('=',1);
|
|
result=result.section('#',0,0);
|
|
return QStringList::split (" ",result);
|
|
}
|
|
}
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
}
|
|
return QString::null;
|
|
}
|
|
|
|
QStringList KgpgInterface::getGpgGroupNames(QString configFile)
|
|
{
|
|
QStringList groups;
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
result=result.stripWhiteSpace();
|
|
if (result.startsWith("group ")) {
|
|
result.remove(0,6);
|
|
groups<<result.section("=",0,0).stripWhiteSpace();
|
|
}
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
}
|
|
return groups;
|
|
}
|
|
|
|
|
|
bool KgpgInterface::getGpgBoolSetting(QString name,QString configFile)
|
|
{
|
|
name=name;
|
|
QFile qfile(QFile::encodeName(configFile));
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
return true;
|
|
}
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void KgpgInterface::setGpgSetting(QString name,QString value,QString url)
|
|
{
|
|
name=name+" ";
|
|
QString textToWrite;
|
|
bool found=false;
|
|
QFile qfile(QFile::encodeName(url));
|
|
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
if (!value.isEmpty())
|
|
result=name+" "+value;
|
|
else
|
|
result=QString::null;
|
|
found=true;
|
|
}
|
|
if (result!=QString::null) textToWrite+=result+"\n";
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
if ((!found) && (!value.isEmpty()))
|
|
textToWrite+="\n"+name+" "+value;
|
|
|
|
if (qfile.open(IO_WriteOnly)) {
|
|
QTextStream t( &qfile);
|
|
t << textToWrite;
|
|
qfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgInterface::setGpgMultiSetting(QString name,QStringList values,QString url)
|
|
{
|
|
name=name+" ";
|
|
QString textToWrite;
|
|
bool found=false;
|
|
QFile qfile(QFile::encodeName(url));
|
|
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (!result.stripWhiteSpace().startsWith(name))
|
|
textToWrite+=result+"\n";
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
|
|
while (!values.isEmpty())
|
|
{
|
|
textToWrite+="\n"+name+" "+values.first();
|
|
values.pop_front();
|
|
}
|
|
|
|
if (qfile.open(IO_WriteOnly)) {
|
|
QTextStream t( &qfile);
|
|
t << textToWrite;
|
|
qfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
void KgpgInterface::setGpgBoolSetting(QString name,bool enable,QString url)
|
|
{
|
|
QString textToWrite;
|
|
bool found=false;
|
|
QFile qfile(QFile::encodeName(url));
|
|
|
|
if (qfile.open(IO_ReadOnly) && (qfile.exists())) {
|
|
QString result;
|
|
QTextStream t( &qfile );
|
|
result=t.readLine();
|
|
while (result!=NULL) {
|
|
if (result.stripWhiteSpace().startsWith(name)) {
|
|
if (enable)
|
|
result=name;
|
|
else
|
|
result=QString::null;
|
|
found=true;
|
|
}
|
|
if (result!=QString::null) textToWrite+=result+"\n";
|
|
result=t.readLine();
|
|
}
|
|
qfile.close();
|
|
if ((!found) && (enable))
|
|
textToWrite+=name;
|
|
|
|
if (qfile.open(IO_WriteOnly)) {
|
|
QTextStream t( &qfile);
|
|
t << textToWrite;
|
|
qfile.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
QString KgpgInterface::checkForUtf8bis(QString txt)
|
|
{
|
|
if (strchr (txt.ascii(), 0xc3) || (txt.find("\\x")!=-1))
|
|
txt=checkForUtf8(txt);
|
|
else {
|
|
txt=checkForUtf8(txt);
|
|
txt=QString::fromUtf8(txt.ascii());
|
|
}
|
|
return txt;
|
|
}
|
|
|
|
|
|
QString KgpgInterface::checkForUtf8(QString txt)
|
|
{
|
|
// code borrowed from gpa
|
|
const char *s;
|
|
|
|
/* Make sure the encoding is UTF-8.
|
|
* Test structure suggested by Werner Koch */
|
|
if (txt.isEmpty())
|
|
return QString::null;
|
|
|
|
for (s = txt.ascii(); *s && !(*s & 0x80); s++)
|
|
;
|
|
if (*s && !strchr (txt.ascii(), 0xc3) && (txt.find("\\x")==-1))
|
|
return txt;
|
|
|
|
/* The string is not in UTF-8 */
|
|
//if (strchr (txt.ascii(), 0xc3)) return (txt+" +++");
|
|
if (txt.find("\\x")==-1)
|
|
return QString::fromUtf8(txt.ascii());
|
|
// if (!strchr (txt.ascii(), 0xc3) || (txt.find("\\x")!=-1)) {
|
|
for ( int idx = 0 ; (idx = txt.find( "\\x", idx )) >= 0 ; ++idx ) {
|
|
char str[2] = "x";
|
|
str[0] = (char) QString( txt.mid( idx + 2, 2 ) ).toShort( 0, 16 );
|
|
txt.replace( idx, 4, str );
|
|
}
|
|
if (!strchr (txt.ascii(), 0xc3))
|
|
return QString::fromUtf8(txt.ascii());
|
|
else
|
|
return QString::fromUtf8(QString::fromUtf8(txt.ascii()).ascii()); // perform Utf8 twice, or some keys display badly
|
|
|
|
return txt;
|
|
}
|
|
|
|
|
|
#include "kgpginterface.moc"
|