diff --git a/libtorrent/src/disk_io_thread.cpp b/libtorrent/src/disk_io_thread.cpp index 92255261..744400c9 100644 --- a/libtorrent/src/disk_io_thread.cpp +++ b/libtorrent/src/disk_io_thread.cpp @@ -1077,8 +1077,9 @@ namespace libtorrent if (!m_settings.disable_hash_checks) { + std::string errmsg; *hash_ok = acceptSignedPost((char const*)p->blocks[0].buf, piece_size, - j.storage->info()->name(), j.piece); + j.storage->info()->name(), j.piece, errmsg); } ret = copy_from_piece(const_cast(*p), hit, j, l); diff --git a/libtorrent/src/peer_connection.cpp b/libtorrent/src/peer_connection.cpp index c2ab8d90..0885f708 100644 --- a/libtorrent/src/peer_connection.cpp +++ b/libtorrent/src/peer_connection.cpp @@ -539,7 +539,7 @@ namespace libtorrent char buf[450]; snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr); //(*m_logger) << buf; - printf(buf); + //printf(buf); } #endif diff --git a/libtorrent/src/storage.cpp b/libtorrent/src/storage.cpp index 5dc1c630..fa4e1fc8 100644 --- a/libtorrent/src/storage.cpp +++ b/libtorrent/src/storage.cpp @@ -231,8 +231,9 @@ namespace libtorrent if (ret > 0) { + std::string errmsg; *hash_ok = acceptSignedPost((char const*)buf.iov_base, ret, - m_info->name(), slot); + m_info->name(), slot, errmsg); } if (error()) return 0; diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index cf9cbbe6..a310dc7b 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -239,6 +239,7 @@ static const CRPCCommand vRPCCommands[] = { "dhtput", &dhtput, false, true }, { "dhtget", &dhtget, false, true }, { "newpostmsg", &newpostmsg, false, true }, + { "newdirectmsg", &newdirectmsg, false, true }, }; CRPCTable::CRPCTable() diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index a4bbc833..dc58af39 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -196,5 +196,6 @@ extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHe extern json_spirit::Value dhtput(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value dhtget(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value newpostmsg(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value newdirectmsg(const json_spirit::Array& params, bool fHelp); #endif diff --git a/src/twister.cpp b/src/twister.cpp index aa07e5b5..81bf7e9a 100644 --- a/src/twister.cpp +++ b/src/twister.cpp @@ -48,6 +48,22 @@ sha1_hash dhtTargetHash(std::string const &username, std::string const &resource return hasher(buf.data(), buf.size()).final(); } +torrent_handle startTorrentUser(std::string const &username) +{ + if( !m_userTorrent.count(username) ) { + sha1_hash ih = dhtTargetHash(username, "tracker", "m"); + + printf("adding torrent for [%s,tracker]\n", username.c_str()); + add_torrent_params tparams; + tparams.info_hash = ih; + tparams.name = username; + boost::filesystem::path torrentPath = GetDataDir() / "swarm" / ""; + tparams.save_path= torrentPath.string(); + m_userTorrent[username] = ses->add_torrent(tparams); + } + return m_userTorrent[username]; +} + int load_file(std::string const& filename, std::vector& v, libtorrent::error_code& ec, int limit = 8000000) { ec.clear(); @@ -348,15 +364,7 @@ void ThreadSessionAlerts() // Do something! printf("Neighbor of special resource - do something!\n"); if( dd->m_resource == "tracker" ) { - if( !m_userTorrent.count(dd->m_username) ) { - printf("adding torrent for [%s,tracker]\n", dd->m_username.c_str()); - add_torrent_params tparams; - tparams.info_hash = ih; - tparams.name = dd->m_username; - boost::filesystem::path torrentPath = GetDataDir() / "swarm" / ""; - tparams.save_path= torrentPath.string(); - m_userTorrent[dd->m_username] = ses->add_torrent(tparams); - } + startTorrentUser(dd->m_username); } } continue; @@ -388,7 +396,7 @@ void encryptDecryptTest() ecies_secure_t sec; bool encrypted = key1.GetPubKey().Encrypt(textIn, sec); - printf("encrypted = %d [key %d, mac %d, orig %d, body %d]\n", encrypted, + printf("encrypted = %d [key %zd, mac %zd, orig %zd, body %zd]\n", encrypted, sec.key.size(), sec.mac.size(), sec.orig, sec.body.size()); std::string textOut; @@ -527,9 +535,10 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna return (pubkeyRec.GetID() == pubkey.GetID()); } -bool acceptSignedPost(char const *data, int data_size, std::string username, int seq) +bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg) { bool ret = false; + char errbuf[200]=""; lazy_entry v; int pos; @@ -541,48 +550,46 @@ bool acceptSignedPost(char const *data, int data_size, std::string username, int std::string sig = v.dict_find_string_value("sig_userpost"); if( !post || !sig.size() ) { -#ifdef DEBUG_ACCEPT_POST - printf("acceptSignedPost: missing post or signature\n"); -#endif + sprintf(errbuf,"missing post or signature."); } else { std::string n = post->dict_find_string_value("n"); + std::string msg = post->dict_find_string_value("msg"); int k = post->dict_find_int_value("k",-1); int height = post->dict_find_int_value("height",-1); if( n != username ) { -#ifdef DEBUG_ACCEPT_POST - printf("acceptSignedPost: expected username '%s' got '%s'\n", - username.c_str(), n.c_str()); -#endif + sprintf(errbuf,"expected username '%s' got '%s'", + username.c_str(),n.c_str()); } else if( k != seq ) { -#ifdef DEBUG_ACCEPT_POST - printf("acceptSignedPost: expected piece '%d' got '%d'\n", + sprintf(errbuf,"expected piece '%d' got '%d'", seq, k); -#endif } else if( !validatePostNumberForUser(username, k) ) { -#ifdef DEBUG_ACCEPT_POST - printf("acceptSignedPost: too much posts from user '%s' rejecting post %d\n", - username.c_str(), k); -#endif + sprintf(errbuf,"too much posts from user '%s' rejecting post", + username.c_str()); } else if( height < 0 || height > getBestHeight() ) { -#ifdef DEBUG_ACCEPT_POST - printf("acceptSignedPost: post from future not accepted %d > %d\n", - height, getBestHeight()); -#endif + sprintf(errbuf,"post from future not accepted (height: %d > %d)", + height, getBestHeight()); + } else if( msg.size() && msg.size() > 140 ) { + sprintf(errbuf,"msg too big (%zd > 140)", msg.size()); } else { std::pair postbuf = post->data_section(); ret = verifySignature( std::string(postbuf.first,postbuf.second), username, sig); -#ifdef DEBUG_ACCEPT_POST if( !ret ) { - printf("acceptSignedPost: bad signature\n"); + sprintf(errbuf,"bad signature"); } -#endif } } } } + + errmsg = errbuf; +#ifdef DEBUG_ACCEPT_POST + if( !ret ) { + printf("acceptSignedPost: %s\n",errbuf); + } +#endif return ret; } @@ -823,16 +830,59 @@ Value newpostmsg(const Array& params, bool fHelp) int k = atoi( strK.c_str() ); entry v; - createSignedUserpost(v, strUsername, k, strMsg, + if( !createSignedUserpost(v, strUsername, k, strMsg, NULL, NULL, NULL, - std::string(""), 0); + std::string(""), 0) ) + throw JSONRPCError(RPC_INTERNAL_ERROR,"error signing post with private key of user"); std::vector buf; bencode(std::back_inserter(buf), v); - torrent_handle h = m_userTorrent[strUsername]; + std::string errmsg; + if( !acceptSignedPost(buf.data(),buf.size(),strUsername,k,errmsg) ) + throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); + + torrent_handle h = startTorrentUser(strUsername); h.add_piece(k,buf.data(),buf.size()); - return Value(); + return Value(std::string(buf.data(),buf.size())); } +Value newdirectmsg(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 4) + throw runtime_error( + "newdirectmessage \n" + "Post a new dm to swarm"); + + EnsureWalletIsUnlocked(); + + string strFrom = params[0].get_str(); + string strK = params[1].get_str(); + string strTo = params[2].get_str(); + string strMsg = params[3].get_str(); + int k = atoi( strK.c_str() ); + + entry dm; + if( !createDirectMessage(dm, strTo, strMsg) ) + throw JSONRPCError(RPC_INTERNAL_ERROR, + "error encrypting to pubkey of destination user"); + + entry v; + if( !createSignedUserpost(v, strFrom, k, "", + NULL, NULL, &dm, + std::string(""), 0) ) + throw JSONRPCError(RPC_INTERNAL_ERROR,"error signing post with private key of user"); + + std::vector buf; + bencode(std::back_inserter(buf), v); + + std::string errmsg; + if( !acceptSignedPost(buf.data(),buf.size(),strFrom,k,errmsg) ) + throw JSONRPCError(RPC_INVALID_PARAMS,errmsg); + + torrent_handle h = startTorrentUser(strFrom); + h.add_piece(k,buf.data(),buf.size()); + + return Value(std::string(buf.data(),buf.size())); +} diff --git a/src/twister.h b/src/twister.h index 711f999e..093155ed 100644 --- a/src/twister.h +++ b/src/twister.h @@ -18,7 +18,7 @@ void stopSessionTorrent(); std::string createSignature(std::string const &strMessage, std::string const &strUsername); bool verifySignature(std::string const &strMessage, std::string const &strUsername, std::string const &strSign); -bool acceptSignedPost(char const *data, int data_size, std::string username, int seq); +bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg); bool validatePostNumberForUser(std::string const &username, int k); int getBestHeight();