Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
a2b716c
init
Shikugawa Apr 13, 2020
f4fb717
metadata
Shikugawa Apr 13, 2020
06216c0
introduce wasm build with bazel
Shikugawa May 25, 2020
fe44df0
fix compile error
Shikugawa May 27, 2020
54541ba
a
Shikugawa May 29, 2020
d08b2b4
Merge branch 'master' of https://github.com/istio/proxy into authn-wa…
Shikugawa May 29, 2020
3724276
integrate with new build strategy
Shikugawa May 29, 2020
fb933a3
tmp
Shikugawa Jun 3, 2020
04d88bd
tmp
Shikugawa Jun 7, 2020
dd527fb
jwt_authn: replace json processing strategy
Shikugawa Jun 9, 2020
d2d2e9b
cleanup
Shikugawa Jun 9, 2020
f760395
not to use exception
Shikugawa Jun 16, 2020
1d6845b
fix
Shikugawa Jun 16, 2020
9b3f4f6
fix
Shikugawa Jun 16, 2020
087120b
fix
Shikugawa Jun 16, 2020
c14a931
format
Shikugawa Jun 16, 2020
fb1aafe
Merge branch 'master' of https://github.com/istio/proxy into refactor…
Shikugawa Jun 16, 2020
fb8744e
fix
Shikugawa Jun 17, 2020
e598b67
fix
Shikugawa Jun 17, 2020
64c73b3
Merge branch 'master' of https://github.com/istio/proxy into authn-wa…
Shikugawa Jun 17, 2020
39a3bce
fix
Shikugawa Jun 17, 2020
c9b0066
fix
Shikugawa Jun 17, 2020
9f80d3d
stash
Shikugawa Jun 17, 2020
f0ab83c
change CI config
Shikugawa Jun 17, 2020
7c38bab
stash
Shikugawa Jun 18, 2020
93d5b0e
change CI config
Shikugawa Jun 17, 2020
0db34e4
Merge branch 'refactor-jwt-authn' into refactor-authn-utils
Shikugawa Jun 18, 2020
0712dec
authn: relpace json processing strategy
Shikugawa Jun 19, 2020
6e9ae54
fix
Shikugawa Jun 19, 2020
8bc3b49
fix
Shikugawa Jun 19, 2020
9b626ff
stash
Shikugawa Jun 19, 2020
840bce7
Merge branch 'refactor-jwt-authn' into authn-wasm-2
Shikugawa Jun 19, 2020
5692759
stash
Shikugawa Jun 21, 2020
10b8fb0
fix
Shikugawa Jun 21, 2020
645b623
Merge branch 'refactor-jwt-authn' into refactor-authn-utils
Shikugawa Jun 21, 2020
63c66f8
jwt_authn: replace with wasm buildable base64
Shikugawa Jun 21, 2020
78b2bf5
stash
Shikugawa Jun 21, 2020
15da72e
stash
Shikugawa Jun 21, 2020
7b2562e
fix
Shikugawa Jun 21, 2020
aaa5a64
renew authn wasm implementation
Shikugawa Jun 25, 2020
4b09264
stash
Shikugawa Jun 25, 2020
94f2293
resolve conflict
Shikugawa Jul 7, 2020
e619be3
fix
Shikugawa Jul 7, 2020
f725a03
fix
Shikugawa Jul 7, 2020
972bc3e
list
Shikugawa Jul 7, 2020
be2dd43
stash
Shikugawa Jul 8, 2020
909546c
fix
Shikugawa Jul 8, 2020
eba5631
fix
Shikugawa Jul 10, 2020
9bab8e3
conflict
Shikugawa Jul 14, 2020
986742b
fix
Shikugawa Jul 14, 2020
74c5000
deadcode
Shikugawa Jul 14, 2020
5fffebe
stash
Shikugawa Jul 15, 2020
a01f698
abseil: destroy wasm un-compatible repository
Shikugawa Jul 15, 2020
1e175af
Merge branch 'wasm-abseil' of https://github.com/Shikugawa/proxy into…
Shikugawa Jul 15, 2020
3d062f7
Merge branch 'refactor-jwt-base64' of https://github.com/Shikugawa/pr…
Shikugawa Jul 15, 2020
2a3a7ac
update
Shikugawa Jul 16, 2020
2094774
fix
Shikugawa Jul 16, 2020
3b688a2
format
Shikugawa Jul 16, 2020
f211924
fix
Shikugawa Jul 16, 2020
92721c8
Merge branch 'wasm-abseil' of https://github.com/Shikugawa/proxy into…
Shikugawa Jul 16, 2020
81d237d
stash
Shikugawa Jul 16, 2020
ce4b3ce
stash
Shikugawa Jul 16, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ workspace(name = "io_istio_proxy")

