PGP 6.x support and a few other PGP related things from Andreas Gungl

svn path=/trunk/kdenetwork/kmail/; revision=39335
wilder-work
Don Sanders 27 years ago
parent d5945b1571
commit 24c803ef04
  1. 104
      kpgp.cpp
  2. 34
      kpgp.h
  3. 199
      kpgpbase.cpp
  4. 20
      kpgpbase.h

@ -66,8 +66,15 @@ Kpgp::init()
else if (haveGpg)
pgp = new KpgpBaseG();
else
pgp = new KpgpBase2();
{
KpgpBase6 *pgp_v6 = new KpgpBase6();
if (!pgp_v6->isVersion6())
{
delete pgp_v6;
pgp = new KpgpBase2();
}
else pgp = pgp_v6;
}
}
else
{
@ -470,7 +477,7 @@ Kpgp::getPublicKey(QString _person)
}
// do the search case insensitive, but return the correct key.
QString adress,str;
QString adress,str,disp_str;
adress = _person.lower();
// first try the canonical mail adress.
@ -478,12 +485,21 @@ Kpgp::getPublicKey(QString _person)
for(str=publicKeys.first(); str!=0; str=publicKeys.next())
if(str.contains(adress)) return str;
// now try the pure input
// now check if the key contains the address
adress = _person.lower();
for(str=publicKeys.first(); str!=0; str=publicKeys.next())
if(str.contains(adress)) return str;
// FIXME: let user set the key/ get from keyserver
// now check if the address contains the key
adress = _person.lower();
for(str=publicKeys.first(); str!=0; str=publicKeys.next())
if(adress.contains(str)) return str;
// no match until now, let the user choose the key:
adress = canonicalAdress(adress);
str= SelectPublicKey(publicKeys, adress);
if (!str.isEmpty()) return str;
return QString::null;
}
@ -729,6 +745,21 @@ Kpgp::canonicalAdress(QString _adress)
}
}
QString
Kpgp::SelectPublicKey(QStrList pbkeys, const char *caption)
{
KpgpSelDlg dlg(pbkeys,caption);
QString txt ="";
if (dlg.exec()==QDialog::Rejected) return 0;
txt = dlg.key();
if (!txt.isEmpty())
{
return txt;
}
return 0;
}
//----------------------------------------------------------------------
// widgets needed by kpgp
@ -932,3 +963,68 @@ KpgpConfig::applySettings()
}
//-----------------------------------------------------------------------------
#define KpgpDlgInherited QDialog
KpgpSelDlg::KpgpSelDlg(QStrList aKeyList, const char *aCap):
KpgpDlgInherited(NULL, aCap, TRUE), mGrid(this, 2, 2),
mListBox(this),
mBtnOk(i18n("OK"),this),
mBtnCancel(i18n("Cancel"),this)
{
const char* key;
QString caption;
caption=i18n("Select public key for recipient \"");
caption += aCap;
caption += i18n("\"");
initMetaObject();
setCaption(aCap ? /*(const char *)*/caption : i18n("PGP Key Selection"));
/*assert(aKeyList != NULL);*/
mKeyList = aKeyList;
mkey = "";
mBtnOk.adjustSize();
mBtnOk.setMinimumSize(mBtnOk.size());
mBtnCancel.adjustSize();
mBtnCancel.setMinimumSize(mBtnCancel.size());
mGrid.addMultiCellWidget(&mListBox, 0, 0, 0, 1);
mGrid.addWidget(&mBtnOk, 1, 0);
mGrid.addWidget(&mBtnCancel, 1, 1);
mGrid.setRowStretch(0,10);
mGrid.setRowStretch(1,0);
mGrid.setColStretch(0,10);
mGrid.setColStretch(1,10);
mGrid.activate();
connect(&mBtnOk, SIGNAL(clicked()), SLOT(slotOk()));
connect(&mListBox, SIGNAL(selected(int)), SLOT(slotOk()));
connect(&mBtnCancel, SIGNAL(clicked()), SLOT(slotCancel()));
for (key=mKeyList.first(); key; key=mKeyList.next())
{
//insert only real keys:
// if (!(QString)key.contains("matching key"))
mListBox.insertItem(key);
}
}
void KpgpSelDlg::slotOk()
{
int idx = mListBox.currentItem();
if (idx>=0) mkey = mListBox.text(idx);
else mkey = "";
accept();
}
void KpgpSelDlg::slotCancel()
{
mkey = "";
reject();
}

