File indexing completed on 2025-01-12 04:19:46
0001 /* 0002 * Copyright (C) 2003-2005 Justin Karneges <justin@affinix.com> 0003 * 0004 * This library is free software; you can redistribute it and/or 0005 * modify it under the terms of the GNU Lesser General Public 0006 * License as published by the Free Software Foundation; either 0007 * version 2.1 of the License, or (at your option) any later version. 0008 * 0009 * This library is distributed in the hope that it will be useful, 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 * Lesser General Public License for more details. 0013 * 0014 * You should have received a copy of the GNU Lesser General Public 0015 * License along with this library; if not, write to the Free Software 0016 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 0017 * 0018 */ 0019 0020 #include "gpgop.h" 0021 #include "gpgaction.h" 0022 #include "gpgop_p.h" 0023 0024 namespace gpgQCAPlugin { 0025 0026 //---------------------------------------------------------------------------- 0027 // GpgOp 0028 //---------------------------------------------------------------------------- 0029 GpgOp::Private::Private(GpgOp *_q) 0030 : QObject(_q) 0031 , sync(_q) 0032 , q(_q) 0033 , act(nullptr) 0034 , waiting(false) 0035 { 0036 reset(ResetAll); 0037 } 0038 0039 GpgOp::Private::~Private() 0040 { 0041 reset(ResetAll); 0042 } 0043 0044 void GpgOp::Private::reset(ResetMode mode) 0045 { 0046 if (act) { 0047 act->disconnect(this); 0048 act->setParent(nullptr); 0049 act->deleteLater(); 0050 0051 act = nullptr; 0052 } 0053 0054 if (mode >= ResetSessionAndData) { 0055 output = GpgAction::Output(); 0056 result.clear(); 0057 diagnosticText = QString(); 0058 eventList.clear(); 0059 } 0060 0061 if (mode >= ResetAll) { 0062 opt_ascii = false; 0063 opt_noagent = false; 0064 opt_alwaystrust = false; 0065 opt_pubfile = QString(); 0066 opt_secfile = QString(); 0067 } 0068 } 0069 0070 void GpgOp::Private::make_act(GpgOp::Type _op) 0071 { 0072 reset(ResetSessionAndData); 0073 0074 op = _op; 0075 0076 act = new GpgAction(this); 0077 0078 connect(act, &GpgAction::readyRead, this, &GpgOp::Private::act_readyRead); 0079 connect(act, &GpgAction::bytesWritten, this, &GpgOp::Private::act_bytesWritten); 0080 connect(act, &GpgAction::needPassphrase, this, &GpgOp::Private::act_needPassphrase); 0081 connect(act, &GpgAction::needCard, this, &GpgOp::Private::act_needCard); 0082 connect(act, &GpgAction::finished, this, &GpgOp::Private::act_finished); 0083 connect(act, &GpgAction::readyReadDiagnosticText, this, &GpgOp::Private::act_readyReadDiagnosticText); 0084 0085 act->input.bin = bin; 0086 act->input.op = op; 0087 act->input.opt_ascii = opt_ascii; 0088 act->input.opt_noagent = opt_noagent; 0089 act->input.opt_alwaystrust = opt_alwaystrust; 0090 act->input.opt_pubfile = opt_pubfile; 0091 act->input.opt_secfile = opt_secfile; 0092 } 0093 0094 void GpgOp::Private::eventReady(const GpgOp::Event &e) 0095 { 0096 eventList += e; 0097 sync.conditionMet(); 0098 } 0099 0100 void GpgOp::Private::eventReady(GpgOp::Event::Type type) 0101 { 0102 GpgOp::Event e; 0103 e.type = type; 0104 eventReady(e); 0105 } 0106 0107 void GpgOp::Private::eventReady(GpgOp::Event::Type type, int written) 0108 { 0109 GpgOp::Event e; 0110 e.type = type; 0111 e.written = written; 0112 eventReady(e); 0113 } 0114 0115 void GpgOp::Private::eventReady(GpgOp::Event::Type type, const QString &keyId) 0116 { 0117 GpgOp::Event e; 0118 e.type = type; 0119 e.keyId = keyId; 0120 eventReady(e); 0121 } 0122 0123 void GpgOp::Private::act_readyRead() 0124 { 0125 if (waiting) 0126 eventReady(GpgOp::Event::ReadyRead); 0127 else 0128 emit q->readyRead(); 0129 } 0130 0131 void GpgOp::Private::act_bytesWritten(int bytes) 0132 { 0133 if (waiting) 0134 eventReady(GpgOp::Event::BytesWritten, bytes); 0135 else 0136 emit q->bytesWritten(bytes); 0137 } 0138 0139 void GpgOp::Private::act_needPassphrase(const QString &keyId) 0140 { 0141 if (waiting) 0142 eventReady(GpgOp::Event::NeedPassphrase, keyId); 0143 else 0144 emit q->needPassphrase(keyId); 0145 } 0146 0147 void GpgOp::Private::act_needCard() 0148 { 0149 if (waiting) 0150 eventReady(GpgOp::Event::NeedCard); 0151 else 0152 emit q->needCard(); 0153 } 0154 0155 void GpgOp::Private::act_readyReadDiagnosticText() 0156 { 0157 const QString s = act->readDiagnosticText(); 0158 // printf("dtext ready: [%s]\n", qPrintable(s)); 0159 diagnosticText += s; 0160 0161 if (waiting) 0162 eventReady(GpgOp::Event::ReadyReadDiagnosticText); 0163 else 0164 emit q->readyReadDiagnosticText(); 0165 } 0166 0167 void GpgOp::Private::act_finished() 0168 { 0169 #ifdef GPG_PROFILE 0170 if (op == GpgOp::Encrypt) 0171 printf("<< doEncrypt: %d >>\n", timer.elapsed()); 0172 #endif 0173 0174 result = act->read(); 0175 diagnosticText += act->readDiagnosticText(); 0176 output = act->output; 0177 0178 QMap<int, QString> errmap; 0179 errmap[GpgOp::ErrorProcess] = QStringLiteral("ErrorProcess"); 0180 errmap[GpgOp::ErrorPassphrase] = QStringLiteral("ErrorPassphrase"); 0181 errmap[GpgOp::ErrorFormat] = QStringLiteral("ErrorFormat"); 0182 errmap[GpgOp::ErrorSignerExpired] = QStringLiteral("ErrorSignerExpired"); 0183 errmap[GpgOp::ErrorEncryptExpired] = QStringLiteral("ErrorEncryptExpired"); 0184 errmap[GpgOp::ErrorEncryptUntrusted] = QStringLiteral("ErrorEncryptUntrusted"); 0185 errmap[GpgOp::ErrorEncryptInvalid] = QStringLiteral("ErrorEncryptInvalid"); 0186 errmap[GpgOp::ErrorDecryptNoKey] = QStringLiteral("ErrorDecryptNoKey"); 0187 errmap[GpgOp::ErrorUnknown] = QStringLiteral("ErrorUnknown"); 0188 if (output.success) 0189 diagnosticText += QStringLiteral("GpgAction success\n"); 0190 else 0191 diagnosticText += QStringLiteral("GpgAction error: %1\n").arg(errmap[output.errorCode]); 0192 0193 if (output.wasSigned) { 0194 QString s; 0195 if (output.verifyResult == GpgOp::VerifyGood) 0196 s = QStringLiteral("VerifyGood"); 0197 else if (output.verifyResult == GpgOp::VerifyBad) 0198 s = QStringLiteral("VerifyBad"); 0199 else 0200 s = QStringLiteral("VerifyNoKey"); 0201 diagnosticText += QStringLiteral("wasSigned: verifyResult: %1\n").arg(s); 0202 } 0203 0204 // printf("diagnosticText:\n%s", qPrintable(diagnosticText)); 0205 0206 reset(ResetSession); 0207 0208 if (waiting) 0209 eventReady(GpgOp::Event::Finished); 0210 else 0211 emit q->finished(); 0212 } 0213 0214 GpgOp::GpgOp(const QString &bin, QObject *parent) 0215 : QObject(parent) 0216 { 0217 d = new Private(this); 0218 d->bin = bin; 0219 } 0220 0221 GpgOp::~GpgOp() 0222 { 0223 delete d; 0224 } 0225 0226 void GpgOp::reset() 0227 { 0228 d->reset(ResetAll); 0229 } 0230 0231 bool GpgOp::isActive() const 0232 { 0233 return (d->act ? true : false); 0234 } 0235 0236 GpgOp::Type GpgOp::op() const 0237 { 0238 return d->op; 0239 } 0240 0241 void GpgOp::setAsciiFormat(bool b) 0242 { 0243 d->opt_ascii = b; 0244 } 0245 0246 void GpgOp::setDisableAgent(bool b) 0247 { 0248 d->opt_noagent = b; 0249 } 0250 0251 void GpgOp::setAlwaysTrust(bool b) 0252 { 0253 d->opt_alwaystrust = b; 0254 } 0255 0256 void GpgOp::setKeyrings(const QString &pubfile, const QString &secfile) 0257 { 0258 d->opt_pubfile = pubfile; 0259 d->opt_secfile = secfile; 0260 } 0261 0262 void GpgOp::doCheck() 0263 { 0264 d->make_act(Check); 0265 d->act->start(); 0266 } 0267 0268 void GpgOp::doSecretKeyringFile() 0269 { 0270 d->make_act(SecretKeyringFile); 0271 d->act->start(); 0272 } 0273 0274 void GpgOp::doPublicKeyringFile() 0275 { 0276 d->make_act(PublicKeyringFile); 0277 d->act->start(); 0278 } 0279 0280 void GpgOp::doSecretKeys() 0281 { 0282 d->make_act(SecretKeys); 0283 d->act->start(); 0284 } 0285 0286 void GpgOp::doPublicKeys() 0287 { 0288 d->make_act(PublicKeys); 0289 d->act->start(); 0290 } 0291 0292 void GpgOp::doEncrypt(const QStringList &recip_ids) 0293 { 0294 #ifdef GPG_PROFILE 0295 d->timer.start(); 0296 printf("<< doEncrypt >>\n"); 0297 #endif 0298 0299 d->make_act(Encrypt); 0300 d->act->input.recip_ids = recip_ids; 0301 d->act->start(); 0302 } 0303 0304 void GpgOp::doDecrypt() 0305 { 0306 d->make_act(Decrypt); 0307 d->act->start(); 0308 } 0309 0310 void GpgOp::doSign(const QString &signer_id) 0311 { 0312 d->make_act(Sign); 0313 d->act->input.signer_id = signer_id; 0314 d->act->start(); 0315 } 0316 0317 void GpgOp::doSignAndEncrypt(const QString &signer_id, const QStringList &recip_ids) 0318 { 0319 d->make_act(SignAndEncrypt); 0320 d->act->input.signer_id = signer_id; 0321 d->act->input.recip_ids = recip_ids; 0322 d->act->start(); 0323 } 0324 0325 void GpgOp::doSignClearsign(const QString &signer_id) 0326 { 0327 d->make_act(SignClearsign); 0328 d->act->input.signer_id = signer_id; 0329 d->act->start(); 0330 } 0331 0332 void GpgOp::doSignDetached(const QString &signer_id) 0333 { 0334 d->make_act(SignDetached); 0335 d->act->input.signer_id = signer_id; 0336 d->act->start(); 0337 } 0338 0339 void GpgOp::doVerify() 0340 { 0341 d->make_act(Verify); 0342 d->act->start(); 0343 } 0344 0345 void GpgOp::doVerifyDetached(const QByteArray &sig) 0346 { 0347 d->make_act(VerifyDetached); 0348 d->act->input.sig = sig; 0349 d->act->start(); 0350 } 0351 0352 void GpgOp::doImport(const QByteArray &in) 0353 { 0354 d->make_act(Import); 0355 d->act->input.inkey = in; 0356 d->act->start(); 0357 } 0358 0359 void GpgOp::doExport(const QString &key_id) 0360 { 0361 d->make_act(Export); 0362 d->act->input.export_key_id = key_id; 0363 d->act->start(); 0364 } 0365 0366 void GpgOp::doDeleteKey(const QString &key_fingerprint) 0367 { 0368 d->make_act(DeleteKey); 0369 d->act->input.delete_key_fingerprint = key_fingerprint; 0370 d->act->start(); 0371 } 0372 0373 #ifdef QPIPE_SECURE 0374 void GpgOp::submitPassphrase(const QCA::SecureArray &a) 0375 #else 0376 void GpgOp::submitPassphrase(const QByteArray &a) 0377 #endif 0378 { 0379 d->act->submitPassphrase(a); 0380 } 0381 0382 void GpgOp::cardOkay() 0383 { 0384 d->act->cardOkay(); 0385 } 0386 0387 QByteArray GpgOp::read() 0388 { 0389 if (d->act) { 0390 return d->act->read(); 0391 } else { 0392 const QByteArray a = d->result; 0393 d->result.clear(); 0394 return a; 0395 } 0396 } 0397 0398 void GpgOp::write(const QByteArray &in) 0399 { 0400 d->act->write(in); 0401 } 0402 0403 void GpgOp::endWrite() 0404 { 0405 d->act->endWrite(); 0406 } 0407 0408 QString GpgOp::readDiagnosticText() 0409 { 0410 QString s = d->diagnosticText; 0411 d->diagnosticText = QString(); 0412 return s; 0413 } 0414 0415 GpgOp::Event GpgOp::waitForEvent(int msecs) 0416 { 0417 if (!d->eventList.isEmpty()) 0418 return d->eventList.takeFirst(); 0419 0420 if (!d->act) 0421 return GpgOp::Event(); 0422 0423 d->waiting = true; 0424 d->sync.waitForCondition(msecs); 0425 d->waiting = false; 0426 if (!d->eventList.isEmpty()) 0427 return d->eventList.takeFirst(); 0428 else 0429 return GpgOp::Event(); 0430 } 0431 0432 bool GpgOp::success() const 0433 { 0434 return d->output.success; 0435 } 0436 0437 GpgOp::Error GpgOp::errorCode() const 0438 { 0439 return d->output.errorCode; 0440 } 0441 0442 GpgOp::KeyList GpgOp::keys() const 0443 { 0444 return d->output.keys; 0445 } 0446 0447 QString GpgOp::keyringFile() const 0448 { 0449 return d->output.keyringFile; 0450 } 0451 0452 QString GpgOp::homeDir() const 0453 { 0454 return d->output.homeDir; 0455 } 0456 0457 QString GpgOp::encryptedToId() const 0458 { 0459 return d->output.encryptedToId; 0460 } 0461 0462 bool GpgOp::wasSigned() const 0463 { 0464 return d->output.wasSigned; 0465 } 0466 0467 QString GpgOp::signerId() const 0468 { 0469 return d->output.signerId; 0470 } 0471 0472 QDateTime GpgOp::timestamp() const 0473 { 0474 return d->output.timestamp; 0475 } 0476 0477 GpgOp::VerifyResult GpgOp::verifyResult() const 0478 { 0479 return d->output.verifyResult; 0480 } 0481 0482 }