Skip to content

Commit bd203a9

Browse files
Merge OpenKMIP updates into Cloudian fork (#7)
1 parent 6846449 commit bd203a9

19 files changed

Lines changed: 186 additions & 120 deletions

File tree

.github/workflows/tox.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: tox
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
8+
jobs:
9+
tox-test:
10+
strategy:
11+
matrix:
12+
os: [ubuntu-latest]
13+
python:
14+
- {version: '3.8', env: py38}
15+
- {version: '3.9', env: py39}
16+
- {version: '3.10', env: py310}
17+
- {version: '3.11', env: py311}
18+
test_mode: [0, 1]
19+
runs-on: ${{ matrix.os }}
20+
env:
21+
TOXENV: ${{ matrix.python.env }}
22+
RUN_INTEGRATION_TESTS: ${{ matrix.test_mode }}
23+
steps:
24+
- uses: actions/checkout@v3
25+
- uses: actions/setup-python@v4
26+
with:
27+
python-version: ${{ matrix.python.version }}
28+
- run: pip install tox
29+
- run: pip install codecov
30+
- run: pip install slugs
31+
- run: python3 setup.py install
32+
- run: ./.travis/run.sh
33+
- run: codecov
34+
tox-other:
35+
strategy:
36+
matrix:
37+
os: [ubuntu-latest]
38+
python: ['3.8', '3.9', '3.10', '3.11']
39+
test: [pep8, bandit, docs]
40+
runs-on: ${{ matrix.os }}
41+
env:
42+
TOXENV: ${{ matrix.test }}
43+
steps:
44+
- uses: actions/checkout@v3
45+
- uses: actions/setup-python@v4
46+
with:
47+
python-version: ${{ matrix.python }}
48+
- run: pip install tox
49+
- run: pip install bandit
50+
if: ${{ matrix.test == 'bandit' }}
51+
- run: tox

.travis/run.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
set -e
44
set -x
55

6+
pkill -f run_server.py || true
7+
sleep 1
8+
69
if [[ "${RUN_INTEGRATION_TESTS}" == "1" ]]; then
710
sudo mkdir -p /etc/pykmip/certs
811
sudo mkdir -p /etc/pykmip/policies
@@ -14,6 +17,7 @@ if [[ "${RUN_INTEGRATION_TESTS}" == "1" ]]; then
1417
sudo cp ./.travis/policy.json /etc/pykmip/policies/policy.json
1518
sudo mkdir -p /var/log/pykmip
1619
sudo chmod 777 /var/log/pykmip
20+
sudo chmod -R 777 /etc/pykmip/
1721
python3 ./bin/run_server.py &
1822
tox -e integration -- --config client
1923
elif [[ "${RUN_INTEGRATION_TESTS}" == "2" ]]; then

docs/source/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
#
6565
# This is also used if you do content translation via gettext catalogs.
6666
# Usually you set "language" from the command line for these cases.
67-
language = None
67+
language = 'en'
6868

6969
# List of patterns, relative to source directory, that match files and
7070
# directories to ignore when looking for source files.

kmip/__init__.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
import os
1717
import re
18-
import sys
19-
import warnings
2018

2119
from kmip.core import enums
2220
from kmip.pie import client
@@ -46,22 +44,3 @@
4644
'objects',
4745
'services'
4846
]
49-
50-
51-
if sys.version_info[:2] == (2, 7):
52-
warnings.warn(
53-
(
54-
"PyKMIP will drop support for Python 2.7 in a future release. "
55-
"Please upgrade to a newer version of Python (3.5+ preferred)."
56-
),
57-
PendingDeprecationWarning
58-
)
59-
60-
if sys.version_info[:2] == (3, 4):
61-
warnings.warn(
62-
(
63-
"PyKMIP will drop support for Python 3.4 in a future release. "
64-
"Please upgrade to a newer version of Python (3.5+ preferred)."
65-
),
66-
PendingDeprecationWarning
67-
)