@ -2,6 +2,12 @@
* This code is under GPL V2.0
*
* @author Lars Knoll <knoll@mpi-hd.mpg.de>
*
* GNUPG support
* @author "J. Nick Koston" <bdraco@the.system.is.halted.net>
*
* PGP6 and other enhancements
* @author Andreas Gungl <Andreas.Gungl@osp-dd.de>
*/
#ifndef KPGP_H
#define KPGP_H
@ -12,6 +18,9 @@
#include <qdialog.h>
#include <qwidget.h>
#include <qcombobox.h>
#include <qlayout.h>
#include <qpushbt.h>
#include <qlistbox.h>
class QLineEdit;
class QCursor;
@ -153,6 +162,9 @@ private:
// transform an adress into canonical form
QString canonicalAdress(QString _person);
//Select public key from a list of all public keys
QString SelectPublicKey(QStrList pbkeys, const char *caption);
bool checkForPGP(void);
static Kpgp *kpgpObject;
@ -234,5 +246,27 @@ protected:
};
// -------------------------------------------------------------------------
class KpgpSelDlg: public QDialog
{
Q_OBJECT
public:
KpgpSelDlg(QStrList aKeyList, const char *caption=NULL);
virtual ~KpgpSelDlg() {};
virtual const QString key(void) const {return mkey;};
protected slots:
void slotOk();
void slotCancel();
protected:
QGridLayout mGrid;
QListBox mListBox;
QPushButton mBtnOk, mBtnCancel;
QString mkey;
QStrList mKeyList;
};
#endif

