summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTor Brede Vekterli <vekterli@yahooinc.com>2022-07-11 14:21:18 +0200
committerGitHub <noreply@github.com>2022-07-11 14:21:18 +0200
commit2ff5525244c48dd0f1aa8a1a44291fd8839d14ec (patch)
treefc23af98ca9091cde9859ab83279f789e6915f83
parent548fcbaa2a98f1626e7fb652db36dbfd4e9a1624 (diff)
parent09269e1dd17c2c272ba385293da2848a0ac03b83 (diff)
Merge pull request #23453 from vespa-engine/vekterli/add-request-access-filter-to-storageapi-rpc
Add request access filter to internal StorageAPI RPC [run-systemtest]
-rw-r--r--fnet/src/vespa/fnet/connection.h8
-rw-r--r--fnet/src/vespa/fnet/frt/require_capabilities.cpp18
-rw-r--r--storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp4
3 files changed, 25 insertions, 5 deletions
diff --git a/fnet/src/vespa/fnet/connection.h b/fnet/src/vespa/fnet/connection.h
index 4d66f22ce2b..10cf74e79de 100644
--- a/fnet/src/vespa/fnet/connection.h
+++ b/fnet/src/vespa/fnet/connection.h
@@ -240,10 +240,6 @@ private:
bool writePendingAfterConnect();
- /**
- * @return address spec of socket peer. Only makes sense to call on non-listening sockets.
- */
- vespalib::string GetPeerSpec() const;
public:
FNET_Connection(const FNET_Connection &) = delete;
FNET_Connection &operator=(const FNET_Connection &) = delete;
@@ -309,6 +305,10 @@ public:
return ((_currentID & 0x01) != (chid & 0x01));
}
+ /**
+ * @return address spec of socket peer. Only makes sense to call on non-listening sockets.
+ */
+ vespalib::string GetPeerSpec() const;
/**
* Does this connection have the ability to accept incoming channels ?
diff --git a/fnet/src/vespa/fnet/frt/require_capabilities.cpp b/fnet/src/vespa/fnet/frt/require_capabilities.cpp
index c74e9ad648a..fc64621717f 100644
--- a/fnet/src/vespa/fnet/frt/require_capabilities.cpp
+++ b/fnet/src/vespa/fnet/frt/require_capabilities.cpp
@@ -5,9 +5,25 @@
#include <vespa/fnet/connection.h>
#include <vespa/vespalib/net/connection_auth_context.h>
+#include <vespa/log/bufferedlogger.h>
+LOG_SETUP(".fnet.frt.require_capabilities");
+
+using namespace vespalib::net::tls;
+
bool
FRT_RequireCapabilities::allow(FRT_RPCRequest& req) const noexcept
{
const auto& auth_ctx = req.GetConnection()->auth_context();
- return auth_ctx.capabilities().contains_all(_required_capabilities);
+ const bool is_authorized = auth_ctx.capabilities().contains_all(_required_capabilities);
+ if (!is_authorized) {
+ auto peer_spec = req.GetConnection()->GetPeerSpec();
+ std::string method_name(req.GetMethodName(), req.GetMethodNameLen());
+ LOGBT(warning, peer_spec, "Permission denied for RPC method '%s'. "
+ "Peer at %s with %s. Call requires %s, but peer has %s",
+ method_name.c_str(), peer_spec.c_str(),
+ to_string(auth_ctx.peer_credentials()).c_str(),
+ _required_capabilities.to_string().c_str(),
+ auth_ctx.capabilities().to_string().c_str());
+ }
+ return is_authorized;
}
diff --git a/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp b/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp
index 006193f0c37..41dcafc055a 100644
--- a/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp
+++ b/storage/src/vespa/storage/storageserver/rpc/storage_api_rpc_service.cpp
@@ -5,6 +5,7 @@
#include "rpc_envelope_proto.h"
#include "shared_rpc_resources.h"
#include "storage_api_rpc_service.h"
+#include <vespa/fnet/frt/require_capabilities.h>
#include <vespa/fnet/frt/supervisor.h>
#include <vespa/fnet/frt/target.h>
#include <vespa/slobrok/sbmirror.h>
@@ -54,6 +55,9 @@ StorageApiRpcService::Params::~Params() = default;
void StorageApiRpcService::register_server_methods(SharedRpcResources& rpc_resources) {
FRT_ReflectionBuilder rb(&rpc_resources.supervisor());
rb.DefineMethod(rpc_v1_method_name(), "bixbix", "bixbix", FRT_METHOD(StorageApiRpcService::RPC_rpc_v1_send), this);
+ rb.RequestAccessFilter(std::make_unique<FRT_RequireCapabilities>(vespalib::net::tls::CapabilitySet::of({
+ vespalib::net::tls::Capability::content_storage_api()
+ })));
rb.MethodDesc("V1 of StorageAPI direct RPC protocol");
rb.ParamDesc("header_encoding", "0=raw, 6=lz4");
rb.ParamDesc("header_decoded_size", "Uncompressed header blob size");