Sync to bitcoin git e94010b2395694d56dd6
[novacoin.git] / src / bitcoinrpc.cpp
index 644ad92..0493c6a 100644 (file)
@@ -13,7 +13,7 @@
 #include <boost/iostreams/stream.hpp>
 #include <boost/algorithm/string.hpp>
 #ifdef USE_SSL
-#include <boost/asio/ssl.hpp> 
+#include <boost/asio/ssl.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/filesystem/fstream.hpp>
 typedef boost::asio::ssl::stream<boost::asio::ip::tcp::socket> SSLStream;
@@ -332,12 +332,15 @@ Value getnewaddress(const Array& params, bool fHelp)
     // Generate a new key that is added to wallet
     string strAddress = PubKeyToAddress(pwalletMain->GetKeyFromKeyPool());
 
-    pwalletMain->SetAddressBookName(strAddress, strAccount);
+    // This could be done in the same main CS as GetKeyFromKeyPool.
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
+       pwalletMain->SetAddressBookName(strAddress, strAccount);
+
     return strAddress;
 }
 
 
-// requires cs_main, cs_mapWallet locks
+// requires cs_main, cs_mapWallet, cs_mapAddressBook locks
 string GetAccountAddress(string strAccount, bool bForceNew=false)
 {
     string strAddress;
@@ -393,6 +396,7 @@ Value getaccountaddress(const Array& params, bool fHelp)
 
     CRITICAL_BLOCK(cs_main)
     CRITICAL_BLOCK(pwalletMain->cs_mapWallet)
+    CRITICAL_BLOCK(pwalletMain->cs_mapAddressBook)
     {
         ret = GetAccountAddress(strAccount);
     }
@@ -431,9 +435,10 @@ Value setaccount(const Array& params, bool fHelp)
             if (strAddress == GetAccountAddress(strOldAccount))
                 GetAccountAddress(strOldAccount, true);
         }
+
+        pwalletMain->SetAddressBookName(strAddress, strAccount);
     }
 
-    pwalletMain->SetAddressBookName(strAddress, strAccount);
     return Value::null;
 }
 
@@ -838,7 +843,7 @@ Value sendmany(const Array& params, bool fHelp)
         CScript scriptPubKey;
         if (!scriptPubKey.SetBitcoinAddress(strAddress))
             throw JSONRPCError(-5, string("Invalid bitcoin address:")+strAddress);
-        int64 nAmount = AmountFromValue(s.value_); 
+        int64 nAmount = AmountFromValue(s.value_);
         totalAmount += nAmount;
 
         vecSend.push_back(make_pair(scriptPubKey, nAmount));
@@ -1156,7 +1161,7 @@ Value listtransactions(const Array& params, bool fHelp)
         }
         // ret is now newest to oldest
     }
-    
+
     // Make sure we return only last nCount items (sends-to-self might give us an extra):
     if (ret.size() > nCount)
     {
@@ -1532,7 +1537,7 @@ string rfc1123Time()
     return string(buffer);
 }
 
-string HTTPReply(int nStatus, const string& strMsg)
+static string HTTPReply(int nStatus, const string& strMsg)
 {
     if (nStatus == 401)
         return strprintf("HTTP/1.0 401 Authorization Required\r\n"
@@ -1554,6 +1559,7 @@ string HTTPReply(int nStatus, const string& strMsg)
     string strStatus;
          if (nStatus == 200) strStatus = "OK";
     else if (nStatus == 400) strStatus = "Bad Request";
+    else if (nStatus == 403) strStatus = "Forbidden";
     else if (nStatus == 404) strStatus = "Not Found";
     else if (nStatus == 500) strStatus = "Internal Server Error";
     return strprintf(
@@ -1887,7 +1893,12 @@ void ThreadRPCServer2(void* parg)
 
         // Restrict callers by IP
         if (!ClientAllowed(peer.address().to_string()))
+        {
+            // Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
+            if (!fUseSSL)
+                stream << HTTPReply(403, "") << std::flush;
             continue;
+        }
 
         map<string, string> mapHeaders;
         string strRequest;