# http_archive is not a native function since bazel 0.19
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive", "http_file")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
load(
"//:repositories.bzl",
"docker_dependencies",
Expand Down
33 changes: 32 additions & 1 deletion extensions/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,37 @@ wasm_cc_binary(
],
)

wasm_cc_binary(
name = "authn.wasm",
srcs = [
"//extensions/authn:authenticator_base.h",
"//extensions/authn:authenticator_base.cc",
"//extensions/authn:authn_utils.h",
"//extensions/authn:authn_utils.cc",
"//extensions/authn:filter_context.h",
"//extensions/authn:filter_context.cc",
"//extensions/authn:origin_authenticator.h",
"//extensions/authn:origin_authenticator.cc",
"//extensions/authn:peer_authenticator.h",
"//extensions/authn:peer_authenticator.cc",
"//extensions/authn:plugin.h",
"//extensions/authn:plugin.cc",
],
copts = ["-UNULL_PLUGIN"],
deps = [
"//external:authentication_policy_config_cc_proto",
"//external:abseil_strings",
"//src/istio/authn:context_proto_cc_wasm",
"//src/envoy/utils:filter_names_lib",
"//src/envoy/utils:utils_lib_wasm",
"//src/envoy/http/jwt_auth:jwt_lib_wasm",
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
"@proxy_wasm_cpp_sdk//contrib:contrib_lib",
"@envoy//source/common/http:headers_lib",
"@envoy//source/extensions/filters/http:well_known_names",
],
)

