From 7120d76dc6fc9d86aac5d3a5454f248de5a5853f Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Tue, 26 Nov 2013 12:52:21 +0100 Subject: Store and use a sanitized subVer Rebased-from: a946aa8d3ec7009ac670eeb65a525efe5eeb6e84 --- src/main.cpp | 10 ++++++---- src/net.cpp | 2 +- src/net.h | 8 ++++++-- src/rpcnet.cpp | 5 ++++- 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index b0a6e36236..f8f194afc5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3216,8 +3216,10 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->nVersion = 300; if (!vRecv.empty()) vRecv >> addrFrom >> nNonce; - if (!vRecv.empty()) + if (!vRecv.empty()) { vRecv >> pfrom->strSubVer; + pfrom->cleanSubVer = SanitizeString(pfrom->strSubVer); + } if (!vRecv.empty()) vRecv >> pfrom->nStartingHeight; if (!vRecv.empty()) @@ -3285,7 +3287,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) pfrom->fSuccessfullyConnected = true; - printf("receive version message: %s: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->strSubVer.c_str(), pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); + printf("receive version message: %s: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->cleanSubVer.c_str(), pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str()); cPeerBlockCounts.input(pfrom->nStartingHeight); } @@ -3534,7 +3536,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) vEraseQueue.push_back(inv.hash); printf("AcceptToMemoryPool: %s %s : accepted %s (poolsz %"PRIszu")\n", - pfrom->addr.ToString().c_str(), pfrom->strSubVer.c_str(), + pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str(), tx.GetHash().ToString().c_str(), mempool.mapTx.size()); @@ -3587,7 +3589,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) if (state.IsInvalid(nDoS)) { printf("%s from %s %s was not accepted into the memory pool\n", tx.GetHash().ToString().c_str(), - pfrom->addr.ToString().c_str(), pfrom->strSubVer.c_str()); + pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str()); if (nDoS > 0) pfrom->Misbehaving(nDoS); } diff --git a/src/net.cpp b/src/net.cpp index e5f85d3290..f40afde20f 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -612,7 +612,7 @@ void CNode::copyStats(CNodeStats &stats) X(nTimeConnected); X(addrName); X(nVersion); - X(strSubVer); + X(cleanSubVer); X(fInbound); X(nStartingHeight); X(nMisbehavior); diff --git a/src/net.h b/src/net.h index 6f315f74fd..dfdd3c8137 100644 --- a/src/net.h +++ b/src/net.h @@ -98,7 +98,7 @@ public: int64 nTimeConnected; std::string addrName; int nVersion; - std::string strSubVer; + std::string cleanSubVer; bool fInbound; int nStartingHeight; int nMisbehavior; @@ -177,7 +177,11 @@ public: std::string addrName; CService addrLocal; int nVersion; - std::string strSubVer; + // strSubVer is whatever byte array we read from the wire. However, this field is intended + // to be printed out, displayed to humans in various forms and so on. So we sanitize it and + // store the sanitized version in cleanSubVer. The original should be used when dealing with + // the network or wire types and the cleaned string used when displayed or logged. + std::string strSubVer, cleanSubVer; bool fOneShot; bool fClient; bool fInbound; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 644c2675ae..99b94ffa3a 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -55,7 +55,10 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes)); obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); obj.push_back(Pair("version", stats.nVersion)); - obj.push_back(Pair("subver", stats.strSubVer)); + // Use the sanitized form of subver here, to avoid tricksy remote peers from + // corrupting or modifiying the JSON output by putting special characters in + // their ver message. + obj.push_back(Pair("subver", stats.cleanSubVer)); obj.push_back(Pair("inbound", stats.fInbound)); obj.push_back(Pair("startingheight", stats.nStartingHeight)); obj.push_back(Pair("banscore", stats.nMisbehavior)); -- cgit v1.2.3