// Copyright (c) 2010 Satoshi Nakamoto
-// Copyright (c) 2011 The Bitcoin developers
+// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.
obj.push_back(Pair("keypoolsize", pwalletMain->GetKeyPoolSize()));
obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee)));
if (pwalletMain->IsCrypted())
- obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime));
+ obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime / 1000));
obj.push_back(Pair("errors", GetWarnings("statusbar")));
return obj;
}
return wtx.GetHash().GetHex();
}
-static const string strMessageMagic = "Bitcoin Signed Message:\n";
-
Value signmessage(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 2)
if (address.IsScript())
throw runtime_error(
strprintf("%s is a pay-to-script address",ks.c_str()));
- if (!pwalletMain->GetKey(address, pubkeys[i]))
+ std::vector<unsigned char> vchPubKey;
+ if (!pwalletMain->GetPubKey(address, vchPubKey))
throw runtime_error(
strprintf("no full public key for address %s",ks.c_str()));
+ if (vchPubKey.empty() || !pubkeys[i].SetPubKey(vchPubKey))
+ throw runtime_error(" Invalid public key: "+ks);
}
// Case 2: hex public key
void ThreadCleanWalletPassphrase(void* parg)
{
- int64 nMyWakeTime = GetTime() + *((int*)parg);
+ int64 nMyWakeTime = GetTimeMillis() + *((int*)parg) * 1000;
+
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
if (nWalletUnlockTime == 0)
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ nWalletUnlockTime = nMyWakeTime;
+
+ do
{
- nWalletUnlockTime = nMyWakeTime;
- }
+ if (nWalletUnlockTime==0)
+ break;
+ int64 nToSleep = nWalletUnlockTime - GetTimeMillis();
+ if (nToSleep <= 0)
+ break;
+
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
+ Sleep(nToSleep);
+ ENTER_CRITICAL_SECTION(cs_nWalletUnlockTime);
- while (GetTime() < nWalletUnlockTime)
- Sleep(GetTime() - nWalletUnlockTime);
+ } while(1);
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
+ if (nWalletUnlockTime)
{
nWalletUnlockTime = 0;
+ pwalletMain->Lock();
}
}
else
{
- CRITICAL_BLOCK(cs_nWalletUnlockTime)
- {
- if (nWalletUnlockTime < nMyWakeTime)
- nWalletUnlockTime = nMyWakeTime;
- }
- free(parg);
- return;
+ if (nWalletUnlockTime < nMyWakeTime)
+ nWalletUnlockTime = nMyWakeTime;
}
- pwalletMain->Lock();
+ LEAVE_CRITICAL_SECTION(cs_nWalletUnlockTime);
delete (int*)parg;
}
if (!pwalletMain->IsCrypted())
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
- pwalletMain->Lock();
CRITICAL_BLOCK(cs_nWalletUnlockTime)
{
+ pwalletMain->Lock();
nWalletUnlockTime = 0;
}
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
// Update nExtraNonce
" \"coinbasevalue\" : maximum allowable input to coinbase transaction, including the generation award and transaction fees\n"
" \"coinbaseflags\" : data that should be included in coinbase so support for new features can be judged\n"
" \"time\" : timestamp appropriate for next block\n"
+ " \"mintime\" : minimum timestamp appropriate for next block\n"
+ " \"curtime\" : current timestamp\n"
" \"bits\" : compressed target of next block\n"
"If [data] is specified, tries to solve the block and returns true if it was successful.");
}
// Update nTime
- pblock->nTime = max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime());
+ pblock->UpdateTime(pindexPrev);
pblock->nNonce = 0;
Array transactions;
result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].vout[0].nValue));
result.push_back(Pair("coinbaseflags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
result.push_back(Pair("time", (int64_t)pblock->nTime));
+ result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast()+1));
+ result.push_back(Pair("curtime", (int64_t)GetAdjustedTime()));
union {
int32_t nBits;
printf("ThreadRPCServer started\n");
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
- if (strRPCUserColonPass == ":")
+ if (mapArgs["-rpcpassword"] == "")
{
+ unsigned char rand_pwd[32];
+ RAND_bytes(rand_pwd, 32);
string strWhatAmI = "To use bitcoind";
if (mapArgs.count("-server"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-server\"");
else if (mapArgs.count("-daemon"))
strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\"");
PrintConsole(
- _("Error: %s, you must set rpcpassword=<password>\nin the configuration file: %s\n"
+ _("Error: %s, you must set a rpcpassword in the configuration file:\n %s\n"
+ "It is recommended you use the following random password:\n"
+ "rpcuser=bitcoinrpc\n"
+ "rpcpassword=%s\n"
+ "(you do not need to remember this password)\n"
"If the file does not exist, create it with owner-readable-only file permissions.\n"),
strWhatAmI.c_str(),
- GetConfigFile().c_str());
+ GetConfigFile().c_str(),
+ EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32).c_str());
#ifndef QT_GUI
CreateThread(Shutdown, NULL);
#endif
}
if (!HTTPAuthorized(mapHeaders))
{
- // Deter brute-forcing short passwords
- if (mapArgs["-rpcpassword"].size() < 15)
- Sleep(50);
+ printf("ThreadRPCServer incorrect password attempt from %s\n",peer.address().to_string().c_str());
+ /* Deter brute-forcing short passwords.
+ If this results in a DOS the user really
+ shouldn't have their RPC port exposed.*/
+ if (mapArgs["-rpcpassword"].size() < 20)
+ Sleep(250);
stream << HTTPReply(401, "") << std::flush;
- printf("ThreadRPCServer incorrect password attempt\n");
continue;
}