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.
870 lines
30 KiB
870 lines
30 KiB
/***************************************************************************
|
|
keyservers.cpp - description
|
|
-------------------
|
|
begin : Tue Nov 26 2002
|
|
copyright : (C) 2002 by Jean-Baptiste Mardelle
|
|
email : bj@altern.org
|
|
|
|
updated to handle gpg21 : Sun Jul 30 10:18:29 CEST 2017
|
|
copyright : (C) 2017 by Emanoil Kotsev
|
|
email : deloptes@yahoo.com
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <tqfile.h>
|
|
#include <tqcheckbox.h>
|
|
#include <tdeapplication.h>
|
|
#include <kiconloader.h>
|
|
#include <kcombobox.h>
|
|
#include <kdialogbase.h>
|
|
#include <tdemessagebox.h>
|
|
#include <tqtextcodec.h>
|
|
#include <tqlayout.h>
|
|
#include <tqlabel.h>
|
|
#include <tqdialog.h>
|
|
#include <tqpushbutton.h>
|
|
#include <tqbuttongroup.h>
|
|
#include <tqhbuttongroup.h>
|
|
#include <tqvbuttongroup.h>
|
|
#include <tqregexp.h>
|
|
#include <tqcursor.h>
|
|
|
|
#include <tdelocale.h>
|
|
#include <kprocess.h>
|
|
#include <kprocio.h>
|
|
#include <tdelistview.h>
|
|
#include <kstatusbar.h>
|
|
#include <tdeconfig.h>
|
|
#include <klineedit.h>
|
|
#include <ksimpleconfig.h>
|
|
#include <tdeaction.h>
|
|
#include <kdebug.h>
|
|
|
|
|
|
#include "kgpgsettings.h"
|
|
#include "searchres.h"
|
|
#include "detailedconsole.h"
|
|
#include "keyservers.h"
|
|
|
|
keyServer::keyServer(TQWidget *parent, const char *name,bool modal,bool autoClose):KDialogBase( Swallow, i18n("Key Server"), Close, Close, parent, name,modal)
|
|
{
|
|
autoCloseWindow=autoClose;
|
|
config=new KSimpleConfig ("kgpgrc");
|
|
page=new keyServerWidget();
|
|
setMainWidget(page);
|
|
|
|
syncCombobox();
|
|
page->kLEimportid->setFocus();
|
|
currentKey = TQString();
|
|
hashMap.clear();
|
|
|
|
connect(page->Buttonimport,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotImport()));
|
|
connect(page->Buttonsearch,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotSearch()));
|
|
connect(page->Buttonexport,TQT_SIGNAL(clicked()),this,TQT_SLOT(slotPreExport()));
|
|
connect(this,TQT_SIGNAL(okClicked()),this,TQT_SLOT(slotOk()));
|
|
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
connect(page->cBproxyI,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(slotEnableProxyI(bool)));
|
|
connect(page->cBproxyE,TQT_SIGNAL(toggled(bool)),this,TQT_SLOT(slotEnableProxyE(bool)));
|
|
}
|
|
|
|
connect(page->kLEimportid, TQT_SIGNAL( textChanged ( const TQString & )), this, TQT_SLOT( slotTextChanged( const TQString &)));
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
page->cBproxyI->setChecked(KGpgSettings::useProxy());
|
|
page->cBproxyE->setChecked(KGpgSettings::useProxy());
|
|
const char *httpproxy = getenv("http_proxy");
|
|
if (httpproxy) {
|
|
page->cBproxyI->setEnabled(true);
|
|
page->cBproxyE->setEnabled(true);
|
|
page->kLEproxyI->setText(httpproxy);
|
|
page->kLEproxyE->setText(httpproxy);
|
|
}
|
|
}
|
|
|
|
KProcIO *encid=new KProcIO(TQTextCodec::codecForLocale());
|
|
*encid << "gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--with-colon"<<"--list-keys";
|
|
TQObject::connect(encid, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotprocresult(TDEProcess *)));
|
|
TQObject::connect(encid, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotprocread(KProcIO *)));
|
|
encid->start(TDEProcess::NotifyOnExit,true);
|
|
page->Buttonimport->setEnabled( !page->kLEimportid->text().isEmpty());
|
|
page->Buttonsearch->setEnabled( !page->kLEimportid->text().isEmpty());
|
|
setMinimumSize(sizeHint());
|
|
}
|
|
|
|
|
|
keyServer::~keyServer()
|
|
{}
|
|
|
|
|
|
void keyServer::slotTextChanged( const TQString &text)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
page->Buttonimport->setEnabled( !text.isEmpty());
|
|
page->Buttonsearch->setEnabled( !text.isEmpty());
|
|
|
|
}
|
|
void keyServer::slotEnableProxyI(bool on)
|
|
{
|
|
page->kLEproxyI->setEnabled(on);
|
|
}
|
|
|
|
void keyServer::slotEnableProxyE(bool on)
|
|
{
|
|
page->kLEproxyE->setEnabled(on);
|
|
}
|
|
|
|
void keyServer::slotprocread(KProcIO *p)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
///////////////////////////////////////////////////////////////// extract encryption keys
|
|
TQString tst;
|
|
//TQPixmap pixkeySingle(TDEGlobal::iconLoader()->loadIcon("kgpg_key1",TDEIcon::Small,20));
|
|
while (p->readln(tst)!=-1) {
|
|
// kdDebug(2100) << k_funcinfo << "Read one public key line: " << tst << endl;
|
|
if ( tst.startsWith("pub") ) {
|
|
currentKey = tst.section(':',4,4).right(8);
|
|
TQStringList lst; lst << tst;
|
|
hashMap.insert(currentKey,tst);
|
|
}
|
|
else {
|
|
hashMap.find(currentKey).data().append(tst);
|
|
}
|
|
}
|
|
}
|
|
|
|
void keyServer::slotprocresult(TDEProcess *) {
|
|
|
|
TQMap<TQString,TQString> hashImportList;
|
|
|
|
TQMap<TQString,TQStringList>::Iterator ite;
|
|
for (ite = hashMap.begin(); ite != hashMap.end(); ite++) {
|
|
TQString fullname,id;
|
|
bool dead;
|
|
|
|
for (TQStringList::Iterator it = ite.data().begin(); it != ite.data().end(); it++) {
|
|
TQString line = (*it);
|
|
// kdDebug(2100) << k_funcinfo << "Export line: " <<line<< endl;
|
|
if (line.startsWith("pub")) {
|
|
const TQString trust=line.section(':',1,1);
|
|
switch( trust[0] ) {
|
|
case 'i':
|
|
dead=true;
|
|
break;
|
|
case 'd':
|
|
dead=true;
|
|
break;
|
|
case 'r':
|
|
dead=true;
|
|
break;
|
|
case 'e':
|
|
dead=true;
|
|
break;
|
|
default:
|
|
dead=false;
|
|
break;
|
|
}
|
|
fullname = line.section(':',9,9);
|
|
id = "0x"+line.section(':',4,4).right(8);
|
|
}
|
|
if ( line.startsWith("uid") && fullname.isEmpty() ) {
|
|
fullname = line.section(':',9,9);
|
|
}
|
|
}
|
|
// if (fullname.length()>35) {
|
|
// fullname.remove(35,fullname.length());
|
|
// fullname+="...";
|
|
// }
|
|
|
|
TQString tst;
|
|
if (fullname.find("<",0)!=-1) {
|
|
tst=fullname.section('<',0,0);
|
|
}
|
|
|
|
if (!tst.isEmpty()) {
|
|
fullname = tst;
|
|
}
|
|
|
|
if ((!dead) && (!fullname.isEmpty())) {
|
|
if ( hashImportList.find(id) == hashImportList.end() ) {
|
|
hashImportList.insert(fullname,id);
|
|
}
|
|
}
|
|
}
|
|
|
|
for (TQMap<TQString,TQString>::Iterator ite = hashImportList.begin(); ite != hashImportList.end() ; ite++) {
|
|
// page->kCBexportkey->insertItem(pixkeySingle,id+": "+tst);
|
|
page->kCBexportkey->insertItem(ite.data()+": "+ite.key());
|
|
}
|
|
|
|
}
|
|
|
|
void keyServer::slotSearch()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (page->kCBimportks->currentText().isEmpty())
|
|
return;
|
|
|
|
if (page->kLEimportid->text().isEmpty()) {
|
|
KMessageBox::sorry(this,i18n("You must enter a search string."));
|
|
return;
|
|
}
|
|
|
|
currentKey = TQString();
|
|
//listpop = new KeyServer( this,"result",WType_Dialog | WShowModal);
|
|
hashMap.clear();
|
|
invalidKeys.clear();
|
|
keyNumbers=0;
|
|
count=0;
|
|
readmessage=TQString();
|
|
|
|
dialogServer=new KDialogBase(KDialogBase::Swallow, i18n("Import Key From Keyserver"), KDialogBase::Ok | KDialogBase::Close,KDialogBase::Ok,this,0,true);
|
|
|
|
dialogServer->setButtonText(KDialogBase::Ok,i18n("&Import"));
|
|
dialogServer->enableButtonOK(false);
|
|
listpop=new searchRes();
|
|
listpop->kLVsearch->setColumnWidthMode(0,TQListView::Manual);
|
|
listpop->kLVsearch->setColumnWidthMode(1,TQListView::Manual);
|
|
listpop->kLVsearch->setColumnWidth(0,150);
|
|
listpop->kLVsearch->setColumnWidth(1,130);
|
|
listpop->statusText->setText(i18n("Connecting to the server..."));
|
|
connect(listpop->kLVsearch,TQT_SIGNAL(selectionChanged()),this,TQT_SLOT(transferKeyID()));
|
|
connect(dialogServer,TQT_SIGNAL(okClicked()),this,TQT_SLOT(preimport()));
|
|
connect(listpop->kLVsearch,TQT_SIGNAL(doubleClicked(TQListViewItem *,const TQPoint &,int)),dialogServer,TQT_SIGNAL(okClicked()));
|
|
|
|
connect(dialogServer,TQT_SIGNAL(closeClicked()),this,TQT_SLOT(handleQuit()));
|
|
connect( listpop , TQT_SIGNAL( destroyed() ) , this, TQT_SLOT( abortSearch()));
|
|
|
|
searchproc=new KProcIO(TQTextCodec::codecForLocale());
|
|
TQString keyserv=page->kCBimportks->currentText();
|
|
|
|
*searchproc<<"gpg"<<"--utf8-strings"/*<<"--no-tty"*/;
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
if (page->cBproxyI->isChecked()) {
|
|
searchproc->setEnvironment("http_proxy",page->kLEproxyI->text());
|
|
*searchproc<< "--keyserver-options"<<"honor-http-proxy";
|
|
}
|
|
else {
|
|
*searchproc<< "--keyserver-options"<<"no-honor-http-proxy";
|
|
}
|
|
}
|
|
*searchproc<<"--keyserver"<<keyserv<<"--command-fd=0"<<"--with-colon";
|
|
*searchproc<<"--status-fd=2"<<"--search-keys"<<page->kLEimportid->text().stripWhiteSpace();
|
|
|
|
keyNumbers=0;
|
|
TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
|
|
TQObject::connect(searchproc, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotsearchresult(TDEProcess *)));
|
|
TQObject::connect(searchproc, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotsearchread(KProcIO *)));
|
|
searchproc->setUsePty(TDEProcess::Stdout,false); // EKO: very important line - it took me a day to find out why I should use it
|
|
searchproc->start(TDEProcess::NotifyOnExit,true);
|
|
|
|
dialogServer->setMainWidget(listpop);
|
|
listpop->setMinimumSize(listpop->sizeHint());
|
|
listpop->setMinimumWidth(550);
|
|
dialogServer->exec();
|
|
}
|
|
|
|
void keyServer::handleQuit()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (searchproc->isRunning())
|
|
{
|
|
TQApplication::restoreOverrideCursor();
|
|
searchproc->closePty();
|
|
disconnect(searchproc,0,0,0);
|
|
searchproc->kill();
|
|
}
|
|
dialogServer->close();
|
|
}
|
|
|
|
|
|
void keyServer::abortSearch()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (dialogServer) {
|
|
delete dialogServer;
|
|
dialogServer=0L;
|
|
}
|
|
}
|
|
|
|
void keyServer::preimport()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
transferKeyID();
|
|
if (listpop->kLEID->text().isEmpty()) {
|
|
KMessageBox::sorry(this,i18n("You must choose a key."));
|
|
return;
|
|
}
|
|
page->kLEimportid->setText(listpop->kLEID->text());
|
|
dialogServer->close();
|
|
slotImport();
|
|
}
|
|
|
|
void keyServer::transferKeyID()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (!listpop->kLVsearch->firstChild())
|
|
return;
|
|
TQString kid,keysToSearch;
|
|
listpop->kLEID->clear();
|
|
TQPtrList< TQListViewItem >searchList=listpop->kLVsearch->selectedItems();
|
|
|
|
for ( uint i = 0; i < searchList.count(); ++i )
|
|
{
|
|
if ( searchList.at(i) )
|
|
keysToSearch.append(" "+searchList.at(i)->text(3));
|
|
}
|
|
// kdDebug(2100)<<keysToSearch<<endl;
|
|
listpop->kLEID->setText(keysToSearch.stripWhiteSpace());
|
|
}
|
|
|
|
void keyServer::slotsearchread(KProcIO *p)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQString required = TQString();
|
|
|
|
while (p->readln(required,true)!=-1) {
|
|
// kdDebug(2100) << "\tRead one search key line: " << required << endl;
|
|
if (required.find("keysearch.prompt")!=-1) {
|
|
p->setComm(TDEProcess::Stdin);
|
|
if (KgpgInterface::getGpgVersion() < 210) {
|
|
if (count != 1) {
|
|
p->writeStdin(TQString("N"));
|
|
}
|
|
else {
|
|
p->writeStdin(TQString("Q"));
|
|
p->closeWhenDone();
|
|
}
|
|
}
|
|
else {
|
|
p->writeStdin(TQString("N")); // in 2.1 pressing N ends the session if output is empty
|
|
// if (count == 1)
|
|
// p->closeWhenDone();
|
|
}
|
|
p->setComm(TDEProcess::Stdout);
|
|
required = TQString();
|
|
continue;
|
|
}
|
|
if ( required.isEmpty() ) {
|
|
continue;
|
|
}
|
|
if ( required.find("GOT_IT")!=-1 ) {
|
|
required = TQString();
|
|
continue;
|
|
}
|
|
|
|
if ( required.startsWith("info") ) {
|
|
count = required.section(':',2,2).toInt();
|
|
required = TQString();
|
|
continue;
|
|
}
|
|
if ( required.startsWith("pub") ) {
|
|
currentKey = required.section(':',1,1).right(8);
|
|
if ( hashMap.find(currentKey) == hashMap.end() ) {
|
|
TQStringList lst; lst.append(required.simplifyWhiteSpace());
|
|
hashMap.insert(currentKey,lst);
|
|
count--;
|
|
}
|
|
else {
|
|
hashMap.find(currentKey).data().append(required.simplifyWhiteSpace());
|
|
}
|
|
required = TQString();
|
|
}
|
|
else {
|
|
hashMap.find(currentKey).data().append(required.simplifyWhiteSpace());
|
|
required = TQString();
|
|
}
|
|
}
|
|
}
|
|
|
|
void keyServer::slotsearchresult(TDEProcess *)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQString nb;
|
|
|
|
// check if key is valid
|
|
for (TQMap<TQString,TQStringList>::Iterator ite = hashMap.begin(); ite != hashMap.end() ; ite++) {
|
|
TQStringList::Iterator it;
|
|
bool skip=false;
|
|
// this is to prevent offering to import expired or revoked keys
|
|
// first find out if key is revoked or expired
|
|
for (it = ite.data().begin(); it != ite.data().end(); it++ ) {
|
|
TQStringList keyString=TQStringList::split(":",(*it),true);
|
|
// kdDebug(2100) << k_funcinfo << "Key line: " << (*it) << endl;
|
|
if (keyString[0] == "pub") {
|
|
if (! keyString[6].isEmpty() ) {
|
|
if (keyString[6] == "r") {
|
|
skip = true;
|
|
}
|
|
}
|
|
if (! keyString[5].isEmpty() ) { // expiration date
|
|
TQDate date;
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t( keyString[5].toInt() );
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(keyString[5], Qt::ISODate);
|
|
}
|
|
Q_ASSERT (date.isValid()) /*tqWarning("create date is not valid")*/;
|
|
if (date < TQDate::currentDate() ) {
|
|
skip = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (skip) {
|
|
invalidKeys<<ite.key();
|
|
}
|
|
}
|
|
|
|
for (TQMap<TQString,TQStringList>::Iterator ite = hashMap.begin(); ite != hashMap.end() ; ite++) {
|
|
if (invalidKeys.find(ite.key()) != invalidKeys.end() ) {
|
|
continue;
|
|
}
|
|
// very good our keys is neither revoken nor expired - we can offer it for download
|
|
for (TQStringList::Iterator it = ite.data().begin(); it != ite.data().end(); it++ ) {
|
|
TQStringList keyString=TQStringList::split(":",(*it),true);
|
|
// kdDebug(2100) << k_funcinfo << "Processing key line: " << (*it) << endl;
|
|
TQString created;
|
|
if (keyString[0] == "pub") {
|
|
if (! keyString[4].isEmpty() ) {
|
|
TQDate date;
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t( keyString[4].toInt() );
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(keyString[4], Qt::ISODate);
|
|
}
|
|
created=TDEGlobal::locale()->formatDate(date, true);
|
|
}
|
|
kitem=new TDEListViewItem(listpop->kLVsearch,TQString(),TQString(), created, keyString[1]);
|
|
keyNumbers++;
|
|
}
|
|
if (keyString[0] == "uid") {
|
|
TQString keymail,keyname;
|
|
if (! keyString[2].isEmpty() ) {
|
|
TQDate date;
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t( keyString[2].toInt() );
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(keyString[2], Qt::ISODate);
|
|
}
|
|
created=TDEGlobal::locale()->formatDate(date, true);
|
|
}
|
|
if (keyString[1].find("<")!=-1) {
|
|
keymail=keyString[1].section('<',-1,-1);
|
|
if (keymail.endsWith(">")) {
|
|
keymail.truncate(keymail.length()-1);
|
|
}
|
|
keyname=keyString[1].section('<',0,0);
|
|
}
|
|
else {
|
|
keymail=TQString();
|
|
keyname=keyString[1];
|
|
}
|
|
if (kitem != 0 ) {
|
|
kitem->setText(0,keyname);
|
|
//if ( kitem->getText(1).isEmpty() ) kitem->setText(1,keymail);
|
|
TDEListViewItem *subk = new TDEListViewItem(kitem,keyname,keymail,created,TQString());
|
|
subk->setSelectable(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
dialogServer->enableButtonOK(true);
|
|
TQApplication::restoreOverrideCursor();
|
|
nb=nb.setNum(keyNumbers);
|
|
//listpop->kLVsearch->setColumnText(0,i18n("Found %1 matching keys").arg(nb));
|
|
listpop->statusText->setText(i18n("Found %1 matching keys").arg(nb));
|
|
|
|
if (listpop->kLVsearch->firstChild()!=NULL) {
|
|
listpop->kLVsearch->setSelected(listpop->kLVsearch->firstChild(),true);
|
|
listpop->kLVsearch->setCurrentItem(listpop->kLVsearch->firstChild());
|
|
transferKeyID();
|
|
}
|
|
}
|
|
|
|
void keyServer::slotPreExport()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
slotExport(TQStringList(page->kCBexportkey->currentText().section(':', 0, 0)));
|
|
}
|
|
|
|
void keyServer::slotExport(TQStringList keyIds)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (page->kCBexportks->currentText().isEmpty())
|
|
return;
|
|
readmessage=TQString();
|
|
hashMap.clear();
|
|
exportproc=new KProcIO(TQTextCodec::codecForLocale());
|
|
TQString keyserv=page->kCBexportks->currentText();
|
|
|
|
*exportproc<<"gpg"<<"--utf8-strings";
|
|
if (!page->exportAttributes->isChecked()) {
|
|
*exportproc<<"--export-options"<<"no-include-attributes";
|
|
}
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
if (page->cBproxyE->isChecked()) {
|
|
exportproc->setEnvironment("http_proxy",page->kLEproxyE->text());
|
|
*exportproc<< "--keyserver-options"<<"honor-http-proxy";
|
|
}
|
|
else {
|
|
*exportproc<< "--keyserver-options"<<"no-honor-http-proxy";
|
|
}
|
|
}
|
|
*exportproc << "--status-fd=2" << "--keyserver" << keyserv << "--send-keys" << keyIds;
|
|
|
|
TQObject::connect(exportproc, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotexportresult(TDEProcess *)));
|
|
TQObject::connect(exportproc, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotimportread(KProcIO *)));
|
|
exportproc->start(TDEProcess::NotifyOnExit,true);
|
|
TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
|
|
importpop = new TQDialog( this,0,true,TQt::WDestructiveClose);
|
|
TQVBoxLayout *vbox=new TQVBoxLayout(importpop,3);
|
|
TQLabel *tex=new TQLabel(importpop);
|
|
tex->setText(i18n("<b>Connecting to the server...</b>"));
|
|
TQPushButton *Buttonabort=new TQPushButton(i18n("&Abort"),importpop);
|
|
vbox->addWidget(tex);
|
|
vbox->addWidget(Buttonabort);
|
|
importpop->setMinimumWidth(250);
|
|
importpop->adjustSize();
|
|
importpop->show();
|
|
connect(importpop,TQT_SIGNAL(destroyed ()),this,TQT_SLOT(abortExport()));
|
|
connect(Buttonabort,TQT_SIGNAL(clicked ()),importpop,TQT_SLOT(close()));
|
|
}
|
|
|
|
void keyServer::abortExport()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQApplication::restoreOverrideCursor();
|
|
if (exportproc->isRunning())
|
|
{
|
|
disconnect(exportproc,0,0,0);
|
|
exportproc->kill();
|
|
}
|
|
}
|
|
|
|
void keyServer::slotexportresult(TDEProcess*)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQApplication::restoreOverrideCursor();
|
|
KMessageBox::information(0,readmessage);
|
|
if (importpop)
|
|
delete importpop;
|
|
}
|
|
|
|
void keyServer::slotImport()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
if (page->kCBimportks->currentText().isEmpty())
|
|
return;
|
|
if (page->kLEimportid->text().isEmpty()) {
|
|
KMessageBox::sorry(this,i18n("You must select a valid key for import"));
|
|
return;
|
|
}
|
|
|
|
// kdDebug(2100) << k_funcinfo << "Asked for import: " <<page->kLEimportid->text() <<endl;
|
|
|
|
readmessage=TQString();
|
|
count=0;
|
|
hashMap.clear();
|
|
invalidKeys.clear();
|
|
keysToImport.clear();
|
|
TQString keyserv=page->kCBimportks->currentText();
|
|
/*
|
|
*
|
|
* This function is called from search and from signature import
|
|
* so we need to make sure we have a valid keys for import
|
|
* When import is triggered from the search key dialog, we alread have the full ids
|
|
* When import is triggered from the signature import popup, we have names, but only
|
|
* if single signature is select we can import from the server
|
|
*
|
|
* search the keys first and pass the full pub key ids to the importproc
|
|
* to prevent importing pub keys for revocation and normal pub keys together
|
|
* we check to see if key is marked as revoc and look for another key that would
|
|
* be associated with the revoking one, so we skip both key and everything that
|
|
* belongs to this public key
|
|
*
|
|
* we also check the expiration date and refuse to import expired keys
|
|
*
|
|
*/
|
|
|
|
TQString keyNames=page->kLEimportid->text();
|
|
keyNames=keyNames.stripWhiteSpace();
|
|
keyNames=keyNames.simplifyWhiteSpace();
|
|
|
|
if ( keyNames.startsWith("0x") ) {
|
|
searchproc=new KProcIO(TQTextCodec::codecForLocale());
|
|
*searchproc << "gpg"<<"--utf8-strings"<<"--no-secmem-warning";
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
if (page->cBproxyI->isChecked()) {
|
|
searchproc->setEnvironment("http_proxy",page->kLEproxyI->text());
|
|
*searchproc << "--keyserver-options"<<"honor-http-proxy";
|
|
}
|
|
else {
|
|
*searchproc << "--keyserver-options"<<"no-honor-http-proxy";
|
|
}
|
|
}
|
|
*searchproc << "--keyserver" << keyserv << "--status-fd=2" /*<<"--debug-level"<<"guru"*/;
|
|
*searchproc << "--command-fd=0" << "--with-colon" << "--search-keys";
|
|
|
|
while (!keyNames.isEmpty()) {
|
|
TQString fkeyNames=keyNames.section(' ',0,0);
|
|
keyNames.remove(0,fkeyNames.length());
|
|
keyNames=keyNames.stripWhiteSpace();
|
|
*searchproc<< TQString(TQFile::encodeName(fkeyNames));
|
|
}
|
|
TQObject::connect(searchproc, TQT_SIGNAL(processExited(TDEProcess *)),TQT_TQOBJECT(this), TQT_SLOT(slotksearchprocresult(TDEProcess *)));
|
|
TQObject::connect(searchproc, TQT_SIGNAL(readReady(KProcIO *)),TQT_TQOBJECT(this), TQT_SLOT(slotsearchread(KProcIO *)));
|
|
TQApplication::setOverrideCursor(TQCursor(TQt::BusyCursor));
|
|
searchproc->setUsePty(TDEProcess::Stdout,false); // EKO: very important line - it took me a day to find out why I should use it
|
|
searchproc->start(TDEProcess::Block,true);
|
|
if (searchproc->isRunning()) {
|
|
searchproc->closePty();
|
|
disconnect(searchproc,0,0,0);
|
|
searchproc->kill();
|
|
}
|
|
}
|
|
else {
|
|
keysToImport = TQStringList::split(" ",keyNames,true);
|
|
}
|
|
|
|
importproc=new KProcIO(TQTextCodec::codecForLocale());
|
|
*importproc<<"gpg"<<"--utf8-strings";
|
|
if (KgpgInterface::getGpgVersion() < 210 ) { // was removed in 2.1
|
|
if (page->cBproxyI->isChecked()) {
|
|
importproc->setEnvironment("http_proxy",page->kLEproxyI->text());
|
|
*importproc<< "--keyserver-options"<<"honor-http-proxy";
|
|
}
|
|
else {
|
|
*importproc<< "--keyserver-options"<<"no-honor-http-proxy";
|
|
}
|
|
}
|
|
*importproc<<"--status-fd=2"<<"--keyserver"<<keyserv<<"--recv-keys";
|
|
|
|
for (TQStringList::Iterator it = keysToImport.begin(); it != keysToImport.end(); it++ ) {
|
|
*importproc<< (*it) ;
|
|
}
|
|
|
|
TQObject::connect(importproc, TQT_SIGNAL(processExited(TDEProcess *)),TQT_TQOBJECT(this), TQT_SLOT(slotimportresult(TDEProcess *)));
|
|
TQObject::connect(importproc, TQT_SIGNAL(readReady(KProcIO *)),TQT_TQOBJECT(this), TQT_SLOT(slotimportread(KProcIO *)));
|
|
|
|
importproc->start(TDEProcess::NotifyOnExit,true);
|
|
importproc->closeWhenDone();
|
|
|
|
importpop = new TQDialog( this,0,true,TQt::WDestructiveClose);
|
|
TQVBoxLayout *vbox=new TQVBoxLayout(importpop,3);
|
|
TQLabel *tex=new TQLabel(importpop);
|
|
tex->setText(i18n("<b>Connecting to the server...</b>"));
|
|
TQPushButton *Buttonabort=new TQPushButton(i18n("&Abort"),importpop);
|
|
vbox->addWidget(tex);
|
|
vbox->addWidget(Buttonabort);
|
|
importpop->setMinimumWidth(250);
|
|
importpop->adjustSize();
|
|
importpop->show();
|
|
connect(Buttonabort,TQT_SIGNAL(clicked()),importpop,TQT_SLOT(close()));
|
|
connect(importpop,TQT_SIGNAL(destroyed ()),this,TQT_SLOT(abortImport()));
|
|
}
|
|
|
|
void keyServer::abortImport()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQApplication::restoreOverrideCursor();
|
|
if (importproc->isRunning())
|
|
{
|
|
disconnect(importproc,0,0,0);
|
|
importproc->kill();
|
|
emit importFinished(TQString());
|
|
}
|
|
if (autoCloseWindow) close();
|
|
}
|
|
|
|
void keyServer::slotksearchprocresult(TDEProcess *) {
|
|
// kdDebug(2100) << k_funcinfo << k_funcinfo << endl;
|
|
// leave only valid keys in the list
|
|
for (TQMap<TQString,TQStringList>::Iterator ite = hashMap.begin(); ite != hashMap.end() ; ite++) {
|
|
bool exp=false;
|
|
bool rev=false;
|
|
for (TQStringList::Iterator it = ite.data().begin(); it != ite.data().end(); it++ ) {
|
|
TQStringList keyString=TQStringList::split(":",(*it),true);
|
|
// kdDebug(2100) << k_funcinfo << "Read one key line: " << (*it) << endl;
|
|
if (keyString[0] == "pub") {
|
|
if (! keyString[6].isEmpty() ) {
|
|
if (keyString[6] == "r") {
|
|
rev = true;
|
|
}
|
|
}
|
|
if (! keyString[5].isEmpty() ) { // expiration date
|
|
TQDate date;
|
|
if (KgpgInterface::getGpgVersion() >= 210 ) {
|
|
TQDateTime timestamp;
|
|
timestamp.setTime_t( keyString[5].toInt() );
|
|
date = timestamp.date();
|
|
}
|
|
else {
|
|
date = TQDate::fromString(keyString[5], Qt::ISODate);
|
|
}
|
|
Q_ASSERT (date.isValid()) /*tqWarning("create date is not valid")*/;
|
|
if (date < TQDate::currentDate() ) {
|
|
exp = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (exp || rev) {
|
|
invalidKeys<<ite.key();
|
|
readmessage += "<qt>"+i18n("Public Key")+": <i>0x";
|
|
if (rev) {
|
|
readmessage += ite.key() + " (" + i18n("Revoked");
|
|
}
|
|
if (exp) {
|
|
readmessage += ", "+i18n("Expired");
|
|
}
|
|
readmessage += ")</i><br></qt>\n";
|
|
}
|
|
}
|
|
|
|
for (TQMap<TQString,TQStringList>::Iterator ite = hashMap.begin(); ite != hashMap.end() ; ite++) {
|
|
if (invalidKeys.find(ite.key()) == invalidKeys.end() ) {
|
|
// keys are neither revoked nor expired
|
|
for (TQStringList::Iterator it = ite.data().begin(); it != ite.data().end(); it++ ) {
|
|
if ( (*it).startsWith("pub") ) {
|
|
keysToImport << (*it).section(":",1,1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void keyServer::slotimportresult(TDEProcess*)
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
TQApplication::restoreOverrideCursor();
|
|
TQString importedNb,importedNbSucess,importedNbProcess,resultMessage, parsedOutput,importedNbUnchanged,importedNbSig;
|
|
TQString notImportesNbSec,importedNbMissing,importedNbRSA,importedNbUid,importedNbSub,importedNbRev,readNbSec;
|
|
TQString importedNbSec,dupNbSec;
|
|
|
|
parsedOutput=readmessage;
|
|
TQStringList importedKeys;
|
|
TQApplication::restoreOverrideCursor();
|
|
|
|
while (parsedOutput.find("IMPORTED")!=-1) {
|
|
parsedOutput.remove(0,parsedOutput.find("IMPORTED")+8);
|
|
importedKeys+=parsedOutput.section("\n",0,0).stripWhiteSpace();
|
|
}
|
|
|
|
if (readmessage.find("IMPORT_RES")!=-1) {
|
|
importedNb=readmessage.section("IMPORT_RES",-1,-1);
|
|
importedNb=importedNb.stripWhiteSpace();
|
|
importedNbProcess=importedNb.section(" ",0,0);
|
|
importedNbMissing=importedNb.section(" ",1,1);
|
|
importedNbSucess=importedNb.section(" ",2,2);
|
|
importedNbRSA=importedNb.section(" ",3,3);
|
|
importedNbUnchanged=importedNb.section(" ",4,4);
|
|
importedNbUid=importedNb.section(" ",5,5);
|
|
importedNbSub=importedNb.section(" ",6,6);
|
|
importedNbSig=importedNb.section(" ",7,7);
|
|
importedNbRev=importedNb.section(" ",8,8);
|
|
readNbSec=importedNb.section(" ",9,9);
|
|
importedNbSec=importedNb.section(" ",10,10);
|
|
dupNbSec=importedNb.section(" ",11,11);
|
|
notImportesNbSec=importedNb.section(" ",12,12);
|
|
resultMessage=i18n("<qt>%n key processed.<br></qt>","<qt>%n keys processed.<br></qt>",importedNbProcess.toULong());
|
|
if (importedNbUnchanged!="0")
|
|
resultMessage+=i18n("<qt>One key unchanged.<br></qt>","<qt>%n keys unchanged.<br></qt>",importedNbUnchanged.toULong());
|
|
if (importedNbSig!="0")
|
|
resultMessage+=i18n("<qt>One signature imported.<br></qt>","<qt>%n signatures imported.<br></qt>",importedNbSig.toULong());
|
|
if (importedNbMissing!="0")
|
|
resultMessage+=i18n("<qt>One key without ID.<br></qt>","<qt>%n keys without ID.<br></qt>",importedNbMissing.toULong());
|
|
if (importedNbRSA!="0")
|
|
resultMessage+=i18n("<qt>One RSA key imported.<br></qt>","<qt>%n RSA keys imported.<br></qt>",importedNbRSA.toULong());
|
|
if (importedNbUid!="0")
|
|
resultMessage+=i18n("<qt>One user ID imported.<br></qt>","<qt>%n user IDs imported.<br></qt>",importedNbUid.toULong());
|
|
if (importedNbSub!="0")
|
|
resultMessage+=i18n("<qt>One subkey imported.<br></qt>","<qt>%n subkeys imported.<br></qt>",importedNbSub.toULong());
|
|
if (importedNbRev!="0")
|
|
resultMessage+=i18n("<qt>One revocation certificate imported.<br></qt>","<qt>%n revocation certificates imported.<br></qt>",importedNbRev.toULong());
|
|
if (readNbSec!="0")
|
|
resultMessage+=i18n("<qt>One secret key processed.<br></qt>","<qt>%n secret keys processed.<br></qt>",readNbSec.toULong());
|
|
if (importedNbSec!="0")
|
|
resultMessage+=i18n("<qt><b>One secret key imported.</b><br></qt>","<qt><b>%n secret keys imported.</b><br></qt>",importedNbSec.toULong());
|
|
if (dupNbSec!="0")
|
|
resultMessage+=i18n("<qt>One secret key unchanged.<br></qt>","<qt>%n secret keys unchanged.<br></qt>",dupNbSec.toULong());
|
|
if (notImportesNbSec!="0")
|
|
resultMessage+=i18n("<qt>One secret key not imported.<br></qt>","<qt>%n secret keys not imported.<br></qt>",notImportesNbSec.toULong());
|
|
if (importedNbSucess!="0")
|
|
resultMessage+=i18n("<qt><b>One key imported:</b><br></qt>","<qt><b>%n keys imported:</b><br></qt>",importedNbSucess.toULong());
|
|
}
|
|
else {
|
|
resultMessage=i18n("No key imported... \nCheck detailed log for more infos");
|
|
}
|
|
|
|
TQString lastID=TQString( importedKeys.last().section(" ",0,0).right(8));
|
|
if ( !lastID.isEmpty() ) {
|
|
//kdDebug(2100)<<"++++++++++imported key"<<lastID<<endl;
|
|
emit importFinished(lastID);
|
|
}
|
|
|
|
if (importpop)
|
|
importpop->hide();
|
|
(void) new KDetailedInfo(0,"import_result",resultMessage,readmessage,importedKeys);
|
|
|
|
if (importpop)
|
|
delete importpop;
|
|
if (autoCloseWindow) close();
|
|
}
|
|
|
|
void keyServer::slotimportread(KProcIO *p)
|
|
{
|
|
TQString required;
|
|
while (p->readln(required,true)!=-1)
|
|
readmessage+=required+"\n";
|
|
}
|
|
|
|
void keyServer::syncCombobox()
|
|
{
|
|
// kdDebug(2100) << k_funcinfo << endl;
|
|
config->setGroup("Servers");
|
|
TQString serverList=config->readEntry("Server_List");
|
|
|
|
TQString optionsServer=KgpgInterface::getGpgSetting("keyserver", KGpgSettings::gpgConfigPath());
|
|
|
|
page->kCBexportks->clear();
|
|
page->kCBimportks->clear();
|
|
|
|
if (!optionsServer.isEmpty()) {
|
|
page->kCBexportks->insertItem(optionsServer + " " + i18n("(Default)"));
|
|
page->kCBimportks->insertItem(optionsServer + " " + i18n("(Default)"));
|
|
}
|
|
else if ( serverList.isEmpty() )
|
|
serverList = "hkp://pool.sks-keyservers.net"; // same as ini kgpgoptions.cpp
|
|
|
|
page->kCBexportks->insertStringList(TQStringList::split(",",serverList));
|
|
page->kCBimportks->insertStringList(TQStringList::split(",",serverList));
|
|
}
|
|
|
|
void keyServer::slotOk()
|
|
{
|
|
accept();
|
|
}
|
|
|
|
|
|
#include "keyservers.moc"
|