Skip to content
This repository has been archived by the owner on Mar 13, 2022. It is now read-only.

Commit

Permalink
Merge pull request #147 from roycaihw/automated-cherry-pick-of-#79-up…
Browse files Browse the repository at this point in the history
…stream-release-8.0-base64-patch

Automated cherry pick of #79
  • Loading branch information
k8s-ci-robot authored Jul 30, 2019
2 parents 5c242ea + 4017a9d commit 3f6e65b
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 13 deletions.
4 changes: 0 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,6 @@ matrix:
env: TOXENV=py36
- python: 3.6
env: TOXENV=py36-functional
- python: 3.7
env: TOXENV=py37
- python: 3.7
env: TOXENV=py37-functional

install:
- pip install tox
Expand Down
21 changes: 17 additions & 4 deletions config/kube_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,18 +259,31 @@ def _load_oid_token(self, provider):
if 'config' not in provider:
return

parts = provider['config']['id-token'].split('.')
reserved_characters = frozenset(["=", "+", "/"])
token = provider['config']['id-token']

if any(char in token for char in reserved_characters):
# Invalid jwt, as it contains url-unsafe chars
return

parts = token.split('.')
if len(parts) != 3: # Not a valid JWT
return None
return

padding = (4 - len(parts[1]) % 4) * '='
if len(padding) == 3:
# According to spec, 3 padding characters cannot occur
# in a valid jwt
# https://tools.ietf.org/html/rfc7515#appendix-C
return

if PY3:
jwt_attributes = json.loads(
base64.b64decode(parts[1]).decode('utf-8')
base64.b64decode(parts[1] + padding).decode('utf-8')
)
else:
jwt_attributes = json.loads(
base64.b64decode(parts[1] + "==")
base64.b64decode(parts[1] + padding)
)

expire = jwt_attributes.get('exp')
Expand Down
101 changes: 97 additions & 4 deletions config/kube_config_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ def _base64(string):
return base64.standard_b64encode(string.encode()).decode()


def _urlsafe_unpadded_b64encode(string):
return base64.urlsafe_b64encode(string.encode()).decode().rstrip('=')


def _format_expiry_datetime(dt):
return dt.strftime(EXPIRY_DATETIME_FORMAT)

Expand Down Expand Up @@ -94,12 +98,33 @@ def _raise_exception(st):

TEST_OIDC_TOKEN = "test-oidc-token"
TEST_OIDC_INFO = "{\"name\": \"test\"}"
TEST_OIDC_BASE = _base64(TEST_OIDC_TOKEN) + "." + _base64(TEST_OIDC_INFO)
TEST_OIDC_LOGIN = TEST_OIDC_BASE + "." + TEST_CLIENT_CERT_BASE64
TEST_OIDC_BASE = ".".join([
_urlsafe_unpadded_b64encode(TEST_OIDC_TOKEN),
_urlsafe_unpadded_b64encode(TEST_OIDC_INFO)
])
TEST_OIDC_LOGIN = ".".join([
TEST_OIDC_BASE,
_urlsafe_unpadded_b64encode(TEST_CLIENT_CERT_BASE64)
])
TEST_OIDC_TOKEN = "Bearer %s" % TEST_OIDC_LOGIN
TEST_OIDC_EXP = "{\"name\": \"test\",\"exp\": 536457600}"
TEST_OIDC_EXP_BASE = _base64(TEST_OIDC_TOKEN) + "." + _base64(TEST_OIDC_EXP)
TEST_OIDC_EXPIRED_LOGIN = TEST_OIDC_EXP_BASE + "." + TEST_CLIENT_CERT_BASE64
TEST_OIDC_EXP_BASE = _urlsafe_unpadded_b64encode(
TEST_OIDC_TOKEN) + "." + _urlsafe_unpadded_b64encode(TEST_OIDC_EXP)
TEST_OIDC_EXPIRED_LOGIN = ".".join([
TEST_OIDC_EXP_BASE,
_urlsafe_unpadded_b64encode(TEST_CLIENT_CERT)
])
TEST_OIDC_CONTAINS_RESERVED_CHARACTERS = ".".join([
_urlsafe_unpadded_b64encode(TEST_OIDC_TOKEN),
_urlsafe_unpadded_b64encode(TEST_OIDC_INFO).replace("a", "+"),
_urlsafe_unpadded_b64encode(TEST_CLIENT_CERT)
])
TEST_OIDC_INVALID_PADDING_LENGTH = ".".join([
_urlsafe_unpadded_b64encode(TEST_OIDC_TOKEN),
"aaaaa",
_urlsafe_unpadded_b64encode(TEST_CLIENT_CERT)
])

TEST_OIDC_CA = _base64(TEST_CERTIFICATE_AUTH)


Expand Down Expand Up @@ -406,6 +431,22 @@ class TestKubeConfigLoader(BaseTestCase):
"user": "expired_oidc_nocert"
}
},
{
"name": "oidc_contains_reserved_character",
"context": {
"cluster": "default",
"user": "oidc_contains_reserved_character"

}
},
{
"name": "oidc_invalid_padding_length",
"context": {
"cluster": "default",
"user": "oidc_invalid_padding_length"

}
},
{
"name": "user_pass",
"context": {
Expand Down Expand Up @@ -592,6 +633,38 @@ class TestKubeConfigLoader(BaseTestCase):
}
}
},
{
"name": "oidc_contains_reserved_character",
"user": {
"auth-provider": {
"name": "oidc",
"config": {
"client-id": "tectonic-kubectl",
"client-secret": "FAKE_SECRET",
"id-token": TEST_OIDC_CONTAINS_RESERVED_CHARACTERS,
"idp-issuer-url": "https://example.org/identity",
"refresh-token":
"lucWJjEhlxZW01cXI3YmVlcYnpxNGhzk"
}
}
}
},
{
"name": "oidc_invalid_padding_length",
"user": {
"auth-provider": {
"name": "oidc",
"config": {
"client-id": "tectonic-kubectl",
"client-secret": "FAKE_SECRET",
"id-token": TEST_OIDC_INVALID_PADDING_LENGTH,
"idp-issuer-url": "https://example.org/identity",
"refresh-token":
"lucWJjEhlxZW01cXI3YmVlcYnpxNGhzk"
}
}
}
},
{
"name": "user_pass",
"user": {
Expand Down Expand Up @@ -790,6 +863,26 @@ def test_oidc_with_refresh_nocert(
self.assertTrue(loader._load_auth_provider_token())
self.assertEqual("Bearer abc123", loader.token)

def test_oidc_fails_if_contains_reserved_chars(self):
loader = KubeConfigLoader(
config_dict=self.TEST_KUBE_CONFIG,
active_context="oidc_contains_reserved_character",
)
self.assertEqual(
loader._load_oid_token("oidc_contains_reserved_character"),
None,
)

def test_oidc_fails_if_invalid_padding_length(self):
loader = KubeConfigLoader(
config_dict=self.TEST_KUBE_CONFIG,
active_context="oidc_invalid_padding_length",
)
self.assertEqual(
loader._load_oid_token("oidc_invalid_padding_length"),
None,
)

def test_user_pass(self):
expected = FakeConfig(host=TEST_HOST, token=TEST_BASIC_TOKEN)
actual = FakeConfig()
Expand Down
1 change: 1 addition & 0 deletions run_tox.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ popd > /dev/null
cd "${TMP_DIR}"
git clone https://github.com/kubernetes-client/python.git
cd python
git checkout release-8.0
git config user.email "kubernetes-client@k8s.com"
git config user.name "kubenetes client"
git rm -rf kubernetes/base
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tox]
skipsdist = True
envlist = py27, py34, py35, py36, py37
envlist = py27, py34, py35, py36

[testenv]
passenv = TOXENV CI TRAVIS TRAVIS_*
Expand Down

0 comments on commit 3f6e65b

Please sign in to comment.