kmip/core/factories/attribute_values.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ def create_attribute_value(self, name, value):
114114
return primitives.Boolean(value, enums.Tags.NEVER_EXTRACTABLE)
115115
elif name is enums.AttributeType.CUSTOM_ATTRIBUTE:
116116
return attributes.CustomAttribute(value)
117+
elif name is enums.AttributeType.ORIGINAL_CREATION_DATE:
118+
return primitives.DateTime(value, enums.Tags.ORIGINAL_CREATION_DATE)
117119
else:
118120
if not isinstance(name, str):
119121
raise ValueError('Unrecognized attribute type: '

kmip/core/messages/contents.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,13 @@ def __init__(self):
506506
super(MessageExtension, self).__init__(enums.Tags.MESSAGE_EXTENSION)
507507

508508

509+
# 6.19
510+
class ServerCorrelationValue(TextString):
511+
def __init__(self, value=None):
512+
super(ServerCorrelationValue, self).__init__(
513+
value, enums.Tags.SERVER_CORRELATION_VALUE)
514+
515+
509516
# 9.1.3.2.2
510517
class KeyCompressionType(Enumeration):
511518

kmip/core/messages/messages.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,14 @@ def __init__(self,
150150
protocol_version=None,
151151
time_stamp=None,
152152
batch_count=None,
153-
server_hashed_password=None):
153+
server_hashed_password=None,
154+
server_correlation_value=None):
154155
super(ResponseHeader, self).__init__(tag=Tags.RESPONSE_HEADER)
155156
self.protocol_version = protocol_version
156157
self.time_stamp = time_stamp
157158
self.batch_count = batch_count
158159
self.server_hashed_password = server_hashed_password
160+
self.server_correlation_value = server_correlation_value
159161

160162
self.validate()
161163

@@ -204,6 +206,10 @@ def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0):
204206
server_hashed_password.read(tstream, kmip_version=kmip_version)
205207
self._server_hashed_password = server_hashed_password
206208

209+
if self.is_tag_next(enums.Tags.SERVER_CORRELATION_VALUE, tstream):
210+
self.server_correlation_value = contents.ServerCorrelationValue()
211+
self.server_correlation_value.read(tstream, kmip_version=kmip_version)
212+
207213
self.batch_count = contents.BatchCount()
208214
self.batch_count.read(tstream, kmip_version=kmip_version)
209215

kmip/services/server/auth/slugs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ def authenticate(self,
8888
)
8989

