Merge pull request #5216
5ec654b
[Qt] update paymentserver license and cleanup ordering (Philip Kaufmann)4333e26
[Qt] add BIP70 DoS protection test (Philip Kaufmann)31f8494
[Qt] add BIP70 payment request size DoS protection for URIs (Philip Kaufmann)2284ccb
[Qt] remove dup lock that is done in SetAddressBook() (Philip Kaufmann)1ec753f
[Qt] ensure socket is set to NULL in PaymentServer::ipcSendCommandLine (Philip Kaufmann)814429d
[Qt] add BIP70/BIP71 constants for all messages and mime types (Philip Kaufmann)b82695b
[Qt] make PaymentServer::ipcParseCommandLine void (Philip Kaufmann)
This commit is contained in:
commit
7f76dda903
7 changed files with 88 additions and 43 deletions
|
@ -570,9 +570,9 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_WALLET
|
#ifdef ENABLE_WALLET
|
||||||
// Parse URIs on command line -- this can affect Params()
|
// Parse URIs on command line -- this can affect Params()
|
||||||
if (!PaymentServer::ipcParseCommandLine(argc, argv))
|
PaymentServer::ipcParseCommandLine(argc, argv);
|
||||||
exit(0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
|
QScopedPointer<const NetworkStyle> networkStyle(NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
|
||||||
assert(!networkStyle.isNull());
|
assert(!networkStyle.isNull());
|
||||||
// Allow for separate UI settings for testnets
|
// Allow for separate UI settings for testnets
|
||||||
|
|
|
@ -38,9 +38,6 @@ static const int TOOLTIP_WRAP_THRESHOLD = 80;
|
||||||
/* Maximum allowed URI length */
|
/* Maximum allowed URI length */
|
||||||
static const int MAX_URI_LENGTH = 255;
|
static const int MAX_URI_LENGTH = 255;
|
||||||
|
|
||||||
/* Maximum somewhat-sane size of a payment request file */
|
|
||||||
static const int MAX_PAYMENT_REQUEST_SIZE = 50000; // bytes
|
|
||||||
|
|
||||||
/* QRCodeDialog -- size of exported QR Code image */
|
/* QRCodeDialog -- size of exported QR Code image */
|
||||||
#define EXPORT_IMAGE_SIZE 256
|
#define EXPORT_IMAGE_SIZE 256
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2011-2013 The Bitcoin developers
|
// Copyright (c) 2011-2014 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2011-2013 The Bitcoin developers
|
// Copyright (c) 2011-2014 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H
|
#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
// Copyright (c) 2011-2013 The Bitcoin developers
|
// Copyright (c) 2011-2014 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#include "paymentserver.h"
|
#include "paymentserver.h"
|
||||||
|
|
||||||
#include "bitcoinunits.h"
|
#include "bitcoinunits.h"
|
||||||
#include "guiconstants.h"
|
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
|
|
||||||
|
@ -19,6 +18,7 @@
|
||||||
|
|
||||||
#include <openssl/x509.h>
|
#include <openssl/x509.h>
|
||||||
#include <openssl/x509_vfy.h>
|
#include <openssl/x509_vfy.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
#include <QDataStream>
|
#include <QDataStream>
|
||||||
|
@ -46,14 +46,20 @@
|
||||||
#include <QUrlQuery>
|
#include <QUrlQuery>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
|
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
|
||||||
const QString BITCOIN_IPC_PREFIX("bitcoin:");
|
const QString BITCOIN_IPC_PREFIX("bitcoin:");
|
||||||
const char* BITCOIN_REQUEST_MIMETYPE = "application/bitcoin-paymentrequest";
|
// BIP70 payment protocol messages
|
||||||
const char* BITCOIN_PAYMENTACK_MIMETYPE = "application/bitcoin-paymentack";
|
const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK";
|
||||||
const char* BITCOIN_PAYMENTACK_CONTENTTYPE = "application/bitcoin-payment";
|
const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest";
|
||||||
|
// BIP71 payment protocol media types
|
||||||
|
const char* BIP71_MIMETYPE_PAYMENT = "application/bitcoin-payment";
|
||||||
|
const char* BIP71_MIMETYPE_PAYMENTACK = "application/bitcoin-paymentack";
|
||||||
|
const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/bitcoin-paymentrequest";
|
||||||
|
// BIP70 max payment request size in bytes (DoS protection)
|
||||||
|
const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000;
|
||||||
|
|
||||||
X509_STORE* PaymentServer::certStore = NULL;
|
X509_STORE* PaymentServer::certStore = NULL;
|
||||||
void PaymentServer::freeCertStore()
|
void PaymentServer::freeCertStore()
|
||||||
|
@ -184,7 +190,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
|
||||||
// Warning: ipcSendCommandLine() is called early in init,
|
// Warning: ipcSendCommandLine() is called early in init,
|
||||||
// so don't use "emit message()", but "QMessageBox::"!
|
// so don't use "emit message()", but "QMessageBox::"!
|
||||||
//
|
//
|
||||||
bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
void PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
@ -192,6 +198,10 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
||||||
if (arg.startsWith("-"))
|
if (arg.startsWith("-"))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// If the bitcoin: URI contains a payment request, we are not able to detect the
|
||||||
|
// network as that would require fetching and parsing the payment request.
|
||||||
|
// That means clicking such an URI which contains a testnet payment request
|
||||||
|
// will start a mainnet instance and throw a "wrong network" error.
|
||||||
if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
|
if (arg.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // bitcoin: URI
|
||||||
{
|
{
|
||||||
savedPaymentRequests.append(arg);
|
savedPaymentRequests.append(arg);
|
||||||
|
@ -216,7 +226,7 @@ bool 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")
|
||||||
{
|
{
|
||||||
|
@ -235,7 +245,6 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
||||||
qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
|
qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -254,6 +263,7 @@ bool PaymentServer::ipcSendCommandLine()
|
||||||
if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT))
|
if (!socket->waitForConnected(BITCOIN_IPC_CONNECT_TIMEOUT))
|
||||||
{
|
{
|
||||||
delete socket;
|
delete socket;
|
||||||
|
socket = NULL;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,12 +272,14 @@ bool PaymentServer::ipcSendCommandLine()
|
||||||
out.setVersion(QDataStream::Qt_4_0);
|
out.setVersion(QDataStream::Qt_4_0);
|
||||||
out << r;
|
out << r;
|
||||||
out.device()->seek(0);
|
out.device()->seek(0);
|
||||||
|
|
||||||
socket->write(block);
|
socket->write(block);
|
||||||
socket->flush();
|
socket->flush();
|
||||||
|
|
||||||
socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT);
|
socket->waitForBytesWritten(BITCOIN_IPC_CONNECT_TIMEOUT);
|
||||||
socket->disconnectFromServer();
|
socket->disconnectFromServer();
|
||||||
|
|
||||||
delete socket;
|
delete socket;
|
||||||
|
socket = NULL;
|
||||||
fResult = true;
|
fResult = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,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."),
|
||||||
|
@ -474,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() > MAX_PAYMENT_REQUEST_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -580,10 +599,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
||||||
void PaymentServer::fetchRequest(const QUrl& url)
|
void PaymentServer::fetchRequest(const QUrl& url)
|
||||||
{
|
{
|
||||||
QNetworkRequest netRequest;
|
QNetworkRequest netRequest;
|
||||||
netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest");
|
netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST);
|
||||||
netRequest.setUrl(url);
|
netRequest.setUrl(url);
|
||||||
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
|
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
|
||||||
netRequest.setRawHeader("Accept", BITCOIN_REQUEST_MIMETYPE);
|
netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST);
|
||||||
netManager->get(netRequest);
|
netManager->get(netRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -594,11 +613,11 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QNetworkRequest netRequest;
|
QNetworkRequest netRequest;
|
||||||
netRequest.setAttribute(QNetworkRequest::User, "PaymentACK");
|
netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK);
|
||||||
netRequest.setUrl(QString::fromStdString(details.payment_url()));
|
netRequest.setUrl(QString::fromStdString(details.payment_url()));
|
||||||
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BITCOIN_PAYMENTACK_CONTENTTYPE);
|
netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT);
|
||||||
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
|
netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
|
||||||
netRequest.setRawHeader("Accept", BITCOIN_PAYMENTACK_MIMETYPE);
|
netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK);
|
||||||
|
|
||||||
payments::Payment payment;
|
payments::Payment payment;
|
||||||
payment.set_merchant_data(details.merchant_data());
|
payment.set_merchant_data(details.merchant_data());
|
||||||
|
@ -616,7 +635,6 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
||||||
else {
|
else {
|
||||||
CPubKey newKey;
|
CPubKey newKey;
|
||||||
if (wallet->GetKeyFromPool(newKey)) {
|
if (wallet->GetKeyFromPool(newKey)) {
|
||||||
LOCK(wallet->cs_wallet); // SetAddressBook
|
|
||||||
CKeyID keyID = newKey.GetID();
|
CKeyID keyID = newKey.GetID();
|
||||||
wallet->SetAddressBook(keyID, strAccount, "refund");
|
wallet->SetAddressBook(keyID, strAccount, "refund");
|
||||||
|
|
||||||
|
@ -646,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;
|
||||||
}
|
}
|
||||||
|
@ -660,7 +691,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
|
||||||
QByteArray data = reply->readAll();
|
QByteArray data = reply->readAll();
|
||||||
|
|
||||||
QString requestType = reply->request().attribute(QNetworkRequest::User).toString();
|
QString requestType = reply->request().attribute(QNetworkRequest::User).toString();
|
||||||
if (requestType == "PaymentRequest")
|
if (requestType == BIP70_MESSAGE_PAYMENTREQUEST)
|
||||||
{
|
{
|
||||||
PaymentRequestPlus request;
|
PaymentRequestPlus request;
|
||||||
SendCoinsRecipient recipient;
|
SendCoinsRecipient recipient;
|
||||||
|
@ -676,7 +707,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (requestType == "PaymentACK")
|
else if (requestType == BIP70_MESSAGE_PAYMENTACK)
|
||||||
{
|
{
|
||||||
payments::PaymentACK paymentACK;
|
payments::PaymentACK paymentACK;
|
||||||
if (!paymentACK.ParseFromArray(data.data(), data.size()))
|
if (!paymentACK.ParseFromArray(data.data(), data.size()))
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// Copyright (c) 2011-2014 The Bitcoin developers
|
// Copyright (c) 2011-2014 The Bitcoin developers
|
||||||
// Distributed under the MIT/X11 software license, see the accompanying
|
// Distributed under the MIT software license, see the accompanying
|
||||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
#ifndef BITCOIN_QT_PAYMENTSERVER_H
|
#ifndef BITCOIN_QT_PAYMENTSERVER_H
|
||||||
|
@ -40,6 +40,8 @@
|
||||||
|
|
||||||
class OptionsModel;
|
class OptionsModel;
|
||||||
|
|
||||||
|
class CWallet;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QApplication;
|
class QApplication;
|
||||||
class QByteArray;
|
class QByteArray;
|
||||||
|
@ -50,7 +52,8 @@ class QSslError;
|
||||||
class QUrl;
|
class QUrl;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
class CWallet;
|
// BIP70 max payment request size in bytes (DoS protection)
|
||||||
|
extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE;
|
||||||
|
|
||||||
class PaymentServer : public QObject
|
class PaymentServer : public QObject
|
||||||
{
|
{
|
||||||
|
@ -59,7 +62,7 @@ class PaymentServer : public QObject
|
||||||
public:
|
public:
|
||||||
// Parse URIs on command line
|
// Parse URIs on command line
|
||||||
// Returns false on error
|
// Returns false on error
|
||||||
static bool ipcParseCommandLine(int argc, char *argv[]);
|
static void ipcParseCommandLine(int argc, char *argv[]);
|
||||||
|
|
||||||
// Returns true if there were URIs on the command line
|
// Returns true if there were URIs on the command line
|
||||||
// which were successfully sent to an already-running
|
// which were successfully sent to an already-running
|
||||||
|
@ -85,6 +88,9 @@ public:
|
||||||
// OptionsModel is used for getting proxy settings and display unit
|
// OptionsModel is used for getting proxy settings and display unit
|
||||||
void setOptionsModel(OptionsModel *optionsModel);
|
void setOptionsModel(OptionsModel *optionsModel);
|
||||||
|
|
||||||
|
// This is now public, because we use it in paymentservertests.cpp
|
||||||
|
static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// Fired when a valid payment request is received
|
// Fired when a valid payment request is received
|
||||||
void receivedPaymentRequest(SendCoinsRecipient);
|
void receivedPaymentRequest(SendCoinsRecipient);
|
||||||
|
@ -118,7 +124,6 @@ protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event);
|
bool eventFilter(QObject *object, QEvent *event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool readPaymentRequest(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);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "paymentrequestdata.h"
|
#include "paymentrequestdata.h"
|
||||||
|
|
||||||
|
#include "random.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "utilstrencodings.h"
|
#include "utilstrencodings.h"
|
||||||
|
|
||||||
|
@ -108,6 +109,17 @@ void PaymentServerTests::paymentServerTests()
|
||||||
r.paymentRequest.getMerchant(caStore, merchant);
|
r.paymentRequest.getMerchant(caStore, merchant);
|
||||||
QCOMPARE(merchant, QString(""));
|
QCOMPARE(merchant, QString(""));
|
||||||
|
|
||||||
|
// Just get some random data big enough to trigger BIP70 DoS protection
|
||||||
|
unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1];
|
||||||
|
GetRandBytes(randData, sizeof(randData));
|
||||||
|
// Write data to a temp file:
|
||||||
|
QTemporaryFile tempFile;
|
||||||
|
tempFile.open();
|
||||||
|
tempFile.write((const char*)randData, sizeof(randData));
|
||||||
|
tempFile.close();
|
||||||
|
// Trigger BIP70 DoS protection
|
||||||
|
QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
|
||||||
|
|
||||||
delete server;
|
delete server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue