18#include <tqfileinfo.h> 
   19#include <tqstringlist.h> 
   24#include <kinputdialog.h> 
   27#include <tdemessagebox.h> 
   49void Security::readKeys()
 
   53    TQTimer::singleShot(5, 
this, TQ_SLOT(readKeys()));
 
   58  TDEProcIO *readProcess=
new TDEProcIO();
 
   59  *readProcess << 
"gpg"<<
"--no-secmem-warning"<<
"--no-tty"<<
"--with-colon"<<
"--list-keys";
 
   60  connect(readProcess, TQ_SIGNAL(processExited(TDEProcess *)), 
this, TQ_SLOT(slotProcessExited(TDEProcess *)));
 
   61  connect(readProcess, TQ_SIGNAL(readReady(TDEProcIO *)) ,
this, TQ_SLOT(slotDataArrived(TDEProcIO *)));
 
   62  if (!readProcess->start(TDEProcess::NotifyOnExit, 
true))
 
   63    KMessageBox::error(0L, i18n(
"<qt>Cannot start <i>gpg</i> and retrieve the available keys. Make sure that <i>gpg</i> is installed, otherwise verification of downloaded resources will not be possible.</qt>"));
 
   68void Security::readSecretKeys()
 
   72    TQTimer::singleShot(5, 
this, TQ_SLOT(readSecretKeys()));
 
   75  m_runMode = ListSecret;
 
   76  TDEProcIO *readProcess=
new TDEProcIO();
 
   77  *readProcess << 
"gpg"<<
"--no-secmem-warning"<<
"--no-tty"<<
"--with-colon"<<
"--list-secret-keys";
 
   78  connect(readProcess, TQ_SIGNAL(processExited(TDEProcess *)), 
this, TQ_SLOT(slotProcessExited(TDEProcess *)));
 
   79  connect(readProcess, TQ_SIGNAL(readReady(TDEProcIO *)) ,
this, TQ_SLOT(slotDataArrived(TDEProcIO *)));
 
   80  if (readProcess->start(TDEProcess::NotifyOnExit, 
true))
 
   84void Security::slotProcessExited(TDEProcess *process)
 
   91     case Verify: emit validityResult(m_result);
 
   93     case Sign:   emit fileSigned(m_result);
 
  101void Security::slotDataArrived(TDEProcIO *procIO)
 
  104  while (procIO->readln(data, 
true) != -1)
 
  110          if (data.startsWith(
"pub") || data.startsWith(
"sec"))
 
  113              if (data.startsWith(
"pub"))
 
  117              TQStringList line = TQStringList::split(
":", data, 
true);
 
  119              TQString shortId = key.id.right(8);
 
  120              TQString trustStr = line[1];
 
  122              if (trustStr == 
"u" || trustStr == 
"f")
 
  125              key.mail=data.section(
'<', -1, -1);
 
  126              key.mail.truncate(key.mail.length() - 1);
 
  127              key.name=data.section(
'<',0,0);
 
  128              if (key.name.find(
"(")!=-1)
 
  129                  key.name=key.name.section(
'(',0,0);
 
  130              m_keys[shortId] = key;
 
  134          data = TQString(data.section(
"]",1,-1)).stripWhiteSpace();
 
  135          if (data.startsWith(
"GOODSIG"))
 
  137              m_result &= SIGNED_BAD_CLEAR;
 
  138              m_result |= SIGNED_OK;
 
  139              TQString 
id = data.section(
" ", 1 , 1).right(8);
 
  140              if (!m_keys.contains(
id))
 
  145                 m_signatureKey = m_keys[id];
 
  148          if (data.startsWith(
"NO_PUBKEY"))
 
  150              m_result &= SIGNED_BAD_CLEAR;
 
  153          if (data.startsWith(
"BADSIG"))
 
  155              m_result |= SIGNED_BAD;
 
  156              TQString 
