Merge branch 'master' of git://github.com/miguelfreitas/twister-core

Conflicts:
	Makefile.am
This commit is contained in:
Denis Ryabov 2014-04-10 18:30:13 +04:00
commit 12f74e2bbc
15 changed files with 274 additions and 195 deletions

View File

@ -166,19 +166,18 @@ endif
twisterd_SOURCES = $(LIBTORRENT_SOURCES) $(BITCOIN_TWISTER_SOURCES)
twisterd_LDFLAGS =
twisterd_LDFLAGS = @OPENSSL_LDFLAGS@ @DB_CXX_LDFLAGS@
twisterd_DEPENDENCIES = $(LEVELDB_LIB)
twisterd_LDADD = $(LEVELDB_LIB) $(UPNP_LIB) \
@BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_PROGRAM_OPTIONS_LIB@ @BOOST_THREAD_LIB@ @BOOST_LOCALE_LIB@ \
@BOOST_SYSTEM_LIB@ @BOOST_FILESYSTEM_LIB@ @BOOST_PROGRAM_OPTIONS_LIB@ @BOOST_THREAD_LIB@ @BOOST_CHRONO_LIB@ @BOOST_LOCALE_LIB@ \
@DB_CXX_LIBS@ @OPENSSL_LIBS@
AM_CPPFLAGS = -ftemplate-depth-100 -DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 \
-I$(top_srcdir)/libtorrent/include \
-I$(top_srcdir)/src \
-I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \
@DEBUGFLAGS@ @OPENSSL_INCLUDES@
@DEBUGFLAGS@ @OPENSSL_INCLUDES@ @DB_CXX_CPPFLAGS@
AM_LDFLAGS = @OPENSSL_LDFLAGS@

View File

