Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Encrypt kmip-server database using sqlcipher3. #686

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions docs/source/server.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ as found in the configuration file, is shown below:
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
logging_level=DEBUG
database_path=/tmp/pykmip.db
database_password=pykmip

The server can also be configured manually via Python. The following example
shows how to create the ``KmipServer`` in Python code, directly specifying the
Expand All @@ -64,6 +65,7 @@ different configuration values:
... ],
... logging_level='DEBUG',
... database_path='/tmp/pykmip.db'
... database_password='pykmip'
... )

The different configuration options are defined below:
Expand Down Expand Up @@ -125,6 +127,9 @@ The different configuration options are defined below:
* ``database_path``
A string representing a path to a SQLite database file. The server will
store all managed objects (e.g., keys, certificates) in this file.
* ``database_password``
A string representing the password to encryot the SQLite database file.
Defaults to ``pykmip``.

.. note::
When installing PyKMIP and deploying the server, you must manually set up
Expand Down
18 changes: 17 additions & 1 deletion kmip/services/server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ def __init__(self):
'enable_tls_client_auth',
'tls_cipher_suites',
'logging_level',
'database_path'
'database_path',
'database_password'
]

def set_setting(self, setting, value):
Expand Down Expand Up @@ -96,6 +97,8 @@ def set_setting(self, setting, value):
self._set_tls_cipher_suites(value)
elif setting == 'logging_level':
self._set_logging_level(value)
elif setting == 'database_password':
self._set_database_password(value)
else:
self._set_database_path(value)

Expand Down Expand Up @@ -182,6 +185,9 @@ def _parse_settings(self, parser):
self._set_logging_level(
parser.get('server', 'logging_level')
)
if parser.has_option('server', 'database_password'):
self._set_database_password(parser.get('server', 'database_password'))

if parser.has_option('server', 'database_path'):
self._set_database_path(parser.get('server', 'database_path'))

Expand Down Expand Up @@ -350,3 +356,13 @@ def _set_database_path(self, value):
"The database path, if specified, must be a valid path to a "
"SQLite database file."
)

def _set_database_password(self, value):
if not value:
self.settings['database_password'] = None
elif isinstance(value, six.string_types):
self.settings['database_password'] = value
else:
raise exceptions.ConfigurationError(
"The database password is an invalid string."
)
8 changes: 5 additions & 3 deletions kmip/services/server/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import logging
import six
import sqlalchemy
import sqlcipher3

from sqlalchemy.orm import exc

Expand Down Expand Up @@ -72,7 +73,7 @@ class KmipEngine(object):
* Cryptographic usage mask enforcement per object type
"""

def __init__(self, policies=None, database_path=None):
def __init__(self, policies=None, database_path=None, database_password=None):
"""
Create a KmipEngine.

Expand All @@ -83,14 +84,15 @@ def __init__(self, policies=None, database_path=None):
database_path (string): The path to the SQLite database file
used to store all server data. Optional, defaults to None.
If none, database path defaults to '/tmp/pykmip.database'.
database_password (string): The password to the SQLite database file.
"""
self._logger = logging.getLogger('kmip.server.engine')

self._cryptography_engine = engine.CryptographyEngine()

self.database_path = 'sqlite:///{}'.format(database_path)
self.database_path = 'sqlite+pysqlcipher://:{database_password}@/{database_path}'.format(database_password = database_password, database_path = database_path)
if not database_path:
self.database_path = 'sqlite:////tmp/pykmip.database'
self.database_path = 'sqlite+pysqlcipher://:{database_password}@//tmp/pykmip.database'.format(database_password = database_password)

self._data_store = sqlalchemy.create_engine(
self.database_path,
Expand Down
14 changes: 10 additions & 4 deletions kmip/services/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ def __init__(
tls_cipher_suites=None,
logging_level=None,
live_policies=False,
database_path=None
database_path=None,
database_password='pykmip'
):
"""
Create a KmipServer.
Expand Down Expand Up @@ -127,6 +128,8 @@ def __init__(
to False.
database_path (string): The path to the server's SQLite database
file. Optional, defaults to None.
database_password (string): Password to encrypt the SQLite database
file. Optional, defaults to "pykmip".
"""
self._logger = logging.getLogger('kmip.server')
self._setup_logging(log_path)
Expand All @@ -144,7 +147,8 @@ def __init__(
enable_tls_client_auth,
tls_cipher_suites,
logging_level,
database_path
database_path,
database_password
)
self.live_policies = live_policies
self.policies = {}
Expand Down Expand Up @@ -194,7 +198,8 @@ def _setup_configuration(
enable_tls_client_auth=None,
tls_cipher_suites=None,
logging_level=None,
database_path=None
database_path=None,
database_password="pykmip"
):
if path:
self.config.load_settings(path)
Expand Down Expand Up @@ -261,7 +266,8 @@ def interrupt_handler(trigger, frame):

self._engine = engine.KmipEngine(
policies=self.policies,
database_path=self.config.settings.get('database_path')
database_path=self.config.settings.get('database_path'),
database_password=self.config.settings.get('database_password')
)

self._logger.info("Starting server socket handler.")
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ enum-compat
requests
six>=1.11.0
sqlalchemy>=1.0
sqlcipher3