Add validation of Docker V2_1 schemas and add a test for PUTing an invalid schema

This commit is contained in:
Joseph Schorr 2017-12-20 11:35:43 -05:00
parent 11e3724919
commit f9bd7ef42b
2 changed files with 90 additions and 2 deletions

View file

@ -11,6 +11,8 @@ import logging
from collections import namedtuple, OrderedDict
from datetime import datetime
from jsonschema import validate as validate_schema, ValidationError
from jwkest.jws import SIGNER_ALGS, keyrep
from jwt.utils import base64url_encode, base64url_decode
@ -84,6 +86,73 @@ class Schema1V1Metadata(namedtuple('Schema1V1Metadata', ['image_id', 'parent_ima
class DockerSchema1Manifest(object):
METASCHEMA = {
'type': 'object',
'properties': {
DOCKER_SCHEMA1_SIGNATURES_KEY: {
'type': 'array',
'items': {
'type': 'object',
'properties': {
DOCKER_SCHEMA1_PROTECTED_KEY: {
'type': 'string',
},
DOCKER_SCHEMA1_HEADER_KEY: {
'type': 'object',
'properties': {
'alg': {
'type': 'string',
},
'jwk': {
'type': 'object',
},
},
'required': ['alg', 'jwk'],
},
DOCKER_SCHEMA1_SIGNATURE_KEY: {
'type': 'string',
},
},
'required': [DOCKER_SCHEMA1_PROTECTED_KEY, DOCKER_SCHEMA1_HEADER_KEY,
DOCKER_SCHEMA1_SIGNATURE_KEY],
},
},
DOCKER_SCHEMA1_REPO_TAG_KEY: {
'type': 'string',
},
DOCKER_SCHEMA1_REPO_NAME_KEY: {
'type': 'string',
},
DOCKER_SCHEMA1_HISTORY_KEY: {
'type': 'array',
'items': {
'type': 'object',
'properties': {
DOCKER_SCHEMA1_V1_COMPAT_KEY: {
'type': 'string',
},
},
'required': [DOCKER_SCHEMA1_V1_COMPAT_KEY],
},
},
DOCKER_SCHEMA1_FS_LAYERS_KEY: {
'type': 'array',
'items': {
'type': 'object',
'properties': {
DOCKER_SCHEMA1_BLOB_SUM_KEY: {
'type': 'string',
},
},
'required': [DOCKER_SCHEMA1_BLOB_SUM_KEY],
},
},
},
'required': [DOCKER_SCHEMA1_SIGNATURES_KEY, DOCKER_SCHEMA1_REPO_TAG_KEY,
DOCKER_SCHEMA1_REPO_NAME_KEY, DOCKER_SCHEMA1_FS_LAYERS_KEY,
DOCKER_SCHEMA1_HISTORY_KEY],
}
def __init__(self, manifest_bytes, validate=True):
self._layers = None
self._bytes = manifest_bytes
@ -93,6 +162,11 @@ class DockerSchema1Manifest(object):
except ValueError as ve:
raise MalformedSchema1Manifest('malformed manifest data: %s' % ve)
try:
validate_schema(self._parsed, DockerSchema1Manifest.METASCHEMA)
except ValidationError as ve:
raise MalformedSchema1Manifest('malformed manifest data: %s' % ve)
self._signatures = self._parsed[DOCKER_SCHEMA1_SIGNATURES_KEY]
self._tag = self._parsed[DOCKER_SCHEMA1_REPO_TAG_KEY]

View file

@ -1371,8 +1371,8 @@ class V1RegistryTests(V1RegistryPullMixin, V1RegistryPushMixin, RegistryTestsMix
# Try some logins.
self.conduct('POST', '/v1/users', json_data={'username': 'freshuser'}, expected_code=400)
resp = self.conduct('POST', '/v1/users',
json_data={'username': 'devtable', 'password': 'password'},
expected_code=400)
json_data={'username': 'devtable', 'password': 'password'},
expected_code=400)
# Because Docker
self.assertEquals('"Username or email already exists"', resp.text)
@ -1623,6 +1623,20 @@ class V2RegistryTests(V2RegistryPullMixin, V2RegistryPushMixin, RegistryTestsMix
headers={'Content-Type': 'application/vnd.docker.distribution.manifest.v2+json'},
auth='jwt')
def test_invalid_manifest(self):
namespace = 'devtable'
repository = 'somerepo'
tag_name = 'sometag'
repo_name = _get_repo_name(namespace, repository)
self.v2_ping()
self.do_auth('devtable', 'password', namespace, repository, scopes=['push', 'pull'])
self.conduct('PUT', '/v2/%s/manifests/%s' % (repo_name, tag_name),
data='{}', expected_code=400,
auth='jwt')
def test_oci_manifest_type(self):
namespace = 'devtable'
repository = 'somerepo'