aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorGavin Andresen <[email protected]>2012-08-27 12:39:13 -0400
committerGavin Andresen <[email protected]>2012-08-27 12:39:13 -0400
commitfde5c34bd8cfe8b24321028a8daa7cfee8c7f5c8 (patch)
tree451e3377a9e22d7adaf7deb6e9331a9a75d18868 /src/main.cpp
parentFix compiler warning on mac (diff)
parentSpecial-case the last alert for alert-key-compromised case (diff)
downloaddiscoin-fde5c34bd8cfe8b24321028a8daa7cfee8c7f5c8.tar.xz
discoin-fde5c34bd8cfe8b24321028a8daa7cfee8c7f5c8.zip
Merge branch 'alert_fix' of git://github.com/gavinandresen/bitcoin-git
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/src/main.cpp b/src/main.cpp
index f71cfe7ca..71d425e15 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2322,6 +2322,28 @@ bool CAlert::ProcessAlert()
if (!IsInEffect())
return false;
+ // alert.nID=max is reserved for if the alert key is
+ // compromised. It must have a pre-defined message,
+ // must never expire, must apply to all versions,
+ // and must cancel all previous
+ // alerts or it will be ignored (so an attacker can't
+ // send an "everything is OK, don't panic" version that
+ // cannot be overridden):
+ int maxInt = std::numeric_limits<int>::max();
+ if (nID == maxInt)
+ {
+ if (!(
+ nExpiration == maxInt &&
+ nCancel == (maxInt-1) &&
+ nMinVer == 0 &&
+ nMaxVer == maxInt &&
+ setSubVer.empty() &&
+ nPriority == maxInt &&
+ strStatusBar == "URGENT: Alert key compromised, upgrade required"
+ ))
+ return false;
+ }
+
{
LOCK(cs_mapAlerts);
// Cancel previous alerts
@@ -2997,14 +3019,27 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CAlert alert;
vRecv >> alert;
- if (alert.ProcessAlert())
+ uint256 alertHash = alert.GetHash();
+ if (pfrom->setKnown.count(alertHash) == 0)
{
- // Relay
- pfrom->setKnown.insert(alert.GetHash());
+ if (alert.ProcessAlert())
{
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- alert.RelayTo(pnode);
+ // Relay
+ pfrom->setKnown.insert(alertHash);
+ {
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ alert.RelayTo(pnode);
+ }
+ }
+ else {
+ // Small DoS penalty so peers that send us lots of
+ // duplicate/expired/invalid-signature/whatever alerts
+ // eventually get banned.
+ // This isn't a Misbehaving(100) (immediate ban) because the
+ // peer might be an older or different implementation with
+ // a different signature key, etc.
+ pfrom->Misbehaving(10);
}
}
}