@ -893,6 +893,9 @@ KpgpBase2::pubKeys()
status = run(cmd);
if(status == RUN_ERR) return 0;
//truncate trailing "\n"
if (output.length() > 1) output.truncate(output.length()-1);
QStrList publicKeys;
index = output.find("\n",1)+1; // skip first to "\n"
while( (index = output.find("\n",index)) != -1)
@ -1265,3 +1268,199 @@ KpgpBase5::signKey(const char *key, const char *passphrase)
return status;
}
// -------------------------------------------------------------------------
KpgpBase6::KpgpBase6()
: KpgpBase2()
{
}
KpgpBase6::~KpgpBase6()
{
}
int
KpgpBase6::decrypt(const char *passphrase)
{
QString cmd;
int index, index2;
output = "";
cmd = "pgp +batchmode -f";
status = run(cmd, passphrase);
if(status != OK)
{
errMsg = i18n("error running pgp");
return status;
}
// encrypted message
if( info.find("File is encrypted.") != -1)
{
//debug("kpgpbase: message is encrypted");
status |= ENCRYPTED;
if( info.find("Key for user ID") != -1)
{
// Test output length to find out, if the passphrase is
// bad. If someone knows a better way, please fix this.
if (!passphrase || !output.length())
{
errMsg = i18n("Bad pass Phrase; couldn't decrypt");
//debug("KpgpBase: passphrase is bad");
status |= BADPHRASE;
status |= ERROR;
}
}
else if( info.find("Secret key is required to read it.") != -1)
{
errMsg = i18n("Do not have the secret key for this message");
//debug("KpgpBase: no secret key for this message");
status |= NO_SEC_KEY;
status |= ERROR;
}
}
// signed message
if(((index = info.find("File is signed.")) != -1)
|| (info.find("Good signature") != -1 ))
{
//debug("KpgpBase: message is signed");
status |= SIGNED;
if( info.find("signature not checked") != -1)
{
index = info.find("KeyID:",index);
signatureID = info.mid(index+7,8);
signature = i18n("unknown key ID ");
signature += " " +signatureID;
status |= UNKNOWN_SIG;
status |= GOODSIG;
}
else if((index = info.find("Good signature")) != -1 )
{
status |= GOODSIG;
// get signer
index = info.find("\"",index);
index2 = info.find("\"", index+1);
signature = info.mid(index+1, index2-index-1);
// get key ID of signer
index = info.find("KeyID:",index2);
if (index == -1)
signatureID = "???";
else
signatureID = info.mid(index+7,8);
}
else if( info.find("Can't find the right public key") != -1 )
{
status |= UNKNOWN_SIG;
status |= GOODSIG; // this is a hack...
signature = i18n("??? (file ~/.pgp/pubring.pkr not found)");
signatureID = "???";
}
else
{
status |= ERROR;
signature = "";
signatureID = "";
}
}
//debug("status = %d",status);
return status;
}
QStrList
KpgpBase6::pubKeys()
{
QString cmd;
int index, index2;
int compatibleMode = 1;
cmd = "pgp +batchmode -kv -f \"\" ~/.pgp/pubring.pkr";
status = run(cmd);
if(status != OK) return 0;
//truncate trailing "\n"
if (info.length() > 1) info.truncate(info.length()-1);
QStrList publicKeys;
index = info.find("bits/keyID",1); // skip first to "\n"
if (index ==-1)
{
index = info.find("Type bits",1); // skip first to "\n"
if (index == -1)
return 0;
else
compatibleMode = 0;
}
while( (index = info.find("\n",index)) != -1)
{
//parse line
QString line;
if( (index2 = info.find("\n",index+1)) != -1)
// skip last line
{
int index3;
if (compatibleMode)
index3 = info.find("pub ",index);
else
{
int index_rsa = info.find("RSA ",index);
int index_dss = info.find("DSS ",index);
if (index_rsa < 0)
index3 = index_dss;
else if (index_dss < 0)
index3 = index_rsa;
else
index3 = (index_rsa < index_dss ? index_rsa : index_dss);
}
if( (index3 >index2) || (index3 == -1) )
{
// second adress for the same key
line = info.mid(index+1,index2-index-1);
line = line.stripWhiteSpace();
line = line.lower();
} else {
// line with new key
int index4 = info.find(
QRegExp("/[0-9][0-9]/[0-9][0-9] "),
index);
line = info.mid(index4+7,index2-index4-7);
line = line.lower();
}
//debug("KpgpBase: found key for %s",(const char *)line);
publicKeys.append(line);
}
index = index2;
}
return publicKeys;
}
int
KpgpBase6::isVersion6()
{
QString cmd;
QString empty;
cmd = "pgp";
status = run(cmd, empty);
if(status != OK)
{
errMsg = i18n("error running pgp");
return 0;
}
if( info.find("Version 6") != -1)
{
//debug("kpgpbase: pgp version 6.x detected");
return 1;
}
//debug("kpgpbase: not pgp version 6.x");
return 0;
}

@ -2,6 +2,12 @@
* This code is under GPL V2.0
*
* @author Lars Knoll <knoll@mpi-hd.mpg.de>
*
* GNUPG support
* @author "J. Nick Koston" <bdraco@the.system.is.halted.net>
*
* PGP6 and other enhancements
* @author Andreas Gungl <Andreas.Gungl@osp-dd.de>
*/
#ifndef KPGPBASE_H
#define KPGPBASE_H
@ -148,6 +154,20 @@ public:
virtual int signKey(const char *key, const char *passphrase);
};
class KpgpBase6 : public KpgpBase2
{
public:
KpgpBase6();
virtual ~KpgpBase6();
virtual int decrypt(const char *passphrase = 0);
virtual QStrList pubKeys();
virtual int isVersion6();
};
// ---------------------------------------------------------------------------
// inlined functions

Loading…
Cancel
Save