id = data.section(
" ", 1 , 1).right(8);
 
  157              if (!m_keys.contains(
id))
 
  162                 m_signatureKey = m_keys[id];
 
  165          if (data.startsWith(
"TRUST_ULTIMATE"))
 
  167            m_result &= SIGNED_BAD_CLEAR;
 
  173         if (data.find(
"passphrase.enter") != -1)
 
  176           KeyStruct key = m_keys[m_secretKey];
 
  177           int result = KPasswordDialog::getPassword(password, i18n(
"<qt>Enter passphrase for key <b>0x%1</b>, belonging to<br><i>%2<%3></i>:</qt>").arg(m_secretKey).arg(key.name).arg(key.mail));
 
  178           if (result == KPasswordDialog::Accepted)
 
  180             procIO->writeStdin(password, 
true);
 
  185             m_result |= BAD_PASSPHRASE;
 
  186             slotProcessExited(procIO);
 
  190         if (data.find(
"BAD_PASSPHRASE") != -1)
 
  192           m_result |= BAD_PASSPHRASE;
 
  199void Security::checkValidity(
const TQString& filename)
 
  201  m_fileName = filename;
 
  205void Security::slotCheckValidity()
 
  207  if (!m_keysRead || m_gpgRunning)
 
  209    TQTimer::singleShot(5, 
this, TQ_SLOT(slotCheckValidity()));
 
  212  if (m_keys.count() == 0)
 
  214    emit validityResult(-1);
 
  220  TQFileInfo f(m_fileName);
 
  225  TQFile file(m_fileName);
 
  226  if (file.open(IO_ReadOnly))
 
  229     context.update(file);
 
  230     md5sum = context.hexDigest();
 
  233  file.setName(f.dirPath() + 
"/md5sum");
 
  234  if (file.open(IO_ReadOnly))
 
  236     TQString md5sum_file;
 
  237     file.readLine(md5sum_file, 50);
 
  238     if (!md5sum.isEmpty() && !md5sum_file.isEmpty() && md5sum_file.startsWith(md5sum))
 
  242  m_result |= SIGNED_BAD;
 
  243  m_signatureKey.id = 
"";
 
  244  m_signatureKey.name = 
"";
 
  245  m_signatureKey.mail = 
"";
 
  246  m_signatureKey.trusted = 
false;
 
  249  TDEProcIO *verifyProcess=
new TDEProcIO();
 
  250  *verifyProcess<<
"gpg"<<
"--no-secmem-warning"<<
"--status-fd=2"<<
"--command-fd=0"<<
"--verify" << f.dirPath() + 
"/signature"<< m_fileName;
 
  251  connect(verifyProcess, TQ_SIGNAL(processExited(TDEProcess *)),
this, TQ_SLOT(slotProcessExited(TDEProcess *)));
 
  252  connect(verifyProcess, TQ_SIGNAL(readReady(TDEProcIO *)),
this, TQ_SLOT(slotDataArrived(TDEProcIO *)));
 
  253  if (verifyProcess->start(TDEProcess::NotifyOnExit,
true))
 
  257      KMessageBox::error(0L, i18n(
"<qt>Cannot start <i>gpg</i> and check the validity of the file. Make sure that <i>gpg</i> is installed, otherwise verification of downloaded resources will not be possible.</qt>"));
 
  258      emit validityResult(0);
 
  259      delete verifyProcess;
 
  263void Security::signFile(
const TQString &fileName)
 
  265  m_fileName = fileName;
 
  269void Security::slotSignFile()
 
  271  if (!m_keysRead || m_gpgRunning)
 
  273    TQTimer::singleShot(5, 
this, TQ_SLOT(slotSignFile()));
 
  277  TQStringList secretKeys;
 
  278  for (TQMap<TQString, KeyStruct>::Iterator it = m_keys.begin(); it != m_keys.end(); ++it)
 
  280    if (it.data().secret)
 
  281      secretKeys.append(it.key());
 
  284  if (secretKeys.count() == 0)
 
  291  TQFileInfo f(m_fileName);
 
  297  TQFile file(m_fileName);
 
  298  if (file.open(IO_ReadOnly))
 
  301    context.update(file);
 
  302    md5sum = context.hexDigest();
 
  305  file.setName(f.dirPath() + 
"/md5sum");
 
  306  if (file.open(IO_WriteOnly))
 
  308    TQTextStream stream(&file);
 
  314  if (secretKeys.count() > 1)
 
  317    secretKeys = KInputDialog::getItemList(i18n(
"Select Signing Key"), i18n(
"Key used for signing:"), secretKeys, secretKeys[0], 
false, &ok);    
 
  319      m_secretKey = secretKeys[0];
 
  326    m_secretKey = secretKeys[0];
 
  329  TDEProcIO *signProcess=
new TDEProcIO();
 
  330  *signProcess<<
"gpg"<<
"--no-secmem-warning"<<
"--status-fd=2"<<
"--command-fd=0"<<
"--no-tty"<<
"--detach-sign" << 
"-u" << m_secretKey << 
"-o" << f.dirPath() + 
"/signature" << m_fileName;
 
  331  connect(signProcess, TQ_SIGNAL(processExited(TDEProcess *)),
this, TQ_SLOT(slotProcessExited(TDEProcess *)));
 
  332  connect(signProcess, TQ_SIGNAL(readReady(TDEProcIO *)),
this, TQ_SLOT(slotDataArrived(TDEProcIO *)));
 
  334  if (signProcess->start(TDEProcess::NotifyOnExit,
true))
 
  338    KMessageBox::error(0L, i18n(
"<qt>Cannot start <i>gpg</i> and sign the file. Make sure that <i>gpg</i> is installed, otherwise signing of the resources will not be possible.</qt>"));
 
  344#include "security.moc" 
Handles security releated issues, like signing, verifying.