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.
540 lines
18 KiB
540 lines
18 KiB
/***************************************************************************
|
|
keyinfowidget.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 gpgOutpution) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <tdelocale.h>
|
|
#include <kprocess.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqfile.h>
|
|
#include <kprocio.h>
|
|
#include <kpassivepopup.h>
|
|
#include <tdeaction.h>
|
|
#include <tqregexp.h>
|
|
#include <tdetempfile.h>
|
|
#include <tqimage.h>
|
|
#include <kdatepicker.h>
|
|
#include <tqpushbutton.h>
|
|
#include <kcombobox.h>
|
|
#include <tqlabel.h>
|
|
#include <kiconloader.h>
|
|
#include <tqcheckbox.h>
|
|
#include <tqlayout.h>
|
|
#include <kactivelabel.h>
|
|
#include <klineedit.h>
|
|
#include <ktrader.h>
|
|
#include <kservice.h>
|
|
#include <tdemessagebox.h>
|
|
|
|
#include "keyinfowidget.h"
|
|
#include "keyproperties.h"
|
|
#include "kgpgsettings.h"
|
|
#include "kgpginterface.h"
|
|
|
|
KgpgKeyInfo::KgpgKeyInfo(TQWidget *parent, const char *name,TQString sigkey):KDialogBase( Swallow, i18n("Key Properties"), Close, Close, parent, name,true)
|
|
{
|
|
|
|
FILE *pass;
|
|
char line[200]="";
|
|
TQString gpgOutput,fullID;
|
|
hasPhoto=false;
|
|
bool isSecret=false;
|
|
keyWasChanged=false;
|
|
|
|
prop=new KeyProperties();
|
|
setMainWidget(prop);
|
|
TQString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --list-secret-key "+KShellProcess::quote(sigkey);
|
|
pass=popen(TQFile::encodeName(gpgcmd),"r");
|
|
while ( fgets( line, sizeof(line), pass)) {
|
|
gpgOutput=line;
|
|
if (gpgOutput.startsWith("sec")) isSecret=true;
|
|
}
|
|
pclose(pass);
|
|
|
|
if (!isSecret) {
|
|
prop->changeExp->hide();
|
|
prop->changePass->hide();
|
|
}
|
|
loadKey(sigkey);
|
|
|
|
if (hasPhoto) {
|
|
KgpgInterface *photoProcess=new KgpgInterface();
|
|
photoProcess->KgpgGetPhotoList(displayedKeyID);
|
|
connect(photoProcess,TQT_SIGNAL(signalPhotoList(TQStringList)),this,TQT_SLOT(slotSetMainPhoto(TQStringList)));
|
|
}
|
|
else
|
|
prop->comboId->setEnabled(false);
|
|
|
|
connect(prop->changeExp,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotChangeExp()));
|
|
connect(this,TQT_SIGNAL(closeClicked()),this,TQT_SLOT(slotPreOk()));
|
|
connect(prop->changePass,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotChangePass()));
|
|
connect(prop->comboId,TQT_SIGNAL(activated (const TQString &)),this,TQT_SLOT(reloadMainPhoto(const TQString &)));
|
|
connect(prop->cbDisabled,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(slotDisableKey(bool)));
|
|
connect(prop->kCOwnerTrust,TQT_SIGNAL(activated (int)),this,TQT_SLOT(slotChangeTrust(int)));
|
|
connect(this,TQT_SIGNAL(changeMainPhoto(const TQPixmap&)),this,TQT_SLOT(slotSetPhoto(const TQPixmap&)));
|
|
|
|
//prop->setMinimumSize(prop->sizeHint());
|
|
}
|
|
|
|
void KgpgKeyInfo::slotDisableKey(bool isOn)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TDEProcess kp;
|
|
|
|
kp<<"gpg" <<"--no-tty" <<"--edit-key" <<displayedKeyID;
|
|
if (isOn) kp<<"disable";
|
|
else kp<<"enable";
|
|
kp<<"save";
|
|
kp.start(TDEProcess::Block);
|
|
loadKey(displayedKeyID);
|
|
keyWasChanged=true;
|
|
}
|
|
|
|
void KgpgKeyInfo::loadKey(TQString Keyid)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
FILE *pass;
|
|
char line[200]="";
|
|
TQString currentKey;
|
|
TQMap<TQString,TQStringList> hashMap;
|
|
|
|
TQString gpgcmd="gpg --no-tty --no-secmem-warning --with-colon --with-fingerprint --list-key "+KShellProcess::quote(Keyid);
|
|
|
|
pass=popen(TQFile::encodeName(gpgcmd),"r");
|
|
while ( fgets( line, sizeof(line), pass) ) {
|
|
TQString tst=TQString::fromUtf8(line);
|
|
if ( tst.startsWith("pub") ) {
|
|
currentKey = tst.section(':',4,4);
|
|
TQStringList lst; lst << tst;
|
|
hashMap.insert(currentKey,lst);
|
|
}
|
|
else {
|
|
hashMap.find(currentKey).data().append(tst);
|
|
}
|
|
}
|
|
pclose(pass);
|
|
|
|
TQMap<TQString,TQStringList>::Iterator ite;
|
|
for (ite = hashMap.begin(); ite != hashMap.end(); ite++) {
|
|
TQStringList::Iterator it;
|
|
TQString fullname,gpgOutput;
|
|
TQColor trustColor;
|
|
TQString fingervalue=TQString();
|
|
|
|
for (it = ite.data().begin(); it != ite.data().end(); it++) {
|
|
TQString gpgOutput = (*it);
|
|
|
|
if (gpgOutput.startsWith("uat")) {
|
|
hasPhoto=true;
|
|
}
|
|
if ( gpgOutput.startsWith("pub") ) {
|
|
TQString algo=gpgOutput.section(':',3,3);
|
|
switch( algo.toInt() ) {
|
|
case 1:
|
|
algo="RSA";
|
|
break;
|
|
case 16:
|
|
case 20:
|
|
algo="ElGamal";
|
|
break;
|
|
case 17:
|
|
algo="DSA";
|
|
break;
|
|
default:
|
|
algo=TQString("#" + algo);
|
|
break;
|
|
}
|
|
prop->tLAlgo->setText(algo);
|
|
|
|
const TQString trust=gpgOutput.section(':',1,1);
|
|
TQString tr;
|
|
switch( trust[0] ) {
|
|
case 'o':
|
|
tr= i18n("Unknown");
|
|
trustColor=KGpgSettings::colorUnknown();
|
|
break;
|
|
case 'i':
|
|
tr= i18n("Invalid");
|
|
trustColor=KGpgSettings::colorBad();
|
|
break;
|
|
case 'd':
|
|
tr=i18n("Disabled");
|
|
trustColor=KGpgSettings::colorBad();
|
|
prop->cbDisabled->setChecked(true);
|
|
break;
|
|
case 'r':
|
|
tr=i18n("Revoked");
|
|
trustColor=KGpgSettings::colorRev();
|
|
break;
|
|
case 'e':
|
|
tr=i18n("Expired");
|
|
trustColor=KGpgSettings::colorBad();
|
|
break;
|
|
case 'q':
|
|
tr=i18n("Undefined");
|
|
trustColor=KGpgSettings::colorUnknown();
|
|
break;
|
|
case 'n':
|
|
tr=i18n("None");
|
|
trustColor=KGpgSettings::colorUnknown();
|
|
break;
|
|
case 'm':
|
|
tr=i18n("Marginal");
|
|
trustColor=KGpgSettings::colorBad();
|
|
break;
|
|
case 'f':
|
|
tr=i18n("Full");
|
|
trustColor=KGpgSettings::colorGood();
|
|
break;
|
|
case 'u':
|
|
tr=i18n("Ultimate");
|
|
trustColor=KGpgSettings::colorGood();
|
|
break;
|
|
default:
|
|
tr="?";
|
|
trustColor=KGpgSettings::colorUnknown();
|
|
break;
|
|
}
|
|
|
|
if (gpgOutput.section(':',11,11).find("D",0,true)!=-1) // disabled key
|
|
{
|
|
tr=i18n("Disabled");
|
|
trustColor=KGpgSettings::colorBad();
|
|
prop->cbDisabled->setChecked(true);
|
|
}
|
|
|
|
prop->kLTrust->setText(tr);
|
|
prop->pixmapTrust->setPaletteBackgroundColor(trustColor);
|
|
|
|
TQString fullID=gpgOutput.section(':',4,4);
|
|
displayedKeyID=fullID.right(8);
|
|
prop->tLID->setText(fullID);
|
|
|
|
fullname=gpgOutput.section(':',9,9);
|
|
|
|
TQDate date;
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t(gpgOutput.section(':',5,5).toInt());
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(gpgOutput.section(':',5,5), Qt::ISODate);
|
|
}
|
|
Q_ASSERT ( date.isValid())/* tqWarning("create date is not valid")*/;
|
|
|
|
prop->tLCreation->setText(TDEGlobal::locale()->formatDate(date));
|
|
if (gpgOutput.section(':',6,6).isEmpty()) {
|
|
expirationDate=i18n("Unlimited");
|
|
}
|
|
else {
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t(gpgOutput.section(':',6,6).toInt());
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(gpgOutput.section(':',6,6), Qt::ISODate);
|
|
}
|
|
Q_ASSERT (date.isValid()) /* tqWarning("Expirationdate date is not valid")*/;
|
|
expirationDate=TDEGlobal::locale()->formatDate(date);
|
|
}
|
|
prop->tLExpiration->setText(expirationDate);
|
|
|
|
prop->tLLength->setText(gpgOutput.section(':',2,2));
|
|
|
|
const TQString otrust=gpgOutput.section(':',8,8);
|
|
int ownerTrust=0;
|
|
|
|
/* Don't know=1; Do NOT trust=2; Marginally=3; Fully=4; Ultimately=5; */
|
|
|
|
switch( otrust[0] ) {
|
|
case 'f':
|
|
ownerTrust=3;
|
|
break;
|
|
case 'u':
|
|
ownerTrust=4;
|
|
break;
|
|
case 'm':
|
|
ownerTrust=2;
|
|
break;
|
|
case 'n':
|
|
ownerTrust=1;
|
|
break;
|
|
default:
|
|
ownerTrust=0;
|
|
break;
|
|
}
|
|
prop->kCOwnerTrust->setCurrentItem(ownerTrust);
|
|
}
|
|
|
|
if ( gpgOutput.startsWith("uid") && fullname.isEmpty() ) {
|
|
fullname = gpgOutput.section(':',9,9);
|
|
}
|
|
if (gpgOutput.startsWith("fpr") && (fingervalue.isNull())) {
|
|
fingervalue=gpgOutput.section(':',9,9);
|
|
// format fingervalue in 4-digit groups
|
|
uint len = fingervalue.length();
|
|
if ((len > 0) && (len % 4 == 0)) {
|
|
for (uint n = 0; 4*(n+1) < len; n++) {
|
|
fingervalue.insert(5*n+4, ' ');
|
|
}
|
|
}
|
|
prop->lEFinger->setText(fingervalue);
|
|
}
|
|
}
|
|
|
|
if (!fullname.isEmpty()) {
|
|
if (fullname.find("<")!=-1) {
|
|
TQString kmail=fullname;
|
|
if (fullname.find(")")!=-1)
|
|
kmail=kmail.section(')',1);
|
|
kmail=kmail.section('<',1);
|
|
kmail.truncate(kmail.length()-1);
|
|
if (kmail.find("<")!=-1) //////// several email addresses in the same key
|
|
{
|
|
kmail=kmail.replace(">",";");
|
|
kmail.remove("<");
|
|
}
|
|
prop->tLMail->setText("<qt><a href=mailto:"+kmail+">"+kmail+"</a></qt>");
|
|
} else
|
|
prop->tLMail->setText(i18n("none"));
|
|
|
|
TQString kname=fullname.section('<',0,0);
|
|
if (fullname.find("(")!=-1) {
|
|
kname=kname.section('(',0,0);
|
|
TQString comment=fullname.section('(',1,1);
|
|
comment=comment.section(')',0,0);
|
|
prop->tLComment->setText(KgpgInterface::checkForUtf8(comment));
|
|
} else
|
|
prop->tLComment->setText(i18n("none"));
|
|
|
|
prop->tLName->setText("<qt><b>"+KgpgInterface::checkForUtf8(kname).replace(TQRegExp("<"),"<")+"</b></qt>");
|
|
}
|
|
}
|
|
}
|
|
|
|
void KgpgKeyInfo::slotSetMainPhoto(TQStringList list)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
prop->comboId->insertStringList(list);
|
|
reloadMainPhoto(prop->comboId->currentText());
|
|
}
|
|
|
|
void KgpgKeyInfo::reloadMainPhoto(const TQString &uid)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
|
|
kgpginfotmp=new KTempFile();
|
|
kgpginfotmp->setAutoDelete(true);
|
|
TQString pgpgOutput="cp %i "+kgpginfotmp->name();
|
|
KProcIO *p=new KProcIO();
|
|
*p<<"gpg"<<"--no-tty"<<"--show-photos"<<"--photo-viewer"<<TQString(TQFile::encodeName(pgpgOutput));
|
|
*p<<"--edit-key"<<displayedKeyID<<"uid"<<uid<<"showphoto";
|
|
TQObject::connect(p, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(finishphotoreadprocess(KProcIO *)));
|
|
TQObject::connect(p, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotMainImageRead(TDEProcess *)));
|
|
p->start(TDEProcess::NotifyOnExit,true);
|
|
|
|
}
|
|
|
|
|
|
void KgpgKeyInfo::slotMainImageRead(TDEProcess *p)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
p->deleteLater();
|
|
TQPixmap pixmap;
|
|
pixmap.load(kgpginfotmp->name());
|
|
emit changeMainPhoto(pixmap);
|
|
kgpginfotmp->unlink();
|
|
}
|
|
|
|
|
|
KgpgKeyInfo::~KgpgKeyInfo()
|
|
{
|
|
}
|
|
|
|
void KgpgKeyInfo::slotSetPhoto(const TQPixmap &pix)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQImage dup=pix.convertToImage();
|
|
TQPixmap dup2;
|
|
dup2.convertFromImage(dup.scale(prop->pLPhoto->width(),prop->pLPhoto->height(),TQ_ScaleMin));
|
|
prop->pLPhoto->setPixmap(dup2);
|
|
}
|
|
|
|
|
|
|
|
|
|
void KgpgKeyInfo::finishphotoreadprocess(KProcIO *p)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQString required=TQString();
|
|
while (p->readln(required,true)!=-1)
|
|
if (required.find("keyedit.prompt")!=-1) {
|
|
p->writeStdin(TQString("quit"));
|
|
p->closeWhenDone();
|
|
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgKeyInfo::openPhoto()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TDETrader::OfferList offers = TDETrader::self()->query("image/jpeg", "Type == 'Application'");
|
|
KService::Ptr ptr = offers.first();
|
|
//KMessageBox::sorry(0,ptr->desktopEntryName());
|
|
KProcIO *p=new KProcIO();
|
|
*p<<"gpg"<<"--show-photos"<<"--photo-viewer"<<TQString(TQFile::encodeName(ptr->desktopEntryName()+" %i"))<<"--list-keys"<<displayedKeyID;
|
|
p->start(TDEProcess::DontCare,true);
|
|
}
|
|
|
|
void KgpgKeyInfo::slotChangeExp()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
chdate=new KDialogBase( this, "choose_date", true,i18n("Choose New Expiration"),KDialogBase::Ok | KDialogBase::Cancel);
|
|
TQWidget *page = new TQWidget(chdate);
|
|
kb= new TQCheckBox(i18n("Unlimited"),page );
|
|
|
|
if (prop->tLExpiration->text()==i18n("Unlimited")) {
|
|
kdt= new KDatePicker( page );
|
|
kb->setChecked(true);
|
|
kdt->setEnabled(false);
|
|
}
|
|
else {
|
|
kdt= new KDatePicker(page,TDEGlobal::locale()->readDate(prop->tLExpiration->text()));
|
|
}
|
|
TQVBoxLayout *vbox=new TQVBoxLayout(page,3);
|
|
vbox->addWidget(kdt);
|
|
vbox->addWidget(kb);
|
|
connect(kb,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(slotEnableDate(bool)));
|
|
connect(chdate,TQT_SIGNAL(okClicked()),this,TQT_SLOT(slotChangeDate()));
|
|
connect(kdt,TQT_SIGNAL(dateChanged(TQDate)),this,TQT_SLOT(slotCheckDate(TQDate)));
|
|
connect(kdt,TQT_SIGNAL(dateEntered(TQDate)),this,TQT_SLOT(slotCheckDate(TQDate)));
|
|
|
|
chdate->setMainWidget(page);
|
|
chdate->show();
|
|
}
|
|
|
|
void KgpgKeyInfo::slotCheckDate(TQDate date)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
// kdDebug(2100) << "slotCheckDate" << date<<endl;
|
|
chdate->enableButtonOK(date>=TQDate::currentDate ());
|
|
}
|
|
|
|
void KgpgKeyInfo::slotChangeDate()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
KgpgInterface *KeyExpirationProcess=new KgpgInterface();
|
|
// kdDebug(2100) << "slotChangeDate" << kdt->date()<<endl;
|
|
if (kb->isChecked()) {
|
|
KeyExpirationProcess->KgpgKeyExpire(displayedKeyID,TQDate::currentDate(),true);
|
|
}
|
|
else {
|
|
KeyExpirationProcess->KgpgKeyExpire(displayedKeyID,kdt->date(),false);
|
|
}
|
|
connect(KeyExpirationProcess,TQT_SIGNAL(expirationFinished(int)),this,TQT_SLOT(slotInfoExpirationChanged(int)));
|
|
}
|
|
|
|
void KgpgKeyInfo::slotEnableDate(bool isOn)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (isOn) {
|
|
kdt->setEnabled(false);
|
|
chdate->enableButtonOK(true);
|
|
}
|
|
else {
|
|
kdt->setEnabled(true);
|
|
//kdDebug(2100) << "slotEnableDate" << kdt->date()<<endl;
|
|
chdate->enableButtonOK(kdt->date()>=TQDate::currentDate ());
|
|
}
|
|
}
|
|
|
|
void KgpgKeyInfo::slotinfoimgread(TDEProcess *)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQPixmap pixmap;
|
|
pixmap.load(kgpginfotmp->name());
|
|
emit signalPhotoId(pixmap);
|
|
kgpginfotmp->unlink();
|
|
}
|
|
|
|
void KgpgKeyInfo::slotChangePass()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
KgpgInterface *ChangeKeyPassProcess=new KgpgInterface();
|
|
ChangeKeyPassProcess->KgpgChangePass(displayedKeyID);
|
|
connect(ChangeKeyPassProcess,TQT_SIGNAL(passwordChanged()),this,TQT_SLOT(slotInfoPasswordChanged()));
|
|
}
|
|
|
|
void KgpgKeyInfo::slotChangeTrust(int newTrust)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
KgpgInterface *KeyTrustProcess=new KgpgInterface();
|
|
KeyTrustProcess->KgpgTrustExpire(displayedKeyID,newTrust);
|
|
connect(KeyTrustProcess,TQT_SIGNAL(trustfinished()),this,TQT_SLOT(slotInfoTrustChanged()));
|
|
}
|
|
|
|
|
|
void KgpgKeyInfo::slotInfoPasswordChanged()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
KPassivePopup::message(i18n("Passphrase for the key was changed"),TQString(),TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop),this);
|
|
}
|
|
|
|
void KgpgKeyInfo::slotInfoTrustChanged()
|
|
{
|
|
keyWasChanged=true;
|
|
loadKey(displayedKeyID);
|
|
//KPassivePopup::message(i18n("Owner trust of the key was changed"),TQString(),TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop),this,0,600);
|
|
}
|
|
|
|
void KgpgKeyInfo::slotInfoExpirationChanged(int res)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQString infoMessage,infoText;
|
|
if (res==3) {
|
|
keyWasChanged=true;
|
|
if (kb->isChecked()) {
|
|
prop->tLExpiration->setText(i18n("Unlimited"));
|
|
}
|
|
else {
|
|
prop->tLExpiration->setText(TDEGlobal::locale()->formatDate(kdt->date()));
|
|
}
|
|
}
|
|
if (res==2) {
|
|
infoMessage=i18n("Could not change expiration");
|
|
infoText=i18n("Bad passphrase");
|
|
KPassivePopup::message(infoMessage,infoText,TDEGlobal::iconLoader()->loadIcon("kgpg",TDEIcon::Desktop),this);
|
|
}
|
|
}
|
|
|
|
|
|
void KgpgKeyInfo::slotPreOk()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (keyWasChanged) {
|
|
emit keyNeedsRefresh();
|
|
}
|
|
accept();
|
|
}
|
|
|
|
#include "keyinfowidget.moc"
|