@ -23,7 +23,7 @@ not interoperate with existing networks (on purpose).
Compiling
----------------
You can build you own twister with this docs:
You can build twister using these docs:
[Ubuntu/Debian](https://github.com/miguelfreitas/twister-core/blob/master/doc/building-on-ubuntu-debian.md)
@ -175,3 +175,12 @@ them:
Visit [http://localhost:28332/index.html](http://localhost:28332/index.html)
in your web browser and you should see a page asking you to choose between the
Desktop and Mobile interfaces.
Different themes
-------------------------
If you prefer new modern look of twister with new untested things, you can try twister-calm theme
But be careful, it is in beta stage.
cd ~/.twister/
git clone https://github.com/iHedgehog/twister-calm.git ./html

View File

@ -1,28 +1,38 @@
Security
================
- Encrypt user_data (which contains all DMs)
- Test wallet encrypt to see if it still works from original bitcoin implementation and what
are the implications to our code.
- Rescan directmessages after importing a privatekey (importprivkey)
- Move all crypto to javascript, store only encrypted version of the privatekey (which would be
decrypted only in browser memory). getposts may obtain all DMs encrypted to browser, another
newpostmsg needs to be provided to receive posts with signature field added.
- Check libtorrent's limitation on the number of pieces (max_pieces in piece_picker.hpp = 1<<19)
Since post number is constrained by max of 288 posts per day in average, that means we have 5 years
to think about it (for the really heavy users).
Features
================
- Besides increasing the maximum number of pieces, a more pressing issue to save bandwidth and
torrent download time would be to define the first piece to download/store locally. People don't
need to maintain the entire post history for everybody they follow, they could just keep the last
ones. This has to be implemented.
- Move all crypto to javascript, store only encrypted version of the privatekey (which would be
decrypted only in browser memory). getposts may obtain all DMs encrypted to browser, another
newpostmsg needs to be provided to receive posts with signature field added.
- Store a dht resource "publickey" containing not only the public key itself but also information
needed to validate it by a lightweight client. That includes: block hash, block height and partial
merkle tree inside that block. This resource propagation cannot be sent right after user
registration for obvious reasons (no block yet, other nodes wouldn't accept the signed dht put).
- Share images
Kill bugs
================
- Rescan directmessages after importing a privatekey (importprivkey)
- Check libtorrent's limitation on the number of pieces (max_pieces in piece_picker.hpp = 1<<19)
Since post number is constrained by max of 288 posts per day in average, that means we have 5 years
to think about it (for the really heavy users).
- Implement the mention forwarding mechanism discussed in the paper so user don't need to do polling
and can also be sure to receive all mentions.
@ -39,8 +49,6 @@ of his own torrent)
- Estimate number of online followers by quering the "tracker" resource (implement a value within
this resource to report the number of torrent peers)
- Define and enforce html directory to serve from. Do installation scripts.
- Don't accept dht "post"+k if k violates the validatePostNumberForUser() rule.
- Implement -secdatadir= parameter to store sensitive data (wallet, dm) in a separated dir.

View File

@ -83,27 +83,23 @@ AC_CACHE_CHECK([for __attribute__((visibility("hidden")))],
AS_ECHO
AS_ECHO "Checking for boost libraries:"
AX_BOOST_BASE([1.44])
AX_BOOST_BASE([1.44], [],
[AC_MSG_ERROR(Boost library not found. Try using --with-boost=)])
AX_BOOST_SYSTEM()
AS_IF([test -z "$BOOST_SYSTEM_LIB"],
[AC_MSG_ERROR(Boost.System library not found. Try using --with-boost-libdir=)])
AX_BOOST_FILESYSTEM()
AX_BOOST_PROGRAM_OPTIONS()
AX_BOOST_THREAD()
AX_BOOST_CHRONO()
AX_BOOST_LOCALE()
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS $BOOST_CHRONO_LIB"
###############################################################################
# Checking for Berkeley DB C++
###############################################################################
AC_LANG([C++])
AX_BERKELEY_DB_CXX(4.8)
AX_BERKELEY_DB_CXX(4.8, [],
[AC_MSG_ERROR(Berkeley DB C++ library not found. Try using --with-libdb=)])
###############################################################################
# Checking for functions and other stuffs
@ -773,6 +769,15 @@ Boost libraries:
CPPFlags: ${BOOST_CPPFLAGS}
LDFlags: ${BOOST_LDFLAGS}
boost.system: ${BOOST_SYSTEM_LIB}
boost.filesystem: ${BOOST_FILESYSTEM_LIB}
boost.program_opts: ${BOOST_PROGRAM_OPTIONS_LIB}
boost.thread: ${BOOST_THREAD_LIB}
Berkeley DB C++ library:
header: ${DB_CXX_HEADER}
libraries: ${DB_CXX_LIBS}
LDFlags: ${DB_CXX_LDFLAGS}
CPPFlags: ${DB_CXX_CPPFLAGS}
END
AS_IF([test "x$ARG_ENABLE_PYTHON_BINDING" = "xyes"], [
@ -831,7 +836,7 @@ OpenSSL library:
OpenSSL Libs: ${OPENSSL_LIBS}
OpenSSL LDFlags: ${OPENSSL_LDFLAGS}
OpenSSL Includes: ${OPENSSL_INCLUDES}
END
END
])
cat config.report

View File

@ -43,18 +43,6 @@ Instructions: HomeBrew
brew install boost miniupnpc openssl berkeley-db4 autoconf automake libtool
Note: After you have installed the dependencies, you should check that the Brew-installed
version of OpenSSL is the one available for compilation. You can check this by typing
openssl version
into Terminal. You should see OpenSSL 1.0.1e 11 Feb 2013.
If that's not the case, you *could* `brew link --force openssl` but it's a bad idea.
Instead, it's enough to make sure the right openssl binary is on your $PATH:
export PATH=/usr/local/opt/openssl/bin:$PATH
### Building `twisterd`
1. Clone the github tree to get the source code and go into the directory.
@ -63,29 +51,14 @@ Instead, it's enough to make sure the right openssl binary is on your $PATH:
git clone https://github.com/miguelfreitas/twister-core.git
cd twister-core
2. Set system variables to match your environment. THIS IS IMPORTANT!
export OPENSSL_INCLUDE_PATH=/usr/local/opt/openssl/include
export OPENSSL_LIB_PATH=/usr/local/opt/openssl/lib
export BDB_INCLUDE_PATH=/usr/local/opt/berkeley-db4/include
export BDB_LIB_PATH=/usr/local/opt/berkeley-db4/lib
export BOOST_INCLUDE_PATH=/usr/local/opt/boost/include
export BOOST_LIB_PATH=/usr/local/opt/boost/lib
export BOOST_LIB_SUFFIX=-mt
export LDFLAGS="-L$OPENSSL_LIB_PATH -L$BDB_LIB_PATH -L$BOOST_LIB_PATH"
export CPPFLAGS="-I$OPENSSL_INCLUDE_PATH -I$BDB_INCLUDE_PATH -I$BOOST_INCLUDE_PATH"
export PATH=${BDB_INCLUDE_PATH}:${PATH}
3. Build twister using autotool
2. Build twister using autotool
./autotool.sh
./configure --enable-logging
./configure --enable-logging --with-openssl=/usr/local/opt/openssl --with-libdb=/usr/local/opt/berkeley-db4
make
(If you have multi core CPU, use "make -j N" where N = number of your cores)
4. If things go south, before trying again, make sure you clean it up:
3. If things go south, before trying again, make sure you clean it up:
make clean

View File

@ -118,12 +118,16 @@ struct torrent_entry
struct dht_storage_item
{
// FIXME: optimize so bdecode is not needed all the time
dht_storage_item() : p(), sig_p(), sig_user() {}
dht_storage_item(std::string &_p, lazy_entry const *_sig_p, lazy_entry const *_sig_user)
: p(_p), sig_p(_sig_p->string_value()), sig_user(_sig_user->string_value()) {}
dht_storage_item() : p(), sig_p(), sig_user(), local_add_time(0) {}
dht_storage_item(std::string const &_p, lazy_entry const *_sig_p, lazy_entry const *_sig_user)
: p(_p), sig_p(_sig_p->string_value()), sig_user(_sig_user->string_value()),
local_add_time(0) {}
dht_storage_item(std::string const &_p, std::string const &_sig_p, std::string const &_sig_user)
: p(_p), sig_p(_sig_p), sig_user(_sig_user), local_add_time(0) {}
std::string p;
std::string sig_p;
std::string sig_user;
boost::int64_t local_add_time;
// the last time we heard about this
//ptime last_seen;
};
@ -282,6 +286,8 @@ private:
std::set<traversal_algorithm*> m_running_requests;
void incoming_request(msg const& h, entry& e);
void store_dht_item(dht_storage_item &item, big_number const &target,
bool multi, int seq, int height, std::pair<char const*, int> &bufv);
node_id m_id;

View File

@ -444,11 +444,13 @@ void node_impl::putData(std::string const &username, std::string const &resource
if (seq >= 0 && !multi) p["seq"] = seq;
p["v"] = value;
p["time"] = timeutc;
p["height"] = getBestHeight()-1; // be conservative
int height = getBestHeight()-1; // be conservative
p["height"] = height;
std::vector<char> pbuf;
bencode(std::back_inserter(pbuf), p);
std::string sig_p = createSignature(std::string(pbuf.data(),pbuf.size()), sig_user);
std::string str_p = std::string(pbuf.data(),pbuf.size());
std::string sig_p = createSignature(str_p, sig_user);
if( !sig_p.size() ) {
printf("putData: createSignature error (this should have been caught earlier)\n");
return;
@ -459,7 +461,17 @@ void node_impl::putData(std::string const &username, std::string const &resource
boost::intrusive_ptr<dht_get> ta(new dht_get(*this, username, resource, multi,
boost::bind(&nop),
boost::bind(&putData_fun, _1, boost::ref(*this), p, sig_p, sig_user), true));
ta->start();
// store it locally so it will be automatically refreshed with the rest
dht_storage_item item(str_p, sig_p, sig_user);
item.local_add_time = time(NULL);
std::vector<char> vbuf;
bencode(std::back_inserter(vbuf), value);
std::pair<char const*, int> bufv = std::make_pair(vbuf.data(), vbuf.size());
store_dht_item(item, ta->target(), multi, seq, height, bufv);
// now send it to the network (start transversal algorithm)
ta->start();
}
void node_impl::getData(std::string const &username, std::string const &resource, bool multi,
@ -555,7 +567,8 @@ bool node_impl::refresh_storage() {
bool multi = (target->dict_find_string_value("t") == "m");
// refresh only signed single posts and mentions
if( !multi || (multi && resource == "mention") ) {
if( !multi || (multi && resource == "mention") ||
(multi && item.local_add_time && item.local_add_time + 60*60*24*2 > time(NULL)) ) {
num_refreshable++;
if( refresh_next_item ) {
@ -678,6 +691,8 @@ bool node_impl::save_storage(entry &save) const {
entry_item["p"] = item.p;
entry_item["sig_p"] = item.sig_p;
entry_item["sig_user"] = item.sig_user;
if( item.local_add_time )
entry_item["local_add_time"] = item.local_add_time;
save_list.list().push_back(entry_item);
}
}
@ -709,6 +724,9 @@ void node_impl::load_storage(entry const* e) {
item.p = j->find_key("p")->string();
item.sig_p = j->find_key("sig_p")->string();
item.sig_user = j->find_key("sig_user")->string();
entry const *local_add_time( j->find_key("local_add_time") );
if(local_add_time)
item.local_add_time = local_add_time->integer();
// just for printf for now
bool expired = has_expired(item);
@ -1327,71 +1345,13 @@ void node_impl::incoming_request(msg const& m, entry& e)
// attack this resource by storing value into non-final nodes.
if( !possiblyNeighbor ) {
printf("putData with possiblyNeighbor=false, ignoring request.\n");
return;
}
dht_storage_item item(str_p, msg_keys[mk_sig_p], msg_keys[mk_sig_user]);
dht_storage_table_t::iterator i = m_storage_table.find(target);
if (i == m_storage_table.end()) {
// make sure we don't add too many items
if (int(m_storage_table.size()) >= m_settings.max_dht_items)
{
// FIXME: erase one? preferably a multi
}
dht_storage_list_t to_add;
to_add.push_back(item);
boost::tie(i, boost::tuples::ignore) = m_storage_table.insert(
std::make_pair(target, to_add));
} else {
dht_storage_list_t & lsto = i->second;
dht_storage_list_t::reverse_iterator j, rend(lsto.rend());
dht_storage_list_t::iterator insert_pos = lsto.end();
for( j = lsto.rbegin(); j != rend; ++j) {
dht_storage_item &olditem = *j;
lazy_entry p;
int pos;
error_code err;
// FIXME: optimize to avoid bdecode (store seq separated, etc)
int ret = lazy_bdecode(olditem.p.data(), olditem.p.data() + olditem.p.size(), p, err, &pos, 10, 500);
if( !multi ) {
if( msg_keys[mk_seq]->int_value() > p.dict_find_int("seq")->int_value() ) {
olditem = item;
} else {
// don't report this error (because of refresh storage)
//incoming_error(e, "old sequence number");
return;
}
} else {
std::pair<char const*, int> bufv = msg_keys[mk_v]->data_section();
// compare contents before adding to the list
std::pair<char const*, int> bufoldv = p.dict_find("v")->data_section();
if( bufv.second == bufoldv.second && !memcmp(bufv.first, bufoldv.first,bufv.second) ) {
// break so it wont be inserted
break;
}
// if new entry is newer than existing one, it will be inserted before
if( msg_keys[mk_height]->int_value() >= p.dict_find_int_value("height") ) {
insert_pos = j.base();
insert_pos--;
}
}
}
if(multi && j == rend) {
// new entry
lsto.insert(insert_pos, item);
}
if(lsto.size() > m_settings.max_entries_per_multi) {
lsto.resize(m_settings.max_entries_per_multi);
}
}
std::pair<char const*, int> bufv = msg_keys[mk_v]->data_section();
store_dht_item(item, target, multi, !multi ? msg_keys[mk_seq]->int_value() : 0,
msg_keys[mk_height]->int_value(), bufv);
}
else if (strcmp(query, "getData") == 0)
{
@ -1517,6 +1477,69 @@ void node_impl::incoming_request(msg const& m, entry& e)
}
}
void node_impl::store_dht_item(dht_storage_item &item, const big_number &target,
bool multi, int seq, int height, std::pair<char const*, int> &bufv)
{
dht_storage_table_t::iterator i = m_storage_table.find(target);
if (i == m_storage_table.end()) {
// make sure we don't add too many items
if (int(m_storage_table.size()) >= m_settings.max_dht_items)
{
// FIXME: erase one? preferably a multi
}
dht_storage_list_t to_add;
to_add.push_back(item);
boost::tie(i, boost::tuples::ignore) = m_storage_table.insert(
std::make_pair(target, to_add));
} else {
dht_storage_list_t & lsto = i->second;
dht_storage_list_t::reverse_iterator j, rend(lsto.rend());
dht_storage_list_t::iterator insert_pos = lsto.end();
for( j = lsto.rbegin(); j != rend; ++j) {
dht_storage_item &olditem = *j;
lazy_entry p;
int pos;
error_code err;
// FIXME: optimize to avoid bdecode (store seq separated, etc)
int ret = lazy_bdecode(olditem.p.data(), olditem.p.data() + olditem.p.size(), p, err, &pos, 10, 500);
if( !multi ) {
if( seq > p.dict_find_int("seq")->int_value() ) {
olditem = item;
} else {
// don't report this error (because of refresh storage)
//incoming_error(e, "old sequence number");
return;
}
} else {
// compare contents before adding to the list
std::pair<char const*, int> bufoldv = p.dict_find("v")->data_section();
if( bufv.second == bufoldv.second && !memcmp(bufv.first, bufoldv.first,bufv.second) ) {
// break so it wont be inserted
break;
}
// if new entry is newer than existing one, it will be inserted before
if( height >= p.dict_find_int_value("height") ) {
insert_pos = j.base();
insert_pos--;
}
}
}
if(multi && j == rend) {
// new entry
lsto.insert(insert_pos, item);
}
if(lsto.size() > m_settings.max_entries_per_multi) {
lsto.resize(m_settings.max_entries_per_multi);
}
}
}
} } // namespace libtorrent::dht

View File

@ -21,28 +21,52 @@
# in your C/C++ code. DB_CXX_LIBS is set to linker flags needed to link
# against the library (e.g. -ldb3.1_cxx) and AC_SUBST is called on it.
#
# when specified user-selected spot (via --with-libdb) also sets
#
# DB_CXX_CPPFLAGS to the include directives required
# DB_CXX_LDFLAGS to the -L flags required
#
# LICENSE
#
# Copyright (c) 2008 Vaclav Slavik <vaclav.slavik@matfyz.cz>
# Copyright (c) 2011 Stephan Suerken <absurd@debian.org>
# Copyright (c) 2014 Kirill A. Korinskiy <catap@catap.ru>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 3
#serial 4
AC_DEFUN([AX_BERKELEY_DB_CXX],
[
AC_LANG_ASSERT(C++)
old_LIBS="$LIBS"
old_LDFLAGS="$LDFLAGS"
old_CPPFLAGS="$CPPFLAGS"
libdbdir=""
AC_ARG_WITH(libdb,
AS_HELP_STRING([--with-libdb=DIR],
[root of the Berkeley DB directory]),
[
case "$withval" in
"" | y | ye | yes | n | no)
AC_MSG_ERROR([Invalid --with-libdb value])
;;
*) libdbdir="$withval"
;;
esac
], [])
minversion=ifelse([$1], ,,$1)
DB_CXX_HEADER=""
DB_CXX_LIBS=""
DB_CXX_LDFLAGS=""
DB_CXX_CPPFLAGS=""
if test -z $minversion ; then
minvermajor=0
@ -59,13 +83,20 @@ AC_DEFUN([AX_BERKELEY_DB_CXX],
AC_MSG_CHECKING([for Berkeley DB (C++) >= $minversion])
fi
if test x$libdbdir != x""; then
DB_CXX_CPPFLAGS="-I${libdbdir}/include"
DB_CXX_LDFLAGS="-L${libdbdir}/lib"
LDFLAGS="$DB_CXX_LDFLAGS $old_LDFLAGS"
CPPFLAGS="$DB_CXX_CPPFLAGS $old_CPPFLAGS"
fi
for version in "" 5.0 4.9 4.8 4.7 4.6 4.5 4.4 4.3 4.2 4.1 4.0 3.6 3.5 3.4 3.3 3.2 3.1 ; do
if test -z $version ; then
db_cxx_lib="-ldb_cxx -ldb"
try_headers="db_cxx.h"
else
db_cxx_lib="-ldb_cxx-$version -ldb-$version"
db_cxx_lib="$libdbdir -ldb_cxx-$version -ldb-$version"
try_headers="db$version/db_cxx.h db`echo $version | sed -e 's,\..*,,g'`/db_cxx.h"
fi
@ -102,13 +133,19 @@ AC_DEFUN([AX_BERKELEY_DB_CXX],
done
LIBS="$old_LIBS"
LDFLAGS="$old_LDFLAGS"
CPPFLAGS="$old_CPPFLAGS"
if test -z $DB_CXX_HEADER ; then
AC_MSG_RESULT([not found])
DB_CXX_LDFLAGS=""
DB_CXX_CPPFLAGS=""
ifelse([$3], , :, [$3])
else
AC_DEFINE_UNQUOTED(DB_CXX_HEADER, ["$DB_CXX_HEADER"], ["Berkeley DB C++ Header File"])
AC_SUBST(DB_CXX_LIBS)
AC_SUBST(DB_CXX_LDFLAGS)
AC_SUBST(DB_CXX_CPPFLAGS)
ifelse([$2], , :, [$2])
fi
])

View File

@ -195,74 +195,74 @@ Value stop(const Array& params, bool fHelp)
static const CRPCCommand vRPCCommands[] =
{ // name actor (function) okSafeMode threadSafe
// ------------------------ ----------------------- ---------- ----------
{ "help", &help, true, true },
{ "stop", &stop, true, true },
{ "getblockcount", &getblockcount, true, false },
{ "getbestblockhash", &getbestblockhash, true, false },
{ "getconnectioncount", &getconnectioncount, true, false },
{ "getpeerinfo", &getpeerinfo, true, false },
{ "addnode", &addnode, true, true },
{ "adddnsseed", &adddnsseed, true, true },
{ "getaddednodeinfo", &getaddednodeinfo, true, true },
{ "getdifficulty", &getdifficulty, true, false },
{ "getgenerate", &getgenerate, true, false },
{ "setgenerate", &setgenerate, true, false },
{ "gethashespersec", &gethashespersec, true, false },
{ "getinfo", &getinfo, true, true },
{ "getmininginfo", &getmininginfo, true, false },
{ "createwalletuser", &createwalletuser, true, false },
{ "listwalletusers", &listwalletusers, true, false },
{ "backupwallet", &backupwallet, true, false },
{ "walletpassphrase", &walletpassphrase, true, false },
{ "walletpassphrasechange", &walletpassphrasechange, false, false },
{ "walletlock", &walletlock, true, false },
{ "encryptwallet", &encryptwallet, false, false },
{ "getrawmempool", &getrawmempool, true, false },
{ "getblock", &getblock, false, false },
{ "getblockhash", &getblockhash, false, false },
{ "gettransaction", &gettransaction, false, false },
{ "listtransactions", &listtransactions, false, false },
{ "signmessage", &signmessage, false, false },
{ "verifymessage", &verifymessage, false, false },
{ "getwork", &getwork, true, false },
{ "getblocktemplate", &getblocktemplate, true, false },
{ "submitblock", &submitblock, false, false },
{ "listsinceblock", &listsinceblock, false, false },
{ "dumpprivkey", &dumpprivkey, true, false },
{ "dumppubkey", &dumppubkey, false, false },
{ "dumpwallet", &dumpwallet, true, false },
{ "importprivkey", &importprivkey, false, false },
{ "importwallet", &importwallet, false, false },
{ "getrawtransaction", &getrawtransaction, false, false },
{ "createrawtransaction", &createrawtransaction, false, false },
{ "decoderawtransaction", &decoderawtransaction, false, false },
{ "sendrawtransaction", &sendrawtransaction, false, false },
{ "sendnewusertransaction", &sendnewusertransaction, false, false },
{ "verifychain", &verifychain, true, false },
{ "getlastsoftcheckpoint", &getlastsoftcheckpoint, true, false },
{ // name actor (function) okSafeMode threadSafe allowOnPublicServer
// ------------------------ ----------------------- ---------- ---------- -------------------
{ "help", &help, true, true, true },
{ "stop", &stop, true, true, false },
{ "getblockcount", &getblockcount, true, false, false },
{ "getbestblockhash", &getbestblockhash, true, false, true },
{ "getconnectioncount", &getconnectioncount, true, false, false },
{ "getpeerinfo", &getpeerinfo, true, false, false },
{ "addnode", &addnode, true, true, false },
{ "adddnsseed", &adddnsseed, true, true, false },
{ "getaddednodeinfo", &getaddednodeinfo, true, true, false },
{ "getdifficulty", &getdifficulty, true, false, false },
{ "getgenerate", &getgenerate, true, false, false },
{ "setgenerate", &setgenerate, true, false, false },
{ "gethashespersec", &gethashespersec, true, false, false },
{ "getinfo", &getinfo, true, true, true },
{ "getmininginfo", &getmininginfo, true, false, false },
{ "createwalletuser", &createwalletuser, true, false, false },
{ "listwalletusers", &listwalletusers, true, false, true },
{ "backupwallet", &backupwallet, true, false, false },
{ "walletpassphrase", &walletpassphrase, true, false, false },
{ "walletpassphrasechange", &walletpassphrasechange, false, false, false },
{ "walletlock", &walletlock, true, false, false },
{ "encryptwallet", &encryptwallet, false, false, false },
{ "getrawmempool", &getrawmempool, true, false, false },
{ "getblock", &getblock, false, false, true },
{ "getblockhash", &getblockhash, false, false, false },
{ "gettransaction", &gettransaction, false, false, false },
{ "listtransactions", &listtransactions, false, false, false },
{ "signmessage", &signmessage, false, false, false },
{ "verifymessage", &verifymessage, false, false, false },
{ "getwork", &getwork, true, false, false },
{ "getblocktemplate", &getblocktemplate, true, false, false },
{ "submitblock", &submitblock, false, false, false },
{ "listsinceblock", &listsinceblock, false, false, false },
{ "dumpprivkey", &dumpprivkey, true, false, false },
{ "dumppubkey", &dumppubkey, false, false, false },
{ "dumpwallet", &dumpwallet, true, false, false },
{ "importprivkey", &importprivkey, false, false, false },
{ "importwallet", &importwallet, false, false, false },
{ "getrawtransaction", &getrawtransaction, false, false, false },
{ "createrawtransaction", &createrawtransaction, false, false, false },
{ "decoderawtransaction", &decoderawtransaction, false, false, false },
{ "sendrawtransaction", &sendrawtransaction, false, false, false },
{ "sendnewusertransaction", &sendnewusertransaction, false, false, false },
{ "verifychain", &verifychain, true, false, false },
{ "getlastsoftcheckpoint", &getlastsoftcheckpoint, true, false, false },
// twister dht network
{ "dhtput", &dhtput, false, true },
{ "dhtget", &dhtget, false, true },
{ "newpostmsg", &newpostmsg, false, true },
{ "newdirectmsg", &newdirectmsg, false, true },
{ "newrtmsg", &newrtmsg, false, true },
{ "getposts", &getposts, false, true },
{ "getdirectmsgs", &getdirectmsgs, false, true },
{ "setspammsg", &setspammsg, false, false },
{ "getspammsg", &getspammsg, false, false },
{ "follow", &follow, false, true },
{ "unfollow", &unfollow, false, true },
{ "getfollowing", &getfollowing, false, true },
{ "getlasthave", &getlasthave, false, true },
{ "getnumpieces", &getnumpieces, false, true },
{ "listusernamespartial", &listusernamespartial, false, true },
{ "rescandirectmsgs", &rescandirectmsgs, false, true },
{ "recheckusertorrent", &recheckusertorrent, false, true },
{ "gettrendinghashtags", &gettrendinghashtags, false, true },
{ "getspamposts", &getspamposts, false, true },
{ "torrentstatus", &torrentstatus, false, true },
{ "dhtput", &dhtput, false, true, false },
{ "dhtget", &dhtget, false, true, true },
{ "newpostmsg", &newpostmsg, false, true, false },
{ "newdirectmsg", &newdirectmsg, false, true, false },
{ "newrtmsg", &newrtmsg, false, true, false },
{ "getposts", &getposts, false, true, false },
{ "getdirectmsgs", &getdirectmsgs, false, true, false },
{ "setspammsg", &setspammsg, false, false, false },
{ "getspammsg", &getspammsg, false, false, false },
{ "follow", &follow, false, true, false },
{ "unfollow", &unfollow, false, true, false },
{ "getfollowing", &getfollowing, false, true, false },
{ "getlasthave", &getlasthave, false, true, false },
{ "getnumpieces", &getnumpieces, false, true, false },
{ "listusernamespartial", &listusernamespartial, false, true, true },
{ "rescandirectmsgs", &rescandirectmsgs, false, true, false },
{ "recheckusertorrent", &recheckusertorrent, false, true, false },
{ "gettrendinghashtags", &gettrendinghashtags, false, true, true },
{ "getspamposts", &getspamposts, false, true, false },
{ "torrentstatus", &torrentstatus, false, true, false },
};
CRPCTable::CRPCTable()
@ -989,6 +989,9 @@ void ServiceConnection(AcceptedConnection *conn)
// Read HTTP message headers and body
ReadHTTPMessage(conn->stream(), mapHeaders, strRequest, nProto);
if(strMethod == "GET" && strURI == "/")
strURI="/home.html";
if (strURI != "/" && strURI.find("..") == std::string::npos ) {
filesystem::path pathFile = filesystem::path(GetHTMLDir()) / strURI;
std::string fname = pathFile.string();
@ -1093,6 +1096,9 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
const CRPCCommand *pcmd = tableRPC[strMethod];
if (!pcmd)
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
if(!pcmd->allowOnPublicServer && GetBoolArg("-public_server_mode",false))
throw JSONRPCError(RPC_FORBIDDEN_ON_PUBLIC_SERVER, "Forbidden: accessing this method is not allowed on a public server");
// Observe safe mode
string strWarning = GetWarnings("rpc");

View File

@ -48,6 +48,7 @@ enum RPCErrorCode
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
RPC_DATABASE_ERROR = -20, // Database error
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
RPC_FORBIDDEN_ON_PUBLIC_SERVER = -23, // public server mode is activated, this method is not allowed
// P2P client errors
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
@ -103,6 +104,7 @@ public:
rpcfn_type actor;
bool okSafeMode;
bool threadSafe;
bool allowOnPublicServer;
};
/**

View File

@ -8,7 +8,7 @@
// These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 9
#define CLIENT_VERSION_REVISION 19
#define CLIENT_VERSION_REVISION 20
#define CLIENT_VERSION_BUILD 0
// Set to true for release, false for prerelease or test build

View File

@ -13,7 +13,11 @@
#include <vector>
#include <boost/filesystem.hpp>
#include <db_cxx.h>
#ifdef DB_CXX_HEADER
#include DB_CXX_HEADER
#else
#include <db_cxx.h>
#endif
class CAddrMan;
class CBlockLocator;

View File

@ -96,6 +96,7 @@ Value getinfo(const Array& params, bool fHelp)
if (pwalletMain->IsCrypted())
obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
}
obj.push_back(Pair("public_server_mode", GetBoolArg("-public_server_mode",false)));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
}
return obj;
@ -155,6 +156,11 @@ Value listwalletusers(const Array& params, bool fHelp)
// Find all addresses that have the given account
Array ret;
// Always return an empty array on a public server
if(GetBoolArg("-public_server_mode",false))
return ret;
LOCK(pwalletMain->cs_wallet);
BOOST_FOREACH(const PAIRTYPE(CKeyID, CKeyMetadata)& item, pwalletMain->mapKeyMetadata)
{

View File

@ -1691,7 +1691,7 @@ Value getposts(const Array& params, bool fHelp)
Value getdirectmsgs(const Array& params, bool fHelp)
{
if (fHelp || params.size() < 2 || params.size() > 3)
if (fHelp || params.size() != 3)
throw runtime_error(
"getdirectmsgs <localuser> <count_per_user> '[{\"username\":username,\"max_id\":max_id,\"since_id\":since_id},...]'\n"
"get (locally stored) decrypted direct messages sent/received by user <localuser>\n"

View File

@ -71,6 +71,7 @@ int save_file(std::string const& filename, std::vector<char>& v)
libtorrent::error_code ec;
if (!f.open(filename, file::write_only, ec)) return -1;
if (ec) return -1;
f.set_size(0, ec);
file::iovec_t b = {&v[0], v.size()};
size_type written = f.writev(0, &b, 1, ec);
if (written != int(v.size())) return -3;