Browse Source

error handling in newpostmsg and newdirectmsg implemented

miguelfreitas
miguel 11 years ago
parent
commit
b9c5b90e4d
  1. 3
      libtorrent/src/disk_io_thread.cpp
  2. 2
      libtorrent/src/peer_connection.cpp
  3. 3
      libtorrent/src/storage.cpp
  4. 1
      src/bitcoinrpc.cpp
  5. 1
      src/bitcoinrpc.h
  6. 120
      src/twister.cpp
  7. 2
      src/twister.h

3
libtorrent/src/disk_io_thread.cpp

@ -1077,8 +1077,9 @@ namespace libtorrent
if (!m_settings.disable_hash_checks) if (!m_settings.disable_hash_checks)
{ {
std::string errmsg;
*hash_ok = acceptSignedPost((char const*)p->blocks[0].buf, piece_size, *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<cached_piece_entry&>(*p), hit, j, l); ret = copy_from_piece(const_cast<cached_piece_entry&>(*p), hit, j, l);

2
libtorrent/src/peer_connection.cpp

@ -539,7 +539,7 @@ namespace libtorrent
char buf[450]; char buf[450];
snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr); snprintf(buf, sizeof(buf), "%s: %s\n", time_now_string(), usr);
//(*m_logger) << buf; //(*m_logger) << buf;
printf(buf); //printf(buf);
} }
#endif #endif

3
libtorrent/src/storage.cpp

@ -231,8 +231,9 @@ namespace libtorrent
if (ret > 0) if (ret > 0)
{ {
std::string errmsg;
*hash_ok = acceptSignedPost((char const*)buf.iov_base, ret, *hash_ok = acceptSignedPost((char const*)buf.iov_base, ret,
m_info->name(), slot); m_info->name(), slot, errmsg);
} }
if (error()) return 0; if (error()) return 0;

1
src/bitcoinrpc.cpp

@ -239,6 +239,7 @@ static const CRPCCommand vRPCCommands[] =
{ "dhtput", &dhtput, false, true }, { "dhtput", &dhtput, false, true },
{ "dhtget", &dhtget, false, true }, { "dhtget", &dhtget, false, true },
{ "newpostmsg", &newpostmsg, false, true }, { "newpostmsg", &newpostmsg, false, true },
{ "newdirectmsg", &newdirectmsg, false, true },
}; };
CRPCTable::CRPCTable() CRPCTable::CRPCTable()

1
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 dhtput(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dhtget(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 newpostmsg(const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value newdirectmsg(const json_spirit::Array& params, bool fHelp);
#endif #endif

120
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(); 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<char>& v, libtorrent::error_code& ec, int limit = 8000000) int load_file(std::string const& filename, std::vector<char>& v, libtorrent::error_code& ec, int limit = 8000000)
{ {
ec.clear(); ec.clear();
@ -348,15 +364,7 @@ void ThreadSessionAlerts()
// Do something! // Do something!
printf("Neighbor of special resource - do something!\n"); printf("Neighbor of special resource - do something!\n");
if( dd->m_resource == "tracker" ) { if( dd->m_resource == "tracker" ) {
if( !m_userTorrent.count(dd->m_username) ) { startTorrentUser(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);
}
} }
} }
continue; continue;
@ -388,7 +396,7 @@ void encryptDecryptTest()
ecies_secure_t sec; ecies_secure_t sec;
bool encrypted = key1.GetPubKey().Encrypt(textIn, 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()); sec.key.size(), sec.mac.size(), sec.orig, sec.body.size());
std::string textOut; std::string textOut;
@ -527,9 +535,10 @@ bool verifySignature(std::string const &strMessage, std::string const &strUserna
return (pubkeyRec.GetID() == pubkey.GetID()); 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; bool ret = false;
char errbuf[200]="";
lazy_entry v; lazy_entry v;
int pos; 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"); std::string sig = v.dict_find_string_value("sig_userpost");
if( !post || !sig.size() ) { if( !post || !sig.size() ) {
#ifdef DEBUG_ACCEPT_POST sprintf(errbuf,"missing post or signature.");
printf("acceptSignedPost: missing post or signature\n");
#endif
} else { } else {
std::string n = post->dict_find_string_value("n"); 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 k = post->dict_find_int_value("k",-1);
int height = post->dict_find_int_value("height",-1); int height = post->dict_find_int_value("height",-1);
if( n != username ) { if( n != username ) {
#ifdef DEBUG_ACCEPT_POST sprintf(errbuf,"expected username '%s' got '%s'",
printf("acceptSignedPost: expected username '%s' got '%s'\n", username.c_str(),n.c_str());
username.c_str(), n.c_str());
#endif
} else if( k != seq ) { } else if( k != seq ) {
#ifdef DEBUG_ACCEPT_POST sprintf(errbuf,"expected piece '%d' got '%d'",
printf("acceptSignedPost: expected piece '%d' got '%d'\n",
seq, k); seq, k);
#endif
} else if( !validatePostNumberForUser(username, k) ) { } else if( !validatePostNumberForUser(username, k) ) {
#ifdef DEBUG_ACCEPT_POST sprintf(errbuf,"too much posts from user '%s' rejecting post",
printf("acceptSignedPost: too much posts from user '%s' rejecting post %d\n", username.c_str());
username.c_str(), k);
#endif
} else if( height < 0 || height > getBestHeight() ) { } else if( height < 0 || height > getBestHeight() ) {
#ifdef DEBUG_ACCEPT_POST sprintf(errbuf,"post from future not accepted (height: %d > %d)",
printf("acceptSignedPost: post from future not accepted %d > %d\n",
height, getBestHeight()); height, getBestHeight());
#endif } else if( msg.size() && msg.size() > 140 ) {
sprintf(errbuf,"msg too big (%zd > 140)", msg.size());
} else { } else {
std::pair<char const*, int> postbuf = post->data_section(); std::pair<char const*, int> postbuf = post->data_section();
ret = verifySignature( ret = verifySignature(
std::string(postbuf.first,postbuf.second), std::string(postbuf.first,postbuf.second),
username, sig); username, sig);
#ifdef DEBUG_ACCEPT_POST
if( !ret ) { 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; return ret;
} }
@ -823,16 +830,59 @@ Value newpostmsg(const Array& params, bool fHelp)
int k = atoi( strK.c_str() ); int k = atoi( strK.c_str() );
entry v; entry v;
createSignedUserpost(v, strUsername, k, strMsg, if( !createSignedUserpost(v, strUsername, k, strMsg,
NULL, NULL, NULL, NULL, NULL, NULL,
std::string(""), 0); std::string(""), 0) )
throw JSONRPCError(RPC_INTERNAL_ERROR,"error signing post with private key of user");
std::vector<char> buf; std::vector<char> buf;
bencode(std::back_inserter(buf), v); 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()); 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 <from> <k> <to> <msg>\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<char> 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()));
}

2
src/twister.h

@ -18,7 +18,7 @@ void stopSessionTorrent();
std::string createSignature(std::string const &strMessage, std::string const &strUsername); 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 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); bool validatePostNumberForUser(std::string const &username, int k);
int getBestHeight(); int getBestHeight();

Loading…
Cancel
Save