9090
try:
91-
response = requests.get(self.users_url.format(user_id))
91+
response = requests.get(self.users_url.format(user_id), timeout=10)
9292
except Exception:
9393
raise exceptions.ConfigurationError(
9494
"A connection could not be established using the SLUGS URL."
@@ -98,7 +98,7 @@ def authenticate(self,
9898
"Unrecognized user ID: {}".format(user_id)
9999
)
100100

101-
response = requests.get(self.groups_url.format(user_id))
101+
response = requests.get(self.groups_url.format(user_id), timeout=10)
102102
if response.status_code == 404:
103103
raise exceptions.PermissionDenied(
104104
"Group information could not be retrieved for user ID: "

kmip/services/server/crypto/engine.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,7 @@ def mac(self, algorithm, key, data):
269269
)
270270
cipher_algorithm = self._symmetric_key_algorithms.get(algorithm)
271271
try:
272-
# ARC4 and IDEA algorithms will raise exception as CMAC
273-
# requires block ciphers
272+
# ARC4 and other non-block cipher algorithm will raise TypeError
274273
c = cmac.CMAC(cipher_algorithm(key), backend=default_backend())
275274
c.update(data)
276275
mac_data = c.finalize()
@@ -597,13 +596,17 @@ def _encrypt_asymmetric(self,
597596
"encryption.".format(padding_method)
598597
)
599598

600-
backend = default_backend()
601-
602599
try:
603-
public_key = backend.load_der_public_key(encryption_key)
600+
public_key = serialization.load_der_public_key(
601+
encryption_key,
602+
backend=default_backend()
603+
)
604604
except Exception:
605605
try:
606-
public_key = backend.load_pem_public_key(encryption_key)
606+
public_key = serialization.load_pem_public_key(
607+
encryption_key,
608+
backend=default_backend()
609+
)
607610
except Exception:
608611
raise exceptions.CryptographicFailure(
609612
"The public key bytes could not be loaded."
@@ -1458,8 +1461,6 @@ def verify_signature(self,
14581461
loaded, or when the signature verification process fails
14591462
unexpectedly.
14601463
"""
1461-
backend = default_backend()
1462-
14631464
hash_algorithm = None
14641465
dsa_hash_algorithm = None
14651466
dsa_signing_algorithm = None
@@ -1513,10 +1514,16 @@ def verify_signature(self,
15131514
)
15141515

15151516
try:
1516-
public_key = backend.load_der_public_key(signing_key)
1517+
public_key = serialization.load_der_public_key(
1518+
signing_key,
1519+
backend=default_backend()
1520+
)
15171521
except Exception:
15181522
try:
1519-
public_key = backend.load_pem_public_key(signing_key)
1523+
public_key = serialization.load_pem_public_key(
1524+
signing_key,
1525+
backend=default_backend()
1526+
)
15201527
except Exception:
15211528
raise exceptions.CryptographicFailure(
15221529
"The signing key bytes could not be loaded."

kmip/services/server/engine.py

Lines changed: 66 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -356,80 +356,81 @@ def build_error_response(self, version, reason, message):
356356
def _process_batch(self, request_batch, batch_handling, batch_order):
357357
response_batch = list()
358358

359-
self._data_session = self._data_store_session_factory()
359+
with self._data_store_session_factory() as session:
360+
self._data_session = session
360361

361-
for batch_item in request_batch:
362-
error_occurred = False
362+
for batch_item in request_batch:
363+
error_occurred = False
363364

364-
response_payload = None
365-
result_status = None
366-
result_reason = None
367-
result_message = None
365+
response_payload = None
366+
result_status = None
367+
result_reason = None
368+
result_message = None
368369

369-
operation = batch_item.operation
370-
request_payload = batch_item.request_payload
370+
operation = batch_item.operation
371+
request_payload = batch_item.request_payload
371372

372-
# Process batch item ID.
373-
if len(request_batch) > 1:
374-
if not batch_item.unique_batch_item_id:
375-
raise exceptions.InvalidMessage(
376-
"Batch item ID is undefined."
373+
# Process batch item ID.
374+
if len(request_batch) > 1:
375+
if not batch_item.unique_batch_item_id:
376+
raise exceptions.InvalidMessage(
377+
"Batch item ID is undefined."
378+
)
379+
380+
# Process batch message extension.
381+
# TODO (peterhamilton) Add support for message extension handling.
382+
# 1. Extract the vendor identification and criticality indicator.
383+
# 2. If the indicator is True, raise an error.
384+
# 3. If the indicator is False, ignore the extension.
385+
386+
# Process batch payload.
387+
try:
388+
response_payload = self._process_operation(
389+
operation.value,
390+
request_payload
377391
)
378392

379-
# Process batch message extension.
380-
# TODO (peterhamilton) Add support for message extension handling.
381-
# 1. Extract the vendor identification and criticality indicator.
382-
# 2. If the indicator is True, raise an error.
383-
# 3. If the indicator is False, ignore the extension.
384-
385-
# Process batch payload.
386-
try:
387-
response_payload = self._process_operation(
388-
operation.value,
389-
request_payload
390-
)
393+
result_status = enums.ResultStatus.SUCCESS
394+
except exceptions.KmipError as e:
395+
error_occurred = True
396+
result_status = e.status
397+
result_reason = e.reason
398+
result_message = str(e)
399+
except Exception as e:
400+
self._logger.warning(
401+
"Error occurred while processing operation."
402+
)
403+
self._logger.exception(e)
391404

392-
result_status = enums.ResultStatus.SUCCESS
393-
except exceptions.KmipError as e:
394-
error_occurred = True
395-
result_status = e.status
396-
result_reason = e.reason
397-
result_message = str(e)
398-
except Exception as e:
399-
self._logger.warning(
400-
"Error occurred while processing operation."
401-
)
402-
self._logger.exception(e)
403-
404-
error_occurred = True
405-
result_status = enums.ResultStatus.OPERATION_FAILED
406-
result_reason = enums.ResultReason.GENERAL_FAILURE
407-
result_message = (
408-
"Operation failed. See the server logs for more "
409-
"information."
405+
error_occurred = True
406+
result_status = enums.ResultStatus.OPERATION_FAILED
407+
result_reason = enums.ResultReason.GENERAL_FAILURE
408+
result_message = (
409+
"Operation failed. See the server logs for more "
410+
"information."
411+
)
412+
413+
# Compose operation result.
414+
result_status = contents.ResultStatus(result_status)
415+
if result_reason:
416+
result_reason = contents.ResultReason(result_reason)
417+
if result_message:
418+
result_message = contents.ResultMessage(result_message)
419+
420+
batch_item = messages.ResponseBatchItem(
421+
operation=batch_item.operation,
422+
unique_batch_item_id=batch_item.unique_batch_item_id,
423+
result_status=result_status,
424+
result_reason=result_reason,
425+
result_message=result_message,
426+
response_payload=response_payload
410427
)
428+
response_batch.append(batch_item)
411429

412-
# Compose operation result.
413-
result_status = contents.ResultStatus(result_status)
414-
if result_reason:
415-
result_reason = contents.ResultReason(result_reason)
416-
if result_message:
417-
result_message = contents.ResultMessage(result_message)
418-
419-
batch_item = messages.ResponseBatchItem(
420-
operation=batch_item.operation,
421-
unique_batch_item_id=batch_item.unique_batch_item_id,
422-
result_status=result_status,
423-
result_reason=result_reason,
424-
result_message=result_message,
425-
response_payload=response_payload
426-
)
427-
response_batch.append(batch_item)
428-
429-
# Handle batch error if necessary.
430-
if error_occurred:
431-
if batch_handling == enums.BatchErrorContinuationOption.STOP:
432-
break
430+
# Handle batch error if necessary.
431+
if error_occurred:
432+
if batch_handling == enums.BatchErrorContinuationOption.STOP:
433+
break
433434

434435
self._data_session.close()
435436

0 commit comments

Comments
 (0)