• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdenewstuff
 

tdenewstuff

  • tdenewstuff
security.cpp
1 /***************************************************************************
2  security.cpp - description
3  -------------------
4  begin : Thu Jun 24 11:22:12 2004
5  copyright : (C) 2004, 2005 by Andras Mantia <amantia@kde.org>
6  ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * This program is free software; you can redistribute it and/or modify *
11  * it under the terms of the GNU Library General Public License as *
12  * published by the Free Software Foundation; version 2 of the License. *
13  * *
14  ***************************************************************************/
15 
16  //qt includes
17 #include <tqfile.h>
18 #include <tqfileinfo.h>
19 #include <tqstringlist.h>
20 #include <tqtimer.h>
21 
22  //kde includes
23 #include <kdebug.h>
24 #include <kinputdialog.h>
25 #include <tdelocale.h>
26 #include <kmdcodec.h>
27 #include <tdemessagebox.h>
28 #include <kpassdlg.h>
29 #include <kprocio.h>
30 
31  //app includes
32 #include "security.h"
33 
34 using namespace KNS;
35 
36 Security::Security()
37 {
38  m_keysRead = false;
39  m_gpgRunning = false;
40  readKeys();
41  readSecretKeys();
42 }
43 
44 
45 Security::~Security()
46 {
47 }
48 
49 void Security::readKeys()
50 {
51  if (m_gpgRunning)
52  {
53  TQTimer::singleShot(5, this, TQT_SLOT(readKeys()));
54  return;
55  }
56  m_runMode = List;
57  m_keys.clear();
58  KProcIO *readProcess=new KProcIO();
59  *readProcess << "gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--with-colon"<<"--list-keys";
60  connect(readProcess, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_SLOT(slotProcessExited(TDEProcess *)));
61  connect(readProcess, TQT_SIGNAL(readReady(KProcIO *)) ,this, TQT_SLOT(slotDataArrived(KProcIO *)));
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>"));
64  else
65  m_gpgRunning = true;
66 }
67 
68 void Security::readSecretKeys()
69 {
70  if (m_gpgRunning)
71  {
72  TQTimer::singleShot(5, this, TQT_SLOT(readSecretKeys()));
73  return;
74  }
75  m_runMode = ListSecret;
76  KProcIO *readProcess=new KProcIO();
77  *readProcess << "gpg"<<"--no-secmem-warning"<<"--no-tty"<<"--with-colon"<<"--list-secret-keys";
78  connect(readProcess, TQT_SIGNAL(processExited(TDEProcess *)), this, TQT_SLOT(slotProcessExited(TDEProcess *)));
79  connect(readProcess, TQT_SIGNAL(readReady(KProcIO *)) ,this, TQT_SLOT(slotDataArrived(KProcIO *)));
80  if (readProcess->start(TDEProcess::NotifyOnExit, true))
81  m_gpgRunning = true;
82 }
83 
84 void Security::slotProcessExited(TDEProcess *process)
85 {
86  switch (m_runMode)
87  {
88  case ListSecret:
89  m_keysRead = true;
90  break;
91  case Verify: emit validityResult(m_result);
92  break;
93  case Sign: emit fileSigned(m_result);
94  break;
95 
96  }
97  m_gpgRunning = false;
98  delete process;
99 }
100 
101 void Security::slotDataArrived(KProcIO *procIO)
102 {
103  TQString data;
104  while (procIO->readln(data, true) != -1)
105  {
106  switch (m_runMode)
107  {
108  case List:
109  case ListSecret:
110  if (data.startsWith("pub") || data.startsWith("sec"))
111  {
112  KeyStruct key;
113  if (data.startsWith("pub"))
114  key.secret = false;
115  else
116  key.secret = true;
117  TQStringList line = TQStringList::split(":", data, true);
118  key.id = line[4];
119  TQString shortId = key.id.right(8);
120  TQString trustStr = line[1];
121  key.trusted = false;
122  if (trustStr == "u" || trustStr == "f")
123  key.trusted = true;
124  data = line[9];
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;
131  }
132  break;
133  case Verify:
134  data = TQString(data.section("]",1,-1)).stripWhiteSpace();
135  if (data.startsWith("GOODSIG"))
136  {
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))
141  {
142  m_result |= UNKNOWN;
143  } else
144  {
145  m_signatureKey = m_keys[id];
146  }
147  } else
148  if (data.startsWith("NO_PUBKEY"))
149  {
150  m_result &= SIGNED_BAD_CLEAR;
151  m_result |= UNKNOWN;
152  } else
153  if (data.startsWith("BADSIG"))
154  {
155  m_result |= SIGNED_BAD;
156  TQString id = data.section(" ", 1 , 1).right(8);
157  if (!m_keys.contains(id))
158  {
159  m_result |= UNKNOWN;
160  } else
161  {
162  m_signatureKey = m_keys[id];
163  }
164  } else
165  if (data.startsWith("TRUST_ULTIMATE"))
166  {
167  m_result &= SIGNED_BAD_CLEAR;
168  m_result |= TRUSTED;
169  }
170  break;
171 
172  case Sign:
173  if (data.find("passphrase.enter") != -1)
174  {
175  TQCString password;
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&lt;%3&gt;</i>:</qt>").arg(m_secretKey).arg(key.name).arg(key.mail));
178  if (result == KPasswordDialog::Accepted)
179  {
180  procIO->writeStdin(password, true);
181  password.fill(' ');
182  }
183  else
184  {
185  m_result |= BAD_PASSPHRASE;
186  slotProcessExited(procIO);
187  return;
188  }
189  } else
190  if (data.find("BAD_PASSPHRASE") != -1)
191  {
192  m_result |= BAD_PASSPHRASE;
193  }
194  break;
195  }
196  }
197 }
198 
199 void Security::checkValidity(const TQString& filename)
200 {
201  m_fileName = filename;
202  slotCheckValidity();
203 }
204 
205 void Security::slotCheckValidity()
206 {
207  if (!m_keysRead || m_gpgRunning)
208  {
209  TQTimer::singleShot(5, this, TQT_SLOT(slotCheckValidity()));
210  return;
211  }
212  if (m_keys.count() == 0)
213  {
214  emit validityResult(-1);
215  return;
216  }
217 
218  m_result = 0;
219  m_runMode = Verify;
220  TQFileInfo f(m_fileName);
221  //check the MD5 sum
222  TQString md5sum;
223  const char* c = "";
224  KMD5 context(c);
225  TQFile file(m_fileName);
226  if (file.open(IO_ReadOnly))
227  {
228  context.reset();
229  context.update(TQT_TQIODEVICE_OBJECT(file));
230  md5sum = context.hexDigest();
231  file.close();
232  }
233  file.setName(f.dirPath() + "/md5sum");
234  if (file.open(IO_ReadOnly))
235  {
236  TQString md5sum_file;
237  file.readLine(md5sum_file, 50);
238  if (!md5sum.isEmpty() && !md5sum_file.isEmpty() && md5sum_file.startsWith(md5sum))
239  m_result |= MD5_OK;
240  file.close();
241  }
242  m_result |= SIGNED_BAD;
243  m_signatureKey.id = "";
244  m_signatureKey.name = "";
245  m_signatureKey.mail = "";
246  m_signatureKey.trusted = false;
247 
248  //verify the signature
249  KProcIO *verifyProcess=new KProcIO();
250  *verifyProcess<<"gpg"<<"--no-secmem-warning"<<"--status-fd=2"<<"--command-fd=0"<<"--verify" << f.dirPath() + "/signature"<< m_fileName;
251  connect(verifyProcess, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotProcessExited(TDEProcess *)));
252  connect(verifyProcess, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotDataArrived(KProcIO *)));
253  if (verifyProcess->start(TDEProcess::NotifyOnExit,true))
254  m_gpgRunning = true;
255  else
256  {
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;
260  }
261 }
262 
263 void Security::signFile(const TQString &fileName)
264 {
265  m_fileName = fileName;
266  slotSignFile();
267 }
268 
269 void Security::slotSignFile()
270 {
271  if (!m_keysRead || m_gpgRunning)
272  {
273  TQTimer::singleShot(5, this, TQT_SLOT(slotSignFile()));
274  return;
275  }
276 
277  TQStringList secretKeys;
278  for (TQMap<TQString, KeyStruct>::Iterator it = m_keys.begin(); it != m_keys.end(); ++it)
279  {
280  if (it.data().secret)
281  secretKeys.append(it.key());
282  }
283 
284  if (secretKeys.count() == 0)
285  {
286  emit fileSigned(-1);
287  return;
288  }
289 
290  m_result = 0;
291  TQFileInfo f(m_fileName);
292 
293  //create the MD5 sum
294  TQString md5sum;
295  const char* c = "";
296  KMD5 context(c);
297  TQFile file(m_fileName);
298  if (file.open(IO_ReadOnly))
299  {
300  context.reset();
301  context.update(TQT_TQIODEVICE_OBJECT(file));
302  md5sum = context.hexDigest();
303  file.close();
304  }
305  file.setName(f.dirPath() + "/md5sum");
306  if (file.open(IO_WriteOnly))
307  {
308  TQTextStream stream(&file);
309  stream << md5sum;
310  m_result |= MD5_OK;
311  file.close();
312  }
313 
314  if (secretKeys.count() > 1)
315  {
316  bool ok;
317  secretKeys = KInputDialog::getItemList(i18n("Select Signing Key"), i18n("Key used for signing:"), secretKeys, secretKeys[0], false, &ok);
318  if (ok)
319  m_secretKey = secretKeys[0];
320  else
321  {
322  emit fileSigned(0);
323  return;
324  }
325  } else
326  m_secretKey = secretKeys[0];
327 
328  //verify the signature
329  KProcIO *signProcess=new KProcIO();
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, TQT_SIGNAL(processExited(TDEProcess *)),this, TQT_SLOT(slotProcessExited(TDEProcess *)));
332  connect(signProcess, TQT_SIGNAL(readReady(KProcIO *)),this, TQT_SLOT(slotDataArrived(KProcIO *)));
333  m_runMode = Sign;
334  if (signProcess->start(TDEProcess::NotifyOnExit,true))
335  m_gpgRunning = true;
336  else
337  {
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>"));
339  emit fileSigned(0);
340  delete signProcess;
341  }
342 }
343 
344 #include "security.moc"
KNS
Handles security releated issues, like signing, verifying.
Definition: downloaddialog.h:36

tdenewstuff

Skip menu "tdenewstuff"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdenewstuff

Skip menu "tdenewstuff"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdenewstuff by doxygen 1.8.8
This website is maintained by Timothy Pearson.