Fix RIPD-166:

* Allow RPC commands sign and submit to sign using the regular key.
* Allow command line RPC command submit to take an "offline" flag.
* Mark SerializedObject.getFlags() as const.
This commit is contained in:
Tom Swirly
2014-04-23 18:15:08 -04:00
committed by Vinnie Falco
parent c39fd4e64d
commit 360db3c7ca
6 changed files with 37 additions and 39 deletions

View File

@@ -558,7 +558,7 @@ bool STObject::clearFlag (std::uint32_t f)
return true;
}
bool STObject::isFlag (std::uint32_t f)
bool STObject::isFlag (std::uint32_t f) const
{
return (getFlags () & f) == f;
}

View File

@@ -156,7 +156,7 @@ public:
bool setFlag (std::uint32_t);
bool clearFlag (std::uint32_t);
bool isFlag(std::uint32_t);
bool isFlag(std::uint32_t) const;
std::uint32_t getFlags () const;
uint256 getHash (std::uint32_t prefix) const;

View File

@@ -82,7 +82,7 @@ private:
}
else
{
return RPC::make_param_error (std::string ("Invalid currency/issuer '") +
return RPC::make_param_error (std::string ("Invalid currency/issuer '") +
strCurrencyIssuer + "'");
}
}
@@ -829,7 +829,7 @@ public:
{ "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 },
{ "sign", &RPCParser::parseSignSubmit, 2, 3 },
{ "sms", &RPCParser::parseSMS, 1, 1 },
{ "submit", &RPCParser::parseSignSubmit, 1, 2 },
{ "submit", &RPCParser::parseSignSubmit, 1, 3 },
{ "server_info", &RPCParser::parseAsIs, 0, 0 },
{ "server_state", &RPCParser::parseAsIs, 0, 0 },
{ "stop", &RPCParser::parseAsIs, 0, 0 },

View File

@@ -58,6 +58,7 @@ enum error_code_i
rpcACT_NOT_FOUND,
rpcINSUF_FUNDS,
rpcLGR_NOT_FOUND,
rpcMASTER_DISABLED,
rpcNICKNAME_MISSING,
rpcNO_ACCOUNT,
rpcNO_PATH,

View File

@@ -52,7 +52,6 @@ public:
add (rpcACT_MALFORMED, "actMalformed", "Account malformed.");
add (rpcACT_NOT_FOUND, "actNotFound", "Account not found.");
add (rpcBAD_BLOB, "badBlob", "Blob must be a non-empty hex string.");
add (rpcHIGH_FEE, "highFee", "Current transaction fee exceeds your limit.");
add (rpcBAD_FEATURE, "badFeature", "Feature unknown or invalid.");
add (rpcBAD_ISSUER, "badIssuer", "Issuer account malformed.");
add (rpcBAD_MARKET, "badMarket", "No such market.");
@@ -64,10 +63,11 @@ public:
add (rpcDST_ACT_MISSING, "dstActMissing", "Destination account does not exist.");
add (rpcDST_AMT_MALFORMED, "dstAmtMalformed", "Destination amount/currency/issuer is malformed.");
add (rpcDST_ISR_MALFORMED, "dstIsrMalformed", "Destination issuer is malformed.");
add (rpcFORBIDDEN, "forbidden", "Bad credentials.");
add (rpcFAIL_GEN_DECRYPT, "failGenDecrypt", "Failed to decrypt generator.");
add (rpcFORBIDDEN, "forbidden", "Bad credentials.");
add (rpcGETS_ACT_MALFORMED, "getsActMalformed", "Gets account malformed.");
add (rpcGETS_AMT_MALFORMED, "getsAmtMalformed", "Gets amount malformed.");
add (rpcHIGH_FEE, "highFee", "Current transaction fee exceeds your limit.");
add (rpcHOST_IP_MALFORMED, "hostIpMalformed", "Host IP is malformed.");
add (rpcINSUF_FUNDS, "insufFunds", "Insufficient funds.");
add (rpcINTERNAL, "internal", "Internal error.");
@@ -76,6 +76,7 @@ public:
add (rpcLGR_IDXS_INVALID, "lgrIdxsInvalid", "Ledger indexes invalid.");
add (rpcLGR_IDX_MALFORMED, "lgrIdxMalformed", "Ledger index malformed.");
add (rpcLGR_NOT_FOUND, "lgrNotFound", "Ledger not found.");
add (rpcMASTER_DISABLED, "masterDisabled", "Master key is disabled.");
add (rpcNICKNAME_MALFORMED, "nicknameMalformed", "Nickname is malformed.");
add (rpcNICKNAME_MISSING, "nicknameMissing", "Nickname does not exist.");
add (rpcNICKNAME_PERM, "nicknamePerm", "Account does not control nickname.");
@@ -85,7 +86,7 @@ public:
add (rpcNO_CURRENT, "noCurrent", "Current ledger is unavailable.");
add (rpcNO_EVENTS, "noEvents", "Current transport does not support events.");
add (rpcNO_GEN_DECRYPT, "noGenDecrypt", "Password failed to decrypt master public generator.");
add (rpcNO_NETWORK, "noNetwork", "Network not available.");
add (rpcNO_NETWORK, "noNetwork", "Not synced to Ripple network.");
add (rpcNO_PATH, "noPath", "Unable to find a ripple path.");
add (rpcNO_PERMISSION, "noPermission", "You don't have permission for this command.");
add (rpcNO_PF_REQUEST, "noPathRequest", "No pathfinding request in progress.");

View File

@@ -189,14 +189,14 @@ Json::Value transactionSign (
return RPC::make_error (rpcSRC_ACT_MALFORMED,
RPC::invalid_field_message ("tx_json.Account"));
bool const bOffline (
bool const verify = !(
params.isMember ("offline") && params["offline"].asBool ());
if (! tx_json.isMember ("Sequence") && bOffline)
if (!tx_json.isMember ("Sequence") && !verify)
return RPC::missing_field_error ("tx_json.Sequence");
// Check for current ledger
if (!bOffline && !getConfig ().RUN_STANDALONE &&
if (verify && !getConfig ().RUN_STANDALONE &&
(getApp().getLedgerMaster().getValidatedLedgerAge() > 120))
return rpcError (rpcNO_CURRENT);
@@ -205,11 +205,11 @@ Json::Value transactionSign (
return rpcError(rpcTOO_BUSY);
Ledger::pointer lSnapshot = netOps.getCurrentLedger ();
AccountState::pointer asSrc = bOffline
AccountState::pointer asSrc = !verify
? AccountState::pointer () // Don't look up address if offline.
: netOps.getAccountState (lSnapshot, raSrcAddressID);
if (!bOffline && !asSrc)
if (verify && !asSrc)
{
// If not offline and did not find account, error.
WriteLog (lsDEBUG, RPCHandler) << boost::str (boost::format ("transactionSign: Failed to find source account in current ledger: %s")
@@ -311,9 +311,10 @@ Json::Value transactionSign (
if (!tx_json.isMember ("Sequence"))
{
if (bOffline)
if (!verify)
{
// If offline, Sequence is mandatory.
// TODO: duplicates logic above.
return rpcError (rpcINVALID_PARAMS);
}
else
@@ -324,7 +325,7 @@ Json::Value transactionSign (
if (!tx_json.isMember ("Flags")) tx_json["Flags"] = tfFullyCanonicalSig;
if (!bOffline)
if (verify)
{
SLE::pointer sleAccountRoot = netOps.getSLEi (lSnapshot,
Ledger::getAccountRootIndex (raSrcAddressID.getAccountID ()));
@@ -344,41 +345,35 @@ Json::Value transactionSign (
RippleAddress naMasterGenerator = RippleAddress::createGeneratorPublic (
naSecret);
// Find the index of Account from the master generator, so we can generate
// the public and private keys.
RippleAddress naMasterAccountPublic;
unsigned int iIndex = 0;
bool bFound = false;
// Don't look at ledger entries to determine if the account exists.
// Don't want to leak to thin server that these accounts are related.
while (!bFound && iIndex != getConfig ().ACCOUNT_PROBE_MAX)
if (verify)
{
naMasterAccountPublic.setAccountPublic (naMasterGenerator, iIndex);
auto masterAccountPublic = RippleAddress::createAccountPublic (
naMasterGenerator, 0);
auto account = masterAccountPublic.getAccountID();
auto const& sle = asSrc->peekSLE();
WriteLog (lsWARNING, RPCHandler) <<
"authorize: " << iIndex <<
" : " << naMasterAccountPublic.humanAccountID () <<
" : " << raSrcAddressID.humanAccountID ();
bFound = raSrcAddressID.getAccountID () == naMasterAccountPublic.getAccountID ();
if (!bFound)
++iIndex;
}
if (!bFound)
{
return rpcError (rpcBAD_SECRET);
"verify: " << masterAccountPublic.humanAccountID () <<
" : " << raSrcAddressID.humanAccountID ();
if (raSrcAddressID.getAccountID () == account)
{
if (sle.isFlag(lsfDisableMaster))
return rpcError (rpcMASTER_DISABLED);
}
else if (!sle.isFieldPresent(sfRegularKey) ||
account != sle.getFieldAccount160 (sfRegularKey))
{
return rpcError (rpcBAD_SECRET);
}
}
// Use the generator to determine the associated public and private keys.
RippleAddress naGenerator = RippleAddress::createGeneratorPublic (
naSecret);
RippleAddress naAccountPublic = RippleAddress::createAccountPublic (
naGenerator, iIndex);
naGenerator, 0);
RippleAddress naAccountPrivate = RippleAddress::createAccountPrivate (
naGenerator, naSecret, iIndex);
naGenerator, naSecret, 0);
if (bHaveAuthKey
// The generated pair must match authorized...
@@ -386,6 +381,7 @@ Json::Value transactionSign (
// ... or the master key must have been used.
&& raSrcAddressID.getAccountID () != naAccountPublic.getAccountID ())
{
// TODO: we can't ever get here!
// Log::out() << "iIndex: " << iIndex;
// Log::out() << "sfAuthorizedKey: " << strHex(asSrc->getAuthorizedKey().getAccountID());
// Log::out() << "naAccountPublic: " << strHex(naAccountPublic.getAccountID());