diff options
| author | Nils Maier <maierman@web.de> | 2014-07-15 08:15:46 +0200 |
|---|---|---|
| committer | Nils Maier <maierman@web.de> | 2014-07-22 21:58:30 +0200 |
| commit | 8f2af33b6dd33e7937480e37f06d325e812dee8f (patch) | |
| tree | b74350f9d538150246e22551ac65b20c92cf466c /src/RpcMethodImpl.cc | |
| parent | 24ae459523e4a41c711990b04bd9ed6f1222f559 (diff) | |
Delay auth failures instead of PBKDF2
Closes GH-256
Diffstat (limited to 'src/RpcMethodImpl.cc')
| -rw-r--r-- | src/RpcMethodImpl.cc | 111 |
1 files changed, 65 insertions, 46 deletions
diff --git a/src/RpcMethodImpl.cc b/src/RpcMethodImpl.cc index fd4c3d49..eb1a094f 100644 --- a/src/RpcMethodImpl.cc +++ b/src/RpcMethodImpl.cc @@ -1360,54 +1360,73 @@ std::unique_ptr<ValueBase> SaveSessionRpcMethod::process std::unique_ptr<ValueBase> SystemMulticallRpcMethod::process (const RpcRequest& req, DownloadEngine* e) { - const List* methodSpecs = checkRequiredParam<List>(req, 0); - auto list = List::g(); - auto auth = RpcRequest::MUST_AUTHORIZE; - for(auto & methodSpec : *methodSpecs) { - Dict* methodDict = downcast<Dict>(methodSpec); - if(!methodDict) { - list->append(createErrorResponse - (DL_ABORT_EX("system.multicall expected struct."), req)); - continue; - } - const String* methodName = downcast<String>(methodDict->get(KEY_METHOD_NAME)); - if(!methodName) { - list->append(createErrorResponse - (DL_ABORT_EX("Missing methodName."), req)); - continue; - } - if(methodName->s() == getMethodName()) { - list->append(createErrorResponse - (DL_ABORT_EX("Recursive system.multicall forbidden."), req)); - continue; - } - // TODO what if params missing? - auto tempParamsList = methodDict->get(KEY_PARAMS); - std::unique_ptr<List> paramsList; - if(downcast<List>(tempParamsList)) { - paramsList.reset(static_cast<List*>(methodDict->popValue(KEY_PARAMS) - .release())); - } else { - paramsList = List::g(); - } - RpcRequest r = { - methodName->s(), - std::move(paramsList), - nullptr, - auth, - req.jsonRpc - }; - RpcResponse res = getMethod(methodName->s())->execute(std::move(r), e); - if(res.code == 0) { - auto l = List::g(); - l->append(std::move(res.param)); - list->append(std::move(l)); - auth = RpcRequest::PREAUTHORIZED; - } else { - list->append(std::move(res.param)); + // Should never get here, since SystemMulticallRpcMethod overrides execute(). + assert(false); + return nullptr; +} + +RpcResponse SystemMulticallRpcMethod::execute(RpcRequest req, DownloadEngine *e) +{ + auto preauthorized = RpcRequest::MUST_AUTHORIZE; + auto authorized = RpcResponse::AUTHORIZED; + try { + const List* methodSpecs = checkRequiredParam<List>(req, 0); + auto list = List::g(); + for(auto & methodSpec : *methodSpecs) { + Dict* methodDict = downcast<Dict>(methodSpec); + if(!methodDict) { + list->append(createErrorResponse + (DL_ABORT_EX("system.multicall expected struct."), req)); + continue; + } + const String* methodName = downcast<String>(methodDict->get(KEY_METHOD_NAME)); + if(!methodName) { + list->append(createErrorResponse + (DL_ABORT_EX("Missing methodName."), req)); + continue; + } + if(methodName->s() == getMethodName()) { + list->append(createErrorResponse + (DL_ABORT_EX("Recursive system.multicall forbidden."), req)); + continue; + } + // TODO what if params missing? + auto tempParamsList = methodDict->get(KEY_PARAMS); + std::unique_ptr<List> paramsList; + if(downcast<List>(tempParamsList)) { + paramsList.reset(static_cast<List*>(methodDict->popValue(KEY_PARAMS) + .release())); + } else { + paramsList = List::g(); + } + RpcRequest r = { + methodName->s(), + std::move(paramsList), + nullptr, + preauthorized, + req.jsonRpc + }; + RpcResponse res = getMethod(methodName->s())->execute(std::move(r), e); + if(rpc::not_authorized(res)) { + authorized = RpcResponse::NOTAUTHORIZED; + } else { + preauthorized = RpcRequest::PREAUTHORIZED; + } + if(res.code == 0) { + auto l = List::g(); + l->append(std::move(res.param)); + list->append(std::move(l)); + } else { + list->append(std::move(res.param)); + } } + return RpcResponse(0, authorized, std::move(list), std::move(req.id)); + + } catch(RecoverableException& ex) { + A2_LOG_DEBUG_EX(EX_EXCEPTION_CAUGHT, ex); + return RpcResponse(1, authorized, createErrorResponse(ex, req), + std::move(req.id)); } - return std::move(list); } std::unique_ptr<ValueBase> NoSuchMethodRpcMethod::process |
