Skip to content

Commit

Permalink
add DNS SAN as principal (#7881)
Browse files Browse the repository at this point in the history
Description: Adds support for DNS SAN as Principal in RBAC filter.
Risk Level: Low
Testing: Added automated tests
Docs Changes: Updated
Release Notes: Added
Fixes #7836

Signed-off-by: Rama Chavali <rama.rao@salesforce.com>
  • Loading branch information
ramaraochavali authored and lizan committed Aug 15, 2019
1 parent 5c9f1f0 commit 882a306
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
5 changes: 3 additions & 2 deletions api/envoy/config/rbac/v2/rbac.proto
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,9 @@ message Principal {
reserved 1;
reserved "name";

// The name of the principal. If set, The URI SAN is used from the certificate, otherwise the
// subject field is used. If unset, it applies to any user that is authenticated.
// The name of the principal. If set, The URI SAN or DNS SAN in that order is used from the
// certificate, otherwise the subject field is used. If unset, it applies to any user that is
// authenticated.
envoy.type.matcher.StringMatcher principal_name = 2;
}

Expand Down
1 change: 1 addition & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Version history
* http: added the ability to :ref:`merge adjacent slashes<envoy_api_field_config.filter.network.http_connection_manager.v2.HttpConnectionManager.merge_slashes>` in the path.
* listeners: added :ref:`continue_on_listener_filters_timeout <envoy_api_field_Listener.continue_on_listener_filters_timeout>` to configure whether a listener will still create a connection when listener filters time out.
* listeners: added :ref:`HTTP inspector listener filter <config_listener_filters_http_inspector>`.
* rbac: added support for DNS SAN as :ref:`principal_name <envoy_api_field_config.rbac.v2.Principal.Authenticated.principal_name>`.
* lua: extended `httpCall()` and `respond()` APIs to accept headers with entry values that can be a string or table of strings.
* performance: new buffer implementation enabled by default (to disable add "--use-libevent-buffers 1" to the command-line arguments when starting Envoy).
* router: added :ref:`rq_retry_skipped_request_not_complete <config_http_filters_router_stats>` counter stat to router stats.
Expand Down
13 changes: 10 additions & 3 deletions source/extensions/filters/common/rbac/matchers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,17 @@ bool AuthenticatedMatcher::matches(const Network::Connection& connection,

const auto uriSans = ssl->uriSanPeerCertificate();
std::string principal;
if (uriSans.empty()) {
principal = ssl->subjectPeerCertificate();
} else {
// If set, The URI SAN or DNS SAN in that order is used as Principal, otherwise the subject field
// is used.
if (!uriSans.empty()) {
principal = uriSans[0];
} else {
const auto dnsSans = ssl->dnsSansPeerCertificate();
if (!dnsSans.empty()) {
principal = dnsSans[0];
} else {
principal = ssl->subjectPeerCertificate();
}
}

return matcher_.value().match(principal);
Expand Down
23 changes: 23 additions & 0 deletions test/extensions/filters/common/rbac/matchers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,12 +205,35 @@ TEST(AuthenticatedMatcher, uriSanPeerCertificate) {
checkMatcher(AuthenticatedMatcher(auth), false, conn);
}

TEST(AuthenticatedMatcher, dnsSanPeerCertificate) {
Envoy::Network::MockConnection conn;
Envoy::Ssl::MockConnectionInfo ssl;

const std::vector<std::string> uri_sans;
const std::vector<std::string> dns_sans{"foo", "baz"};

EXPECT_CALL(ssl, uriSanPeerCertificate()).WillRepeatedly(Return(uri_sans));
EXPECT_CALL(Const(conn), ssl()).WillRepeatedly(Return(&ssl));

EXPECT_CALL(ssl, dnsSansPeerCertificate()).WillRepeatedly(Return(dns_sans));
EXPECT_CALL(Const(conn), ssl()).WillRepeatedly(Return(&ssl));

// We should get the first DNS SAN as URI SAN is not available.
envoy::config::rbac::v2::Principal_Authenticated auth;
auth.mutable_principal_name()->set_exact("foo");
checkMatcher(AuthenticatedMatcher(auth), true, conn);

auth.mutable_principal_name()->set_exact("bar");
checkMatcher(AuthenticatedMatcher(auth), false, conn);
}

TEST(AuthenticatedMatcher, subjectPeerCertificate) {
Envoy::Network::MockConnection conn;
Envoy::Ssl::MockConnectionInfo ssl;

const std::vector<std::string> sans;
EXPECT_CALL(ssl, uriSanPeerCertificate()).WillRepeatedly(Return(sans));
EXPECT_CALL(ssl, dnsSansPeerCertificate()).WillRepeatedly(Return(sans));
EXPECT_CALL(ssl, subjectPeerCertificate()).WillRepeatedly(Return("bar"));
EXPECT_CALL(Const(conn), ssl()).WillRepeatedly(Return(&ssl));

Expand Down

0 comments on commit 882a306

Please sign in to comment.