wasm_cc_binary(
name = "metadata_exchange.wasm",
srcs = [
Expand All @@ -56,12 +87,12 @@ wasm_cc_binary(
"//extensions/common:proto_util.h",
"//extensions/common:util.cc",
"//extensions/common:util.h",
"//extensions/metadata_exchange:base64.h",
"//extensions/metadata_exchange:plugin.cc",
"//extensions/metadata_exchange:plugin.h",
],
copts = ["-UNULL_PLUGIN"],
deps = [
"//extensions/common:base64_wasm",
"//extensions/common:json_util_wasm",
"//extensions/common:node_info_fb_cc",
"//extensions/metadata_exchange:declare_property_proto_cc",
Expand Down
2 changes: 1 addition & 1 deletion extensions/access_log_policy/plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#ifndef NULL_PLUGIN

#include "base64.h"
#include "extensions/common/base64.h"

#else

Expand Down
155 changes: 155 additions & 0 deletions extensions/authn/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# Copyright 2018 Istio Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#

package(default_visibility = ["//visibility:public"])

load(
"@envoy//bazel:envoy_build_system.bzl",
"envoy_cc_library",
"envoy_cc_test",
"envoy_cc_test_library",
)

envoy_cc_library(
name = "authn_plugin",
srcs = [
"authenticator_base.cc",
"authn_utils.cc",
"filter_context.cc",
"origin_authenticator.cc",
"peer_authenticator.cc",
# "plugin.cc",
],
hdrs = [
"authenticator_base.h",
"authn_utils.h",
"filter_context.h",
"origin_authenticator.h",
"peer_authenticator.h",
# "plugin.h",
],
repository = "@envoy",
visibility = ["//visibility:public"],
deps = [
"//extensions/common:context",
"//extensions/common:json_util",
"//external:authentication_policy_config_cc_proto",
"//src/envoy/utils:filter_names_lib",
"//src/envoy/utils:utils_lib",
"//src/istio/authn:context_proto_cc_proto",
"@envoy//source/common/http:headers_lib",
"@proxy_wasm_cpp_host//:lib",
"@proxy_wasm_cpp_sdk//contrib:contrib_lib",
],
)

envoy_cc_test_library(
name = "test_utils",
hdrs = ["test_utils.h"],
repository = "@envoy",
deps = [
"//src/istio/authn:context_proto_cc_proto",
],
)

envoy_cc_test(
name = "filter_context_test",
srcs = ["filter_context_test.cc"],
repository = "@envoy",
deps = [
":authn_plugin",
":test_utils",
"@envoy//test/mocks/http:http_mocks",
"@envoy//test/test_common:utility_lib",
],
)

envoy_cc_test(
name = "authenticator_base_test",
srcs = ["authenticator_base_test.cc"],
repository = "@envoy",
deps = [
":authn_plugin",
":test_utils",
"//src/envoy/utils:filter_names_lib",
"@envoy//test/mocks/network:network_mocks",
"@envoy//test/mocks/ssl:ssl_mocks",
"@envoy//test/test_common:utility_lib",
],
)

envoy_cc_test(
name = "authn_utils_test",
srcs = ["authn_utils_test.cc"],
repository = "@envoy",
deps = [
":authn_plugin",
":test_utils",
"@envoy//test/test_common:utility_lib",
],
)

envoy_cc_test(
name = "peer_authenticator_test",
srcs = ["peer_authenticator_test.cc"],
repository = "@envoy",
deps = [
":authn_plugin",
":test_utils",
"@envoy//test/mocks/http:http_mocks",
"@envoy//test/test_common:utility_lib",
],
)

envoy_cc_test(
name = "origin_authenticator_test",
srcs = ["origin_authenticator_test.cc"],
repository = "@envoy",
deps = [
":authn_plugin",
":test_utils",
"@envoy//test/mocks/http:http_mocks",
"@envoy//test/test_common:utility_lib",
],
)

# envoy_cc_test(
# name = "http_filter_test",
# srcs = ["http_filter_test.cc"],
# repository = "@envoy",
# deps = [
# ":filter_lib",
# ":test_utils",
# "//external:authentication_policy_config_cc_proto",
# "@envoy//source/common/http:header_map_lib",
# "@envoy//test/mocks/http:http_mocks",
# "@envoy//test/test_common:utility_lib",
# ],
# )

# envoy_cc_test(
# name = "http_filter_integration_test",
# srcs = ["http_filter_integration_test.cc"],
# data = glob(["testdata/*"]),
# repository = "@envoy",
# deps = [
# ":filter_lib",
# "//src/envoy/utils:filter_names_lib",
# "@envoy//source/common/common:utility_lib",
# "@envoy//test/integration:http_protocol_integration_lib",
# ],
# )
168 changes: 168 additions & 0 deletions extensions/authn/authenticator_base.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/* Copyright 2020 Istio Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "extensions/authn/authenticator_base.h"

#include "absl/strings/str_cat.h"
#include "common/common/assert.h"
#include "extensions/authn/authn_utils.h"
#include "src/envoy/utils/filter_names.h"
#include "src/envoy/utils/utils.h"

using istio::authn::Payload;

namespace iaapi = istio::authentication::v1alpha1;

// WASM_PROLOG
#ifndef NULL_PLUGIN

#include "proxy_wasm_intrinsics.h"

#else // NULL_PLUGIN

#include "include/proxy-wasm/null_plugin.h"

namespace proxy_wasm {
namespace null_plugin {
namespace AuthN {

using proxy_wasm::null_plugin::logDebug;
using proxy_wasm::null_plugin::logError;
using proxy_wasm::null_plugin::logTrace;
using proxy_wasm::null_plugin::logWarn;

#endif // NULL_PLUGIN

using Envoy::Http::LowerCaseString;
using Envoy::Utils::GetPrincipal;
using Envoy::Utils::GetTrustDomain;

namespace {
// The default header name for an exchanged token
static const std::string kExchangedTokenHeaderName = "ingress-authorization";

// Returns whether the header for an exchanged token is found
bool FindHeaderOfExchangedToken(const iaapi::Jwt& jwt) {
return (jwt.jwt_headers_size() == 1 &&
LowerCaseString(kExchangedTokenHeaderName) ==
LowerCaseString(jwt.jwt_headers(0)));
}

} // namespace

AuthenticatorBase::AuthenticatorBase(FilterContext* filter_context)
: filter_context_(*filter_context) {}

AuthenticatorBase::~AuthenticatorBase() {}

bool AuthenticatorBase::validateTrustDomain(
const Connection* connection) const {
std::string peer_trust_domain;
if (!GetTrustDomain(connection, true, &peer_trust_domain)) {
logError("trust domain validation failed: cannot get peer trust domain");
return false;
}

std::string local_trust_domain;
if (!GetTrustDomain(connection, false, &local_trust_domain)) {
logError("trust domain validation failed: cannot get local trust domain");
return false;
}

if (peer_trust_domain != local_trust_domain) {
logError(
absl::StrCat("trust domain validation failed: peer trust domain {} "
"different from local trust domain {}",
peer_trust_domain, local_trust_domain));
return false;
}

logDebug("trust domain validation succeeded");
return true;
}

bool AuthenticatorBase::validateX509(const iaapi::MutualTls& mtls,
Payload* payload) const {
const Connection* connection = filter_context_.connection();
if (connection == nullptr) {
// It's wrong if connection does not exist.
logError("validateX509 failed: null connection.");
return false;
}
// Always try to get principal and set to output if available.
const bool has_user =
connection->ssl() != nullptr &&
connection->ssl()->peerCertificatePresented() &&
GetPrincipal(connection, true, payload->mutable_x509()->mutable_user());
logDebug(absl::StrCat("validateX509 mode {}: ssl={}, has_user={}",
iaapi::MutualTls::Mode_Name(mtls.mode()),
connection->ssl() != nullptr, has_user));

if (!has_user) {
// For plaintext connection, return value depend on mode:
// - PERMISSIVE: always true.
// - STRICT: always false.
switch (mtls.mode()) {
case iaapi::MutualTls::PERMISSIVE:
return true;
case iaapi::MutualTls::STRICT:
return false;
default:
NOT_REACHED_GCOVR_EXCL_LINE;
}
}

if (filter_context_.filter_config().skip_validate_trust_domain()) {
logDebug("trust domain validation skipped");
return true;
}

// For TLS connection with valid certificate, validate trust domain for both
// PERMISSIVE and STRICT mode.
return validateTrustDomain(connection);
}

bool AuthenticatorBase::validateJwt(const iaapi::Jwt& jwt, Payload* payload) {
std::string jwt_payload;
if (filter_context()->getJwtPayload(jwt.issuer(), &jwt_payload)) {
std::string payload_to_process = jwt_payload;
std::string original_payload;
if (FindHeaderOfExchangedToken(jwt)) {
if (AuthnUtils::ExtractOriginalPayload(jwt_payload, &original_payload)) {
// When the header of an exchanged token is found and the token
// contains the claim of the original payload, the original payload
// is extracted and used as the token payload.
payload_to_process = original_payload;
} else {
// When the header of an exchanged token is found but the token
// does not contain the claim of the original payload, it
// is regarded as an invalid exchanged token.
logError(absl::StrCat(
"Expect exchanged-token with original payload claim. Received: {}",
jwt_payload));
return false;
}
}
return AuthnUtils::ProcessJwtPayload(payload_to_process,
payload->mutable_jwt());
}
return false;
}

#ifdef NULL_PLUGIN
} // namespace AuthN
} // namespace null_plugin
} // namespace proxy_wasm
#endif
Loading