aboutsummaryrefslogtreecommitdiff
path: root/src/qt/paymentserver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qt/paymentserver.cpp')
-rw-r--r--src/qt/paymentserver.cpp129
1 files changed, 81 insertions, 48 deletions
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index ca6ae17990..5471625a67 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -44,6 +44,7 @@
#include <QUrlQuery>
#endif
+using namespace std;
using namespace boost;
const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
@@ -89,7 +90,7 @@ static QList<QString> savedPaymentRequests;
static void ReportInvalidCertificate(const QSslCertificate& cert)
{
- qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
+ qWarning() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
}
//
@@ -160,7 +161,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
continue;
}
}
- qDebug() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
+ qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
// Project for another day:
// Fetch certificate revocation lists, and add them to certStore.
@@ -178,6 +179,9 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
// and the items in savedPaymentRequest will be handled
// when uiReady() is called.
//
+// Warning: ipcSendCommandLine() is called early in init,
+// so don't use "emit message()", but "QMessageBox::"!
+//
bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
{
for (int i = 1; i < argc; i++)
@@ -191,14 +195,14 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
savedPaymentRequests.append(arg);
SendCoinsRecipient r;
- if (GUIUtil::parseBitcoinURI(arg, &r))
+ if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty())
{
CBitcoinAddress address(r.address.toStdString());
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
if (!address.IsValid())
{
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
}
}
}
@@ -210,16 +214,16 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
if (readPaymentRequest(arg, request))
{
if (request.getDetails().network() == "main")
- SelectParams(CChainParams::MAIN);
+ SelectParams(CBaseChainParams::MAIN);
else
- SelectParams(CChainParams::TESTNET);
+ SelectParams(CBaseChainParams::TESTNET);
}
}
else
{
// Printing to debug.log is about the best we can do here, the
// GUI hasn't started yet so we can't pop up a message box.
- qDebug() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
+ qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
}
}
return true;
@@ -337,20 +341,14 @@ void PaymentServer::initNetManager()
QNetworkProxy proxy;
- // Query active proxy (fails if no SOCKS5 proxy)
+ // Query active SOCKS5 proxy
if (optionsModel->getProxySettings(proxy)) {
- if (proxy.type() == QNetworkProxy::Socks5Proxy) {
- netManager->setProxy(proxy);
+ netManager->setProxy(proxy);
- qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
- }
- else
- qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
+ qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
}
else
- emit message(tr("Net manager warning"),
- tr("Your active proxy doesn't support SOCKS5, which is required for payment requests via proxy."),
- CClientUIInterface::MSG_WARNING);
+ qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
connect(netManager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(netRequestFinished(QNetworkReply*)));
@@ -399,7 +397,7 @@ void PaymentServer::handleURIOrFile(const QString& s)
}
else
{
- qDebug() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
+ qWarning() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
emit message(tr("URI handling"),
tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
CClientUIInterface::ICON_WARNING);
@@ -411,7 +409,15 @@ void PaymentServer::handleURIOrFile(const QString& s)
{
SendCoinsRecipient recipient;
if (GUIUtil::parseBitcoinURI(s, &recipient))
- emit receivedPaymentRequest(recipient);
+ {
+ CBitcoinAddress address(recipient.address.toStdString());
+ if (!address.IsValid()) {
+ emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address),
+ CClientUIInterface::MSG_ERROR);
+ }
+ else
+ emit receivedPaymentRequest(recipient);
+ }
else
emit message(tr("URI handling"),
tr("URI can not be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."),
@@ -425,12 +431,14 @@ void PaymentServer::handleURIOrFile(const QString& s)
{
PaymentRequestPlus request;
SendCoinsRecipient recipient;
- if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient))
- emit receivedPaymentRequest(recipient);
- else
+ if (!readPaymentRequest(s, request))
+ {
emit message(tr("Payment request file handling"),
- tr("Payment request file can not be read or processed! This can be caused by an invalid payment request file."),
+ tr("Payment request file can not be read! This can be caused by an invalid payment request file."),
CClientUIInterface::ICON_WARNING);
+ }
+ else if (processPaymentRequest(request, recipient))
+ emit receivedPaymentRequest(recipient);
return;
}
@@ -462,13 +470,13 @@ bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPl
QFile f(filename);
if (!f.open(QIODevice::ReadOnly))
{
- qDebug() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
+ qWarning() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
return false;
}
if (f.size() > MAX_PAYMENT_REQUEST_SIZE)
{
- qDebug() << "PaymentServer::readPaymentRequest : " << filename << " too large";
+ qWarning() << "PaymentServer::readPaymentRequest : " << filename << " too large";
return false;
}
@@ -482,6 +490,34 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
if (!optionsModel)
return false;
+ if (request.IsInitialized()) {
+ const payments::PaymentDetails& details = request.getDetails();
+
+ // Payment request network matches client network?
+ if (details.network() != Params().NetworkIDString())
+ {
+ emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+
+ // Expired payment request?
+ if (details.has_expires() && (int64_t)details.expires() < GetTime())
+ {
+ emit message(tr("Payment request rejected"), tr("Payment request has expired."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+ }
+ else {
+ emit message(tr("Payment request error"), tr("Payment request is not initialized."),
+ CClientUIInterface::MSG_ERROR);
+
+ return false;
+ }
+
recipient.paymentRequest = request;
recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
@@ -497,11 +533,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
// Append destination address
addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
}
- else if (!recipient.authenticatedMerchant.isEmpty()){
+ else if (!recipient.authenticatedMerchant.isEmpty()) {
// Insecure payments to custom bitcoin addresses are not supported
// (there is no good way to tell the user where they are paying in a way
// they'd have a chance of understanding).
- emit message(tr("Payment request error"),
+ emit message(tr("Payment request rejected"),
tr("Unverified payment requests to custom payment scripts are unsupported."),
CClientUIInterface::MSG_ERROR);
return false;
@@ -509,12 +545,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
- if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
- QString msg = tr("Requested payment amount of %1 is too small (considered dust).")
- .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second));
+ if (txOut.IsDust(::minRelayTxFee)) {
+ emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
+ .arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
+ CClientUIInterface::MSG_ERROR);
- qDebug() << "PaymentServer::processPaymentRequest : " << msg;
- emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
return false;
}
@@ -581,9 +616,9 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
refund_to->set_script(&s[0], s.size());
}
else {
- // This should never happen, because sending coins should have just unlocked the wallet
- // and refilled the keypool
- qDebug() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
+ // This should never happen, because sending coins should have
+ // just unlocked the wallet and refilled the keypool.
+ qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
}
}
@@ -594,8 +629,8 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
netManager->post(netRequest, serData);
}
else {
- // This should never happen, either:
- qDebug() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
+ // This should never happen, either.
+ qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
}
}
@@ -608,7 +643,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
.arg(reply->request().url().toString())
.arg(reply->errorString());
- qDebug() << "PaymentServer::netRequestFinished : " << msg;
+ qWarning() << "PaymentServer::netRequestFinished : " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
return;
}
@@ -620,17 +655,15 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
{
PaymentRequestPlus request;
SendCoinsRecipient recipient;
- if (request.parse(data) && processPaymentRequest(request, recipient))
+ if (!request.parse(data))
{
- emit receivedPaymentRequest(recipient);
- }
- else
- {
- qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";
+ qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request";
emit message(tr("Payment request error"),
- tr("Payment request can not be parsed or processed!"),
+ tr("Payment request can not be parsed!"),
CClientUIInterface::MSG_ERROR);
}
+ else if (processPaymentRequest(request, recipient))
+ emit receivedPaymentRequest(recipient);
return;
}
@@ -642,7 +675,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
QString msg = tr("Bad response from server %1")
.arg(reply->request().url().toString());
- qDebug() << "PaymentServer::netRequestFinished : " << msg;
+ qWarning() << "PaymentServer::netRequestFinished : " << msg;
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
}
else
@@ -658,7 +691,7 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError>
QString errString;
foreach (const QSslError& err, errs) {
- qDebug() << "PaymentServer::reportSslErrors : " << err;
+ qWarning() << "PaymentServer::reportSslErrors : " << err;
errString += err.errorString() + "\n";
}
emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);