|
|
@ -148,7 +148,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) |
|
|
|
int nRootCerts = 0; |
|
|
|
int nRootCerts = 0; |
|
|
|
const QDateTime currentTime = QDateTime::currentDateTime(); |
|
|
|
const QDateTime currentTime = QDateTime::currentDateTime(); |
|
|
|
|
|
|
|
|
|
|
|
foreach (const QSslCertificate& cert, certList) { |
|
|
|
Q_FOREACH (const QSslCertificate& cert, certList) { |
|
|
|
// Don't log NULL certificates
|
|
|
|
// Don't log NULL certificates
|
|
|
|
if (cert.isNull()) |
|
|
|
if (cert.isNull()) |
|
|
|
continue; |
|
|
|
continue; |
|
|
@ -201,7 +201,7 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store) |
|
|
|
// when uiReady() is called.
|
|
|
|
// when uiReady() is called.
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// 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 "Q_EMIT message()", but "QMessageBox::"!
|
|
|
|
//
|
|
|
|
//
|
|
|
|
void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) |
|
|
|
void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -269,7 +269,7 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) |
|
|
|
bool PaymentServer::ipcSendCommandLine() |
|
|
|
bool PaymentServer::ipcSendCommandLine() |
|
|
|
{ |
|
|
|
{ |
|
|
|
bool fResult = false; |
|
|
|
bool fResult = false; |
|
|
|
foreach (const QString& r, savedPaymentRequests) |
|
|
|
Q_FOREACH (const QString& r, savedPaymentRequests) |
|
|
|
{ |
|
|
|
{ |
|
|
|
QLocalSocket* socket = new QLocalSocket(); |
|
|
|
QLocalSocket* socket = new QLocalSocket(); |
|
|
|
socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); |
|
|
|
socket->connectToServer(ipcServerName(), QIODevice::WriteOnly); |
|
|
@ -326,7 +326,7 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : |
|
|
|
uriServer = new QLocalServer(this); |
|
|
|
uriServer = new QLocalServer(this); |
|
|
|
|
|
|
|
|
|
|
|
if (!uriServer->listen(name)) { |
|
|
|
if (!uriServer->listen(name)) { |
|
|
|
// constructor is called early in init, so don't use "emit message()" here
|
|
|
|
// constructor is called early in init, so don't use "Q_EMIT message()" here
|
|
|
|
QMessageBox::critical(0, tr("Payment request error"), |
|
|
|
QMessageBox::critical(0, tr("Payment request error"), |
|
|
|
tr("Cannot start bitcoin: click-to-pay handler")); |
|
|
|
tr("Cannot start bitcoin: click-to-pay handler")); |
|
|
|
} |
|
|
|
} |
|
|
@ -394,7 +394,7 @@ void PaymentServer::uiReady() |
|
|
|
initNetManager(); |
|
|
|
initNetManager(); |
|
|
|
|
|
|
|
|
|
|
|
saveURIs = false; |
|
|
|
saveURIs = false; |
|
|
|
foreach (const QString& s, savedPaymentRequests) |
|
|
|
Q_FOREACH (const QString& s, savedPaymentRequests) |
|
|
|
{ |
|
|
|
{ |
|
|
|
handleURIOrFile(s); |
|
|
|
handleURIOrFile(s); |
|
|
|
} |
|
|
|
} |
|
|
@ -431,7 +431,7 @@ void PaymentServer::handleURIOrFile(const QString& s) |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; |
|
|
|
qWarning() << "PaymentServer::handleURIOrFile: Invalid URL: " << fetchUrl; |
|
|
|
emit message(tr("URI handling"), |
|
|
|
Q_EMIT message(tr("URI handling"), |
|
|
|
tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), |
|
|
|
tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()), |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
} |
|
|
|
} |
|
|
@ -445,14 +445,14 @@ void PaymentServer::handleURIOrFile(const QString& s) |
|
|
|
{ |
|
|
|
{ |
|
|
|
CBitcoinAddress address(recipient.address.toStdString()); |
|
|
|
CBitcoinAddress address(recipient.address.toStdString()); |
|
|
|
if (!address.IsValid()) { |
|
|
|
if (!address.IsValid()) { |
|
|
|
emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), |
|
|
|
Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
emit receivedPaymentRequest(recipient); |
|
|
|
Q_EMIT receivedPaymentRequest(recipient); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
emit message(tr("URI handling"), |
|
|
|
Q_EMIT message(tr("URI handling"), |
|
|
|
tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), |
|
|
|
tr("URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters."), |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
|
|
|
|
|
|
|
@ -466,12 +466,12 @@ void PaymentServer::handleURIOrFile(const QString& s) |
|
|
|
SendCoinsRecipient recipient; |
|
|
|
SendCoinsRecipient recipient; |
|
|
|
if (!readPaymentRequestFromFile(s, request)) |
|
|
|
if (!readPaymentRequestFromFile(s, request)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
emit message(tr("Payment request file handling"), |
|
|
|
Q_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."), |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
CClientUIInterface::ICON_WARNING); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (processPaymentRequest(request, recipient)) |
|
|
|
else if (processPaymentRequest(request, recipient)) |
|
|
|
emit receivedPaymentRequest(recipient); |
|
|
|
Q_EMIT receivedPaymentRequest(recipient); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -500,7 +500,7 @@ void PaymentServer::handleURIConnection() |
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
//
|
|
|
|
// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
|
|
|
|
// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine()
|
|
|
|
// so don't use "emit message()", but "QMessageBox::"!
|
|
|
|
// so don't use "Q_EMIT message()", but "QMessageBox::"!
|
|
|
|
//
|
|
|
|
//
|
|
|
|
bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) |
|
|
|
bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) |
|
|
|
{ |
|
|
|
{ |
|
|
@ -533,7 +533,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
if (request.IsInitialized()) { |
|
|
|
if (request.IsInitialized()) { |
|
|
|
// Payment request network matches client network?
|
|
|
|
// Payment request network matches client network?
|
|
|
|
if (!verifyNetwork(request.getDetails())) { |
|
|
|
if (!verifyNetwork(request.getDetails())) { |
|
|
|
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), |
|
|
|
Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -542,13 +542,13 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
// Make sure any payment requests involved are still valid.
|
|
|
|
// Make sure any payment requests involved are still valid.
|
|
|
|
// This is re-checked just before sending coins in WalletModel::sendCoins().
|
|
|
|
// This is re-checked just before sending coins in WalletModel::sendCoins().
|
|
|
|
if (verifyExpired(request.getDetails())) { |
|
|
|
if (verifyExpired(request.getDetails())) { |
|
|
|
emit message(tr("Payment request rejected"), tr("Payment request expired."), |
|
|
|
Q_EMIT message(tr("Payment request rejected"), tr("Payment request expired."), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
emit message(tr("Payment request error"), tr("Payment request is not initialized."), |
|
|
|
Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -562,7 +562,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); |
|
|
|
QList<std::pair<CScript, CAmount> > sendingTos = request.getPayTo(); |
|
|
|
QStringList addresses; |
|
|
|
QStringList addresses; |
|
|
|
|
|
|
|
|
|
|
|
foreach(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { |
|
|
|
Q_FOREACH(const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) { |
|
|
|
// Extract and check destination addresses
|
|
|
|
// Extract and check destination addresses
|
|
|
|
CTxDestination dest; |
|
|
|
CTxDestination dest; |
|
|
|
if (ExtractDestination(sendingTo.first, dest)) { |
|
|
|
if (ExtractDestination(sendingTo.first, dest)) { |
|
|
@ -573,7 +573,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
// Unauthenticated payment requests to custom bitcoin addresses are not supported
|
|
|
|
// Unauthenticated payment requests 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
|
|
|
|
// (there is no good way to tell the user where they are paying in a way they'd
|
|
|
|
// have a chance of understanding).
|
|
|
|
// have a chance of understanding).
|
|
|
|
emit message(tr("Payment request rejected"), |
|
|
|
Q_EMIT message(tr("Payment request rejected"), |
|
|
|
tr("Unverified payment requests to custom payment scripts are unsupported."), |
|
|
|
tr("Unverified payment requests to custom payment scripts are unsupported."), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -583,14 +583,14 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
// but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
|
|
|
|
// but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
|
|
|
|
// and no overflow has happened.
|
|
|
|
// and no overflow has happened.
|
|
|
|
if (!verifyAmount(sendingTo.second)) { |
|
|
|
if (!verifyAmount(sendingTo.second)) { |
|
|
|
emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Extract and check amounts
|
|
|
|
// Extract and check amounts
|
|
|
|
CTxOut txOut(sendingTo.second, sendingTo.first); |
|
|
|
CTxOut txOut(sendingTo.second, sendingTo.first); |
|
|
|
if (txOut.IsDust(::minRelayTxFee)) { |
|
|
|
if (txOut.IsDust(::minRelayTxFee)) { |
|
|
|
emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") |
|
|
|
Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).") |
|
|
|
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), |
|
|
|
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
|
|
|
|
|
|
|
@ -600,7 +600,7 @@ bool PaymentServer::processPaymentRequest(const PaymentRequestPlus& request, Sen |
|
|
|
recipient.amount += sendingTo.second; |
|
|
|
recipient.amount += sendingTo.second; |
|
|
|
// Also verify that the final amount is still in a valid range after adding additional amounts.
|
|
|
|
// Also verify that the final amount is still in a valid range after adding additional amounts.
|
|
|
|
if (!verifyAmount(recipient.amount)) { |
|
|
|
if (!verifyAmount(recipient.amount)) { |
|
|
|
emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR); |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -694,7 +694,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) |
|
|
|
.arg(BIP70_MAX_PAYMENTREQUEST_SIZE); |
|
|
|
.arg(BIP70_MAX_PAYMENTREQUEST_SIZE); |
|
|
|
|
|
|
|
|
|
|
|
qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; |
|
|
|
qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; |
|
|
|
emit message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -704,7 +704,7 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) |
|
|
|
.arg(reply->errorString()); |
|
|
|
.arg(reply->errorString()); |
|
|
|
|
|
|
|
|
|
|
|
qWarning() << "PaymentServer::netRequestFinished: " << msg; |
|
|
|
qWarning() << "PaymentServer::netRequestFinished: " << msg; |
|
|
|
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -718,12 +718,12 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) |
|
|
|
if (!request.parse(data)) |
|
|
|
if (!request.parse(data)) |
|
|
|
{ |
|
|
|
{ |
|
|
|
qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; |
|
|
|
qWarning() << "PaymentServer::netRequestFinished: Error parsing payment request"; |
|
|
|
emit message(tr("Payment request error"), |
|
|
|
Q_EMIT message(tr("Payment request error"), |
|
|
|
tr("Payment request cannot be parsed!"), |
|
|
|
tr("Payment request cannot be parsed!"), |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
CClientUIInterface::MSG_ERROR); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (processPaymentRequest(request, recipient)) |
|
|
|
else if (processPaymentRequest(request, recipient)) |
|
|
|
emit receivedPaymentRequest(recipient); |
|
|
|
Q_EMIT receivedPaymentRequest(recipient); |
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -736,11 +736,11 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply) |
|
|
|
.arg(reply->request().url().toString()); |
|
|
|
.arg(reply->request().url().toString()); |
|
|
|
|
|
|
|
|
|
|
|
qWarning() << "PaymentServer::netRequestFinished: " << msg; |
|
|
|
qWarning() << "PaymentServer::netRequestFinished: " << msg; |
|
|
|
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
emit receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); |
|
|
|
Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -750,11 +750,11 @@ void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> |
|
|
|
Q_UNUSED(reply); |
|
|
|
Q_UNUSED(reply); |
|
|
|
|
|
|
|
|
|
|
|
QString errString; |
|
|
|
QString errString; |
|
|
|
foreach (const QSslError& err, errs) { |
|
|
|
Q_FOREACH (const QSslError& err, errs) { |
|
|
|
qWarning() << "PaymentServer::reportSslErrors: " << err; |
|
|
|
qWarning() << "PaymentServer::reportSslErrors: " << err; |
|
|
|
errString += err.errorString() + "\n"; |
|
|
|
errString += err.errorString() + "\n"; |
|
|
|
} |
|
|
|
} |
|
|
|
emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); |
|
|
|
Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void PaymentServer::setOptionsModel(OptionsModel *optionsModel) |
|
|
|
void PaymentServer::setOptionsModel(OptionsModel *optionsModel) |
|
|
@ -765,7 +765,7 @@ void PaymentServer::setOptionsModel(OptionsModel *optionsModel) |
|
|
|
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) |
|
|
|
void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) |
|
|
|
{ |
|
|
|
{ |
|
|
|
// currently we don't futher process or store the paymentACK message
|
|
|
|
// currently we don't futher process or store the paymentACK message
|
|
|
|
emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); |
|
|
|
Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails) |
|
|
|
bool PaymentServer::verifyNetwork(const payments::PaymentDetails& requestDetails) |
|
|
|