Auto merge of #2006 - bitcartel:1497_destination_path_validation_when_exporting, r=bitcartel

Fixes #1497 ZCA-009 by restricting export to a user defined folder and sanitizing filenames
This commit is contained in:
zkbot
2017-01-18 18:19:50 +00:00
9 changed files with 122 additions and 30 deletions

View File

@@ -1769,21 +1769,38 @@ Value backupwallet(const Array& params, bool fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"backupwallet \"destination\"\n"
"\nSafely copies wallet.dat to destination, which can be a directory or a path with filename.\n"
"\nSafely copies wallet.dat to destination filename\n"
"\nArguments:\n"
"1. \"destination\" (string) The destination directory or file\n"
"1. \"destination\" (string, required) The destination filename, saved in the directory set by -exportdir option.\n"
"\nResult:\n"
"\"path\" (string) The full path of the destination file\n"
"\nExamples:\n"
+ HelpExampleCli("backupwallet", "\"backup.dat\"")
+ HelpExampleRpc("backupwallet", "\"backup.dat\"")
+ HelpExampleCli("backupwallet", "\"backupdata\"")
+ HelpExampleRpc("backupwallet", "\"backupdata\"")
);
LOCK2(cs_main, pwalletMain->cs_wallet);
string strDest = params[0].get_str();
if (!BackupWallet(*pwalletMain, strDest))
boost::filesystem::path exportdir;
try {
exportdir = GetExportDir();
} catch (const std::runtime_error& e) {
throw JSONRPCError(RPC_INTERNAL_ERROR, e.what());
}
if (exportdir.empty()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot backup wallet until the -exportdir option has been set");
}
std::string unclean = params[0].get_str();
std::string clean = SanitizeFilename(unclean);
if (clean.compare(unclean) != 0) {
throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Filename is invalid as only alphanumeric characters are allowed. Try '%s' instead.", clean));
}
boost::filesystem::path exportfilepath = exportdir / clean;
if (!BackupWallet(*pwalletMain, exportfilepath.string()))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
return Value::null;
return exportfilepath.string();
}