From bc990abfffbf2268d4beaccea899e69b36cda8d4 Mon Sep 17 00:00:00 2001 From: Miguel Freitas Date: Fri, 22 Nov 2013 17:33:07 -0200 Subject: [PATCH] "hexcape" binary strings before json encoding. because json doesn't support binary we need to escape to hex, unfortunatly, this add requirement to twisterd to know each possible binary field we may add to dht items. (unlike bencode that simply doesn't care). --- src/twister.cpp | 16 ++++++- src/twister_utils.cpp | 100 ++++++++++++++++++++++++++++++++++++++++++ src/twister_utils.h | 6 +++ 3 files changed, 120 insertions(+), 2 deletions(-) diff --git a/src/twister.cpp b/src/twister.cpp index 2fa87516..090512a1 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -1115,6 +1115,8 @@ Value dhtput(const Array& params, bool fHelp) string strResource = params[1].get_str(); string strMulti = params[2].get_str(); entry value = jsonToEntry(params[3]); + // value is already "p":"v": contents, so post may be unhexcaped directly + unHexcapePost(value); string strSigUser = params[4].get_str(); // Test for private key here to avoid going into dht @@ -1173,7 +1175,12 @@ Value dhtget(const Array& params, bool fHelp) dht_reply_data_alert const* rd = alert_cast(&(*a)); if( rd ) { - ret = entryToJson(rd->m_lst); + entry::list_type dhtLst = rd->m_lst; + entry::list_type::iterator it; + for( it = dhtLst.begin(); it != dhtLst.end(); ++it ) { + hexcapeDht( *it ); + } + ret = entryToJson(dhtLst); } else { // cast failed => dht_reply_data_done_alert => no data } @@ -1293,6 +1300,7 @@ Value newpostmsg(const Array& params, bool fHelp) } } + hexcapePost(v); return entryToJson(v); } @@ -1341,6 +1349,7 @@ Value newdirectmsg(const Array& params, bool fHelp) torrent_handle h = startTorrentUser(strFrom); h.add_piece(k,buf.data(),buf.size()); + hexcapePost(v); return entryToJson(v); } @@ -1357,6 +1366,7 @@ Value newrtmsg(const Array& params, bool fHelp) int k = params[1].get_int(); string strK = boost::lexical_cast(k); entry vrt = jsonToEntry(params[2].get_obj()); + unHexcapePost(vrt); entry const *rt = vrt.find_key("userpost"); entry const *sig_rt= vrt.find_key("sig_userpost"); @@ -1402,6 +1412,7 @@ Value newrtmsg(const Array& params, bool fHelp) v, strUsername, GetAdjustedTime(), 0); } + hexcapePost(v); return entryToJson(v); } @@ -1446,6 +1457,7 @@ Value getposts(const Array& params, bool fHelp) entry vEntry; vEntry = v; + hexcapePost(vEntry); postsByTime.insert( pair(time, vEntry) ); } } @@ -1477,7 +1489,7 @@ Value getposts(const Array& params, bool fHelp) unsigned char vchSig[65]; RAND_bytes(vchSig,sizeof(vchSig)); - v["sig_userpost"] = std::string((const char *)vchSig, sizeof(vchSig)); + v["sig_userpost"] = HexStr( string((const char *)vchSig, sizeof(vchSig)) ); ret.insert(ret.begin(),entryToJson(v)); m_receivedSpamMsgStr = ""; diff --git a/src/twister_utils.cpp b/src/twister_utils.cpp index aaf36ed8..a8c71470 100644 --- a/src/twister_utils.cpp +++ b/src/twister_utils.cpp @@ -1,5 +1,7 @@ #include "twister_utils.h" +#include "util.h" + #include #include @@ -230,3 +232,101 @@ data_error: } +void findAndHexcape(libtorrent::entry &e, string const& key) +{ + if( e.type() == libtorrent::entry::dictionary_t && + e.find_key(key) && e[key].type() == libtorrent::entry::string_t ) { + e[key] = HexStr(e[key].string()); + } +} + +void findAndUnHexcape(libtorrent::entry &e, string const& key) +{ + if( e.type() == libtorrent::entry::dictionary_t && + e.find_key(key) && e[key].type() == libtorrent::entry::string_t ) { + vector vch = ParseHex(e[key].string()); + e[key] = string((const char *)vch.data(), vch.size()); + } +} + +void hexcapePost(libtorrent::entry &e) +{ + if( e.type() == libtorrent::entry::dictionary_t ) { + findAndHexcape(e,"sig_userpost"); + if( e.find_key("userpost") ) { + entry &userpost = e["userpost"]; + if( userpost.type() == libtorrent::entry::dictionary_t ) { + findAndHexcape(userpost,"sig_rt"); + if( userpost.find_key("dm") ) { + entry &dm = userpost["dm"]; + if( dm.type() == libtorrent::entry::dictionary_t ) { + findAndHexcape(dm,"body"); + findAndHexcape(dm,"key"); + findAndHexcape(dm,"mac"); + } + } + } + } + } +} + +void unHexcapePost(libtorrent::entry &e) +{ + if( e.type() == libtorrent::entry::dictionary_t ) { + findAndUnHexcape(e,"sig_userpost"); + if( e.find_key("userpost") ) { + entry &userpost = e["userpost"]; + if( userpost.type() == libtorrent::entry::dictionary_t ) { + findAndUnHexcape(userpost,"sig_rt"); + if( userpost.find_key("dm") ) { + entry &dm = userpost["dm"]; + if( dm.type() == libtorrent::entry::dictionary_t ) { + findAndUnHexcape(dm,"body"); + findAndUnHexcape(dm,"key"); + findAndUnHexcape(dm,"mac"); + } + } + } + } + } +} + +void hexcapeDht(libtorrent::entry &e) +{ + if( e.type() == libtorrent::entry::dictionary_t ) { + findAndHexcape(e,"sig_p"); + if( e.find_key("p") ) { + entry &p = e["p"]; + if( p.type() == libtorrent::entry::dictionary_t ) { + if( p.find_key("v") ) { + entry &v = p["v"]; + if( v.type() == libtorrent::entry::dictionary_t ) { + hexcapePost(v); + // any other possible content to hexcape? + } + } + } + } + } +} + +void unHexcapeDht(libtorrent::entry &e) +{ + if( e.type() == libtorrent::entry::dictionary_t ) { + findAndUnHexcape(e,"sig_p"); + if( e.find_key("p") ) { + entry &p = e["p"]; + if( p.type() == libtorrent::entry::dictionary_t ) { + if( p.find_key("v") ) { + entry &v = p["v"]; + if( v.type() == libtorrent::entry::dictionary_t ) { + unHexcapePost(v); + // any other possible content to unhexcape? + } + } + } + } + } +} + + diff --git a/src/twister_utils.h b/src/twister_utils.h index 462f3e75..669e266a 100644 --- a/src/twister_utils.h +++ b/src/twister_utils.h @@ -38,4 +38,10 @@ libtorrent::entry jsonToEntry(const json_spirit::Value &v); int saveUserData(std::string const& filename, std::map const &users); int loadUserData(std::string const& filename, std::map &users); +void hexcapePost(libtorrent::entry &e); +void unHexcapePost(libtorrent::entry &e); + +void hexcapeDht(libtorrent::entry &e); +void unHexcapeDht(libtorrent::entry &e); + #endif // TWISTER_UTILS_H