upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp115
1 files changed, 37 insertions, 78 deletions
diff --git a/src/main.cpp b/src/main.cpp
index 62068d2..efff96c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -2782,9 +2782,10 @@ bool AlreadyHave(CTxDB& txdb, const CInv& inv)
2782 { 2782 {
2783 case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash); 2783 case MSG_TX: return mapTransactions.count(inv.hash) || txdb.ContainsTx(inv.hash);
2784 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash); 2784 case MSG_BLOCK: return mapBlockIndex.count(inv.hash) || mapOrphanBlocks.count(inv.hash);
2785 case MSG_REVIEW: return true;
2786 case MSG_PRODUCT: return mapProducts.count(inv.hash);
2787 } 2785 }
2786 // MSG_REVIEW / MSG_PRODUCT / MSG_TABLE are the 2009 marketplace inventory
2787 // types. Nothing announces or serves them any more (see ProcessMessage),
2788 // so they fall through to the default and are never requested.
2788 // Don't know what it is, just say we already got one 2789 // Don't know what it is, just say we already got one
2789 return true; 2790 return true;
2790} 2791}
@@ -2942,7 +2943,6 @@ bool ProcessMessages(CNode* pfrom)
2942 2943
2943bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) 2944bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
2944{ 2945{
2945 static map<unsigned int, vector<unsigned char> > mapReuseKey;
2946 if (LogAcceptsCategory("net")) { printf("received: %-12s (%d bytes) ", strCommand.c_str(), (int)vRecv.size()); for (int i = 0; i < min(vRecv.size(), (unsigned int)25); i++) printf("%02x ", vRecv[i] & 0xff); printf("\n"); } 2946 if (LogAcceptsCategory("net")) { printf("received: %-12s (%d bytes) ", strCommand.c_str(), (int)vRecv.size()); for (int i = 0; i < min(vRecv.size(), (unsigned int)25); i++) printf("%02x ", vRecv[i] & 0xff); printf("\n"); }
2947 if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0) 2947 if (nDropMessagesTest > 0 && GetRand(nDropMessagesTest) == 0)
2948 { 2948 {
@@ -3181,22 +3181,18 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3181 } 3181 }
3182 3182
3183 3183
3184 else if (strCommand == "review") 3184 // "review" used to be handled here. It took a CReview off the wire from an
3185 { 3185 // unauthenticated peer, checked a signature the sender had made with a key
3186 CDataStream vMsg(vRecv); 3186 // of its own choosing -- which proves possession of that key and authorises
3187 CReview review; 3187 // nothing -- and then appended the message to reviews.dat by reading the
3188 vRecv >> review; 3188 // whole vector for the target hash, pushing one entry, and writing all of
3189 3189 // it back. That is quadratic disk for a stream an attacker controls, on a
3190 CInv inv(MSG_REVIEW, review.GetHash()); 3190 // record whose mapValue is an unbounded map<string,string> read straight
3191 pfrom->AddInventoryKnown(inv); 3191 // from the socket, followed by AddAtomsAndPropagate walking a link graph
3192 3192 // the same peer supplied, and finally RelayMessage forwarding it to every
3193 if (review.AcceptReview()) 3193 // other node. Unbounded remote disk growth with network amplification and
3194 { 3194 // no authorisation anywhere in the path. The marketplace it belonged to has
3195 // Relay the original message as-is in case it's a higher version than we know how to parse 3195 // not existed since 2009; the handler is gone rather than bounded.
3196 RelayMessage(inv, vMsg);
3197 mapAlreadyAskedFor.erase(inv);
3198 }
3199 }
3200 3196
3201 3197
3202 else if (strCommand == "block") 3198 else if (strCommand == "block")
@@ -3229,65 +3225,28 @@ bool ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
3229 } 3225 }
3230 3226
3231 3227
3232 else if (strCommand == "checkorder") 3228 // "checkorder", "submitorder" and "reply" -- the 2009 buy-from-a-merchant
3233 { 3229 // exchange -- used to be handled here. All three are gone.
3234 uint256 hashReply; 3230 //
3235 CWalletTx order; 3231 // "checkorder" called GenerateNewKey() for any peer that asked, which is
3236 vRecv >> hashReply >> order; 3232 // AddKey() and a wallet.dat write, and handed the pubkey back. The comment
3237 3233 // said "keep giving the same key to the same ip until they use it", and on
3238 /// we have a chance to check the order here 3234 // a 2009 network of routable IPs that held. It does not hold here: every
3239 3235 // inbound peer arrives through a rendezvous tunnel and is tagged with
3240 // Keep giving the same key to the same ip until they use it 3236 // BtfMarkerAddr() over three random bytes (net.cpp), so addr.ip is freshly
3241 if (!mapReuseKey.count(pfrom->addr.ip)) 3237 // random per connection and the cache never hits. Reconnect in a loop and
3242 mapReuseKey[pfrom->addr.ip] = GenerateNewKey(); 3238 // the node mints a key per connection -- unbounded wallet growth, unbounded
3243 3239 // growth of the static map that held them, and every one of those keys
3244 // Send back approval of order and pubkey to use 3240 // missing from every backup taken beforehand, which for this pre-BIP32
3245 CScript scriptPubKey; 3241 // wallet is how coins are lost.
3246 scriptPubKey << mapReuseKey[pfrom->addr.ip] << OP_CHECKSIG; 3242 //
3247 pfrom->PushMessage("reply", hashReply, (int)0, scriptPubKey); 3243 // "submitorder" took a CWalletTx from an unauthenticated peer and, if it
3248 } 3244 // was merely a valid transaction, AddToWallet()'d it. Valid is not the same
3249 3245 // as ours: any peer could write chosen transactions into wallet.dat.
3250 3246 //
3251 else if (strCommand == "submitorder") 3247 // "reply" dispatched to a CRequestTracker callback. Nothing in this tree
3252 { 3248 // has ever called PushRequest, so mapRequests was permanently empty and the
3253 uint256 hashReply; 3249 // handler could only ever be a parser for hostile input.
3254 CWalletTx wtxNew;
3255 vRecv >> hashReply >> wtxNew;
3256
3257 // Broadcast
3258 if (!wtxNew.AcceptWalletTransaction())
3259 {
3260 pfrom->PushMessage("reply", hashReply, (int)1);
3261 return error("submitorder AcceptWalletTransaction() failed, returning error 1");
3262 }
3263 wtxNew.fTimeReceivedIsTxTime = true;
3264 AddToWallet(wtxNew);
3265 wtxNew.RelayWalletTransaction();
3266 mapReuseKey.erase(pfrom->addr.ip);
3267
3268 // Send back confirmation
3269 pfrom->PushMessage("reply", hashReply, (int)0);
3270 }
3271
3272
3273 else if (strCommand == "reply")
3274 {
3275 uint256 hashReply;
3276 vRecv >> hashReply;
3277
3278 CRequestTracker tracker;
3279 CRITICAL_BLOCK(pfrom->cs_mapRequests)
3280 {
3281 map<uint256, CRequestTracker>::iterator mi = pfrom->mapRequests.find(hashReply);
3282 if (mi != pfrom->mapRequests.end())
3283 {
3284 tracker = (*mi).second;
3285 pfrom->mapRequests.erase(mi);
3286 }
3287 }
3288 if (!tracker.IsNull())
3289 tracker.fn(tracker.param1, vRecv);
3290 }
3291 3250
3292 3251
3293 else if (strCommand == "ping") 3252 else if (strCommand == "ping")