Browse Source

[Qt] add BIP70 payment request size DoS protection for URIs

- current code only does this for payment request files, which are
  used on Mac
- also rename readPaymentRequest to readPaymentRequestFromFile, so it's
  obvious that function only handles payment request files and not URIs
- small logging changes in readPaymentRequestFromFile
0.10
Philip Kaufmann 10 years ago
parent
commit
31f84944a5
  1. 44
      src/qt/paymentserver.cpp
  2. 2
      src/qt/paymentserver.h

44
src/qt/paymentserver.cpp

@ -226,7 +226,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
savedPaymentRequests.append(arg); savedPaymentRequests.append(arg);
PaymentRequestPlus request; PaymentRequestPlus request;
if (readPaymentRequest(arg, request)) if (readPaymentRequestFromFile(arg, request))
{ {
if (request.getDetails().network() == "main") if (request.getDetails().network() == "main")
{ {
@ -452,7 +452,7 @@ void PaymentServer::handleURIOrFile(const QString& s)
{ {
PaymentRequestPlus request; PaymentRequestPlus request;
SendCoinsRecipient recipient; SendCoinsRecipient recipient;
if (!readPaymentRequest(s, request)) if (!readPaymentRequestFromFile(s, request))
{ {
emit message(tr("Payment request file handling"), emit message(tr("Payment request file handling"),
tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), tr("Payment request file cannot be read! This can be caused by an invalid payment request file."),
@ -486,18 +486,25 @@ void PaymentServer::handleURIConnection()
handleURIOrFile(msg); handleURIOrFile(msg);
} }
bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPlus& request) //
// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
// so don't use "emit message()", but "QMessageBox::"!
//
bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request)
{ {
QFile f(filename); QFile f(filename);
if (!f.open(QIODevice::ReadOnly)) if (!f.open(QIODevice::ReadOnly)) {
{ qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename);
qWarning() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
return false; return false;
} }
if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) // BIP70 DoS protection
{ if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
qWarning() << "PaymentServer::readPaymentRequest : " << filename << " too large"; qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
.arg(__func__)
.arg(filename)
.arg(f.size())
.arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
return false; return false;
} }
@ -657,13 +664,26 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
void PaymentServer::netRequestFinished(QNetworkReply* reply) void PaymentServer::netRequestFinished(QNetworkReply* reply)
{ {
reply->deleteLater(); reply->deleteLater();
if (reply->error() != QNetworkReply::NoError)
{ // BIP70 DoS protection
if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) {
QString msg = tr("Payment request %2 is too large (%3 bytes, allowed %4 bytes).")
.arg(__func__)
.arg(reply->request().url().toString())
.arg(reply->size())
.arg(BIP70_MAX_PAYMENTREQUEST_SIZE);
qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg;
emit message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR);
return;
}
if (reply->error() != QNetworkReply::NoError) {
QString msg = tr("Error communicating with %1: %2") QString msg = tr("Error communicating with %1: %2")
.arg(reply->request().url().toString()) .arg(reply->request().url().toString())
.arg(reply->errorString()); .arg(reply->errorString());
qWarning() << "PaymentServer::netRequestFinished : " << msg; qWarning() << "PaymentServer::netRequestFinished: " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
return; return;
} }

2
src/qt/paymentserver.h

@ -118,7 +118,7 @@ protected:
bool eventFilter(QObject *object, QEvent *event); bool eventFilter(QObject *object, QEvent *event);
private: private:
static bool readPaymentRequest(const QString& filename, PaymentRequestPlus& request); static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient);
void fetchRequest(const QUrl& url); void fetchRequest(const QUrl& url);

Loading…
Cancel
Save