~ubuntu-branches/ubuntu/jaunty/psi/jaunty

« back to all changes in this revision

Viewing changes to src/pgputil.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jan Niehusmann
  • Date: 2008-04-14 18:57:30 UTC
  • mfrom: (2.1.9 hardy)
  • Revision ID: james.westby@ubuntu.com-20080414185730-528re3zp0m2hdlhi
Tags: 0.11-8
* added CONFIG -= link_prl to .pro files and removed dependencies
  which are made unnecessary by this change
* Fix segfault when closing last chat tab with qt4.4
  (This is from upstream svn, rev. 1101) (Closes: Bug#476122)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <QtCore>
 
2
#include <QStringList>
 
3
#include <QDialog>
 
4
 
 
5
#include "pgputil.h"
 
6
#include "passphrasedlg.h"
 
7
 
 
8
 
 
9
PGPUtil::PGPUtil() : qcaEventHandler_(NULL), passphraseDlg_(NULL)
 
10
{
 
11
        qcaEventHandler_ = new QCA::EventHandler(this);
 
12
        connect(qcaEventHandler_,SIGNAL(eventReady(int,const QCA::Event&)),SLOT(handleEvent(int,const QCA::Event&)));
 
13
        qcaEventHandler_->start();
 
14
        qcaKeyStoreManager_.waitForBusyFinished(); // FIXME get rid of this
 
15
        connect(&qcaKeyStoreManager_, SIGNAL(keyStoreAvailable(const QString&)), SLOT(keyStoreAvailable(const QString&)));
 
16
        foreach(QString k, qcaKeyStoreManager_.keyStores()) {
 
17
                QCA::KeyStore* ks = new QCA::KeyStore(k, &qcaKeyStoreManager_);
 
18
                connect(ks, SIGNAL(updated()), SIGNAL(pgpKeysUpdated()));
 
19
                keystores_ += ks;
 
20
        }
 
21
 
 
22
        connect(QCoreApplication::instance(),SIGNAL(aboutToQuit()),SLOT(deleteLater()));
 
23
}
 
24
 
 
25
PGPUtil::~PGPUtil()
 
26
{
 
27
        foreach(QCA::KeyStore* ks,keystores_)  {
 
28
                delete ks;
 
29
        }
 
30
        keystores_.clear();
 
31
}
 
32
 
 
33
 
 
34
PGPUtil& PGPUtil::instance()
 
35
{
 
36
        if (!instance_) {
 
37
                instance_ = new PGPUtil();
 
38
        }
 
39
        return *instance_;
 
40
}
 
41
 
 
42
void PGPUtil::handleEvent(int id, const QCA::Event& event)
 
43
{
 
44
        if (event.type() == QCA::Event::Password) {
 
45
                QCA::KeyStoreEntry entry = event.keyStoreEntry();
 
46
                if(!entry.isNull() && passphrases_.contains(entry.id())) {
 
47
                        qcaEventHandler_->submitPassword(id,QCA::SecureArray(passphrases_[entry.id()].utf8()));
 
48
                }
 
49
                else if (passphraseDlg_) {
 
50
                        EventItem i;
 
51
                        i.id = id;
 
52
                        i.event = event;
 
53
                        pendingEvents_.push_back(i);
 
54
                }
 
55
                else {
 
56
                        promptPassphrase(id,event);
 
57
                }
 
58
        }
 
59
}
 
60
 
 
61
void PGPUtil::promptPassphrase(int id, const QCA::Event& event)
 
62
{
 
63
        QString name;
 
64
        currentEventId_ = id;
 
65
 
 
66
        QCA::KeyStoreEntry entry = event.keyStoreEntry();
 
67
        if(!entry.isNull()) {
 
68
                name = entry.name();
 
69
                currentEntryId_ = entry.id(); 
 
70
        }
 
71
        else {
 
72
                name = event.keyStoreInfo().name();
 
73
                currentEntryId_ = QString();
 
74
        }
 
75
        
 
76
        if (!passphraseDlg_) {
 
77
                passphraseDlg_ = new PassphraseDlg();
 
78
                connect(passphraseDlg_,SIGNAL(finished(int)),SLOT(passphraseDone(int)));
 
79
        }
 
80
        passphraseDlg_->promptPassphrase(name);
 
81
        passphraseDlg_->show();
 
82
}
 
83
 
 
84
void PGPUtil::passphraseDone(int result)
 
85
{
 
86
        // Process the result
 
87
        if (result == QDialog::Accepted) {
 
88
                QString passphrase = passphraseDlg_->getPassphrase();
 
89
                if (!currentEntryId_.isEmpty()) {
 
90
                        passphrases_[currentEntryId_] = passphrase;
 
91
                }
 
92
                qcaEventHandler_->submitPassword(currentEventId_,passphrase.toUtf8());
 
93
        }
 
94
        else if (result == QDialog::Rejected) {
 
95
                qcaEventHandler_->reject(currentEventId_);
 
96
        }
 
97
        else {
 
98
                qWarning() << "PGPUtil: Unexpected passphrase dialog result";
 
99
        }
 
100
        
 
101
        // Process the queue
 
102
        if (!pendingEvents_.isEmpty()) {
 
103
                EventItem eventItem;
 
104
                bool handlePendingEvent = false;
 
105
                while (!pendingEvents_.isEmpty() && !handlePendingEvent) {
 
106
                        eventItem = pendingEvents_.takeFirst();
 
107
                        QCA::KeyStoreEntry entry = eventItem.event.keyStoreEntry();
 
108
                        if(!entry.isNull() && passphrases_.contains(entry.id())) {
 
109
                                qcaEventHandler_->submitPassword(eventItem.id,QCA::SecureArray(passphrases_[entry.id()].utf8()));
 
110
                        }
 
111
                        else {
 
112
                                handlePendingEvent = true;
 
113
                        }
 
114
                }
 
115
                if (handlePendingEvent) {
 
116
                        promptPassphrase(eventItem.id,eventItem.event);
 
117
                        return;
 
118
                }
 
119
        }
 
120
        passphraseDlg_->deleteLater();
 
121
        passphraseDlg_ = NULL;
 
122
}
 
123
 
 
124
bool PGPUtil::pgpAvailable()
 
125
{
 
126
        return (QCA::isSupported("openpgp") && keystores_.count() > 0);
 
127
}
 
128
 
 
129
QString PGPUtil::stripHeaderFooter(const QString &str)
 
130
{
 
131
        QString s;
 
132
        if (str.isEmpty()) {
 
133
                qWarning("pgputil.cpp: Empty PGP message");
 
134
                return "";
 
135
        }
 
136
        if(str.at(0) != '-')
 
137
                return str;
 
138
        QStringList lines = QStringList::split('\n', str, true);
 
139
        QStringList::ConstIterator it = lines.begin();
 
140
        // skip the first line
 
141
        ++it;
 
142
        if(it == lines.end())
 
143
                return str;
 
144
 
 
145
        // skip the header
 
146
        for(; it != lines.end(); ++it) {
 
147
                if((*it).isEmpty())
 
148
                        break;
 
149
        }
 
150
        if(it == lines.end())
 
151
                return str;
 
152
        ++it;
 
153
        if(it == lines.end())
 
154
                return str;
 
155
 
 
156
        bool first = true;
 
157
        for(; it != lines.end(); ++it) {
 
158
                if((*it).at(0) == '-')
 
159
                        break;
 
160
                if(!first)
 
161
                        s += '\n';
 
162
                s += (*it);
 
163
                first = false;
 
164
        }
 
165
 
 
166
        return s;
 
167
}
 
168
 
 
169
 
 
170
QString PGPUtil::addHeaderFooter(const QString &str, int type)
 
171
{
 
172
        QString stype;
 
173
        if(type == 0)
 
174
                stype = "MESSAGE";
 
175
        else
 
176
                stype = "SIGNATURE";
 
177
 
 
178
        QString s;
 
179
        s += QString("-----BEGIN PGP %1-----\n").arg(stype);
 
180
        s += "Version: PGP\n";
 
181
        s += "\n";
 
182
        s += str + '\n';
 
183
        s += QString("-----END PGP %1-----\n").arg(stype);
 
184
        return s;
 
185
}
 
186
 
 
187
 
 
188
QCA::KeyStoreEntry PGPUtil::getSecretKeyStoreEntry(const QString& keyID)
 
189
{
 
190
        foreach(QCA::KeyStore *ks, keystores_) {
 
191
                if (ks->type() == QCA::KeyStore::PGPKeyring && ks->holdsIdentities()) {
 
192
                        foreach(QCA::KeyStoreEntry ke, ks->entryList()) {
 
193
                                if (ke.type() == QCA::KeyStoreEntry::TypePGPSecretKey
 
194
                                    && ke.pgpSecretKey().keyId() == keyID) {
 
195
                                        return ke;
 
196
                                }
 
197
                        }
 
198
                }
 
199
        }
 
200
        return QCA::KeyStoreEntry();
 
201
}
 
202
 
 
203
QCA::KeyStoreEntry PGPUtil::getPublicKeyStoreEntry(const QString& keyID)
 
204
{
 
205
        foreach(QCA::KeyStore *ks, keystores_) {
 
206
                if (ks->type() == QCA::KeyStore::PGPKeyring && ks->holdsIdentities()) {
 
207
                        foreach(QCA::KeyStoreEntry ke, ks->entryList()) {
 
208
                                if ((ke.type() == QCA::KeyStoreEntry::TypePGPSecretKey
 
209
                                     || ke.type() == QCA::KeyStoreEntry::TypePGPPublicKey)
 
210
                                    && ke.pgpPublicKey().keyId() == keyID) {
 
211
                                        return ke;
 
212
                                }
 
213
                        }
 
214
                }
 
215
        }
 
216
        return QCA::KeyStoreEntry();
 
217
}
 
218
 
 
219
QString PGPUtil::messageErrorString(enum QCA::SecureMessage::Error e)
 
220
{
 
221
        QString msg;
 
222
        switch(e) {
 
223
                case QCA::SecureMessage::ErrorPassphrase:
 
224
                        msg = QObject::tr("Invalid passphrase");
 
225
                        break;
 
226
                case QCA::SecureMessage::ErrorFormat:
 
227
                        msg = QObject::tr("Invalid input format");
 
228
                        break;
 
229
                case QCA::SecureMessage::ErrorSignerExpired:
 
230
                        msg = QObject::tr("Signing key expired");
 
231
                        break;
 
232
                case QCA::SecureMessage::ErrorSignerInvalid:
 
233
                        msg = QObject::tr("Invalid key");
 
234
                        break;
 
235
                case QCA::SecureMessage::ErrorEncryptExpired:
 
236
                        msg = QObject::tr("Encrypting key expired");
 
237
                        break;
 
238
                case QCA::SecureMessage::ErrorEncryptUntrusted:
 
239
                        msg = QObject::tr("Encrypting key is untrusted");
 
240
                        break;
 
241
                case QCA::SecureMessage::ErrorEncryptInvalid:
 
242
                        msg = QObject::tr("Encrypting key is invalid");
 
243
                        break;
 
244
                case QCA::SecureMessage::ErrorNeedCard:
 
245
                        msg = QObject::tr("PGP card is missing");
 
246
                        break;
 
247
                default:
 
248
                        msg = QObject::tr("Unknown error");
 
249
        }
 
250
        return msg;
 
251
}
 
252
 
 
253
bool PGPUtil::equals(QCA::PGPKey k1, QCA::PGPKey k2)
 
254
{
 
255
        if (k1.isNull()) {
 
256
                return k2.isNull();
 
257
        }
 
258
        else if (k2.isNull()) {
 
259
                return false;
 
260
        }
 
261
        else {
 
262
                return k1.keyId() == k2.keyId();
 
263
        }
 
264
}
 
265
 
 
266
void PGPUtil::removePassphrase(const QString& id)
 
267
{
 
268
        passphrases_.remove(id);
 
269
}
 
270
 
 
271
void PGPUtil::keyStoreAvailable(const QString& k)
 
272
{
 
273
        QCA::KeyStore* ks = new QCA::KeyStore(k, &qcaKeyStoreManager_);
 
274
        connect(ks, SIGNAL(updated()), SIGNAL(pgpKeysUpdated()));
 
275
        keystores_ += ks;
 
276
}
 
277
 
 
278
 
 
279
 
 
280
 
 
281
PGPUtil* PGPUtil::instance_ = NULL;