summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2013-02-21 19:47:35 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2013-03-07 17:51:32 -0500
commitc87a65024177ed67cd4ec0f7d533d973f8e1f971 (patch)
treedcceb0a14d514c62773ee07a1fcb09e787dae6e4 /base
parentb18a44db98f19c4d9b9d8d586d2bd1772a5d9f41 (diff)
downloadpki-c87a65024177ed67cd4ec0f7d533d973f8e1f971.tar.gz
pki-c87a65024177ed67cd4ec0f7d533d973f8e1f971.tar.xz
pki-c87a65024177ed67cd4ec0f7d533d973f8e1f971.zip
Added security domain info validation.
The installer script has been modified to validate security domain info in both interactive and silent installation. A basic Python API has been added to access the REST interface. Ticket #473
Diffstat (limited to 'base')
-rw-r--r--base/common/CMakeLists.txt8
-rw-r--r--base/common/python/pki/__init__.py0
-rw-r--r--base/common/python/pki/account.py31
-rw-r--r--base/common/python/pki/client.py53
-rw-r--r--base/common/python/pki/system.py38
-rw-r--r--base/deploy/CMakeLists.txt16
-rwxr-xr-xbase/deploy/src/pkispawn73
-rw-r--r--base/deploy/src/scriptlets/pkilogging.py40
-rw-r--r--base/deploy/src/scriptlets/pkiparser.py23
9 files changed, 224 insertions, 58 deletions
diff --git a/base/common/CMakeLists.txt b/base/common/CMakeLists.txt
index 73877c82c..e48133986 100644
--- a/base/common/CMakeLists.txt
+++ b/base/common/CMakeLists.txt
@@ -1,5 +1,13 @@
project(common NONE)
+# install Python libraries
+install(
+ DIRECTORY
+ python/
+ DESTINATION
+ ${PYTHON_SITE_PACKAGES}
+)
+
# install systemd scripts
install(
FILES
diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/base/common/python/pki/__init__.py
diff --git a/base/common/python/pki/account.py b/base/common/python/pki/account.py
new file mode 100644
index 000000000..84f2d0ef0
--- /dev/null
+++ b/base/common/python/pki/account.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+# Authors:
+# Endi S. Dewata <edewata@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2013 Red Hat, Inc.
+# All rights reserved.
+#
+
+class AccountClient:
+
+ def __init__(self, connection):
+ self.connection = connection
+
+ def login(self):
+ self.connection.get('account/login')
+
+ def logout(self):
+ self.connection.get('account/logout')
diff --git a/base/common/python/pki/client.py b/base/common/python/pki/client.py
new file mode 100644
index 000000000..7635fe879
--- /dev/null
+++ b/base/common/python/pki/client.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+# Authors:
+# Endi S. Dewata <edewata@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2013 Red Hat, Inc.
+# All rights reserved.
+#
+
+import requests
+
+class PKIConnection:
+
+ def __init__(self,
+ protocol='http',
+ hostname='localhost',
+ port=80,
+ subsystem='ca'):
+
+ self.protocol = protocol
+ self.hostname = hostname
+ self.port = port
+ self.subsystem = subsystem
+
+ self.serverURI = self.protocol + '://' +\
+ self.hostname + ':' + self.port + '/' + \
+ self.subsystem
+
+ self.session = requests.Session()
+ self.session.headers.update({'Accept': 'application/json'})
+
+ def authenticate(self, username=None, password=None):
+ if username is not None and password is not None:
+ self.session.auth = (username, password)
+
+ def get(self, path):
+ r = self.session.get(
+ self.serverURI + '/rest/' + path,
+ verify=False)
+ r.raise_for_status()
+ return r \ No newline at end of file
diff --git a/base/common/python/pki/system.py b/base/common/python/pki/system.py
new file mode 100644
index 000000000..61ffbb9ff
--- /dev/null
+++ b/base/common/python/pki/system.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+# Authors:
+# Endi S. Dewata <edewata@redhat.com>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2013 Red Hat, Inc.
+# All rights reserved.
+#
+
+class SecurityDomainInfo:
+
+ def __init__(self):
+ pass
+
+class SecurityDomainClient:
+
+ def __init__(self, connection):
+ self.connection = connection
+
+ def getSecurityDomainInfo(self):
+ r = self.connection.get('securityDomain/domainInfo')
+
+ info = SecurityDomainInfo()
+ info.name = r.json['DomainInfo']['@id']
+
+ return info
diff --git a/base/deploy/CMakeLists.txt b/base/deploy/CMakeLists.txt
index 94abccdbc..ff9d64545 100644
--- a/base/deploy/CMakeLists.txt
+++ b/base/deploy/CMakeLists.txt
@@ -105,15 +105,6 @@ install(
${SYSCONF_INSTALL_DIR}/pki/
)
-find_package(PythonInterp REQUIRED)
-execute_process(
- COMMAND
- ${PYTHON_EXECUTABLE} -c
- "from distutils.sysconfig import get_python_lib; print get_python_lib()"
- OUTPUT_VARIABLE
- PYTHON_SITE_PACKAGES
- OUTPUT_STRIP_TRAILING_WHITESPACE
-)
install(
FILES
src/scriptlets/configuration.jy
@@ -147,13 +138,6 @@ install(
"execute_process(
COMMAND
${CMAKE_COMMAND} -E touch
- \"\$ENV{DESTDIR}${PYTHON_SITE_PACKAGES}/pki/__init__.py\")"
-)
-install(
- CODE
- "execute_process(
- COMMAND
- ${CMAKE_COMMAND} -E touch
\"\$ENV{DESTDIR}${PYTHON_SITE_PACKAGES}/pki/deployment/__init__.py\")"
)
diff --git a/base/deploy/src/pkispawn b/base/deploy/src/pkispawn
index bca496e1d..65bbaa4a8 100755
--- a/base/deploy/src/pkispawn
+++ b/base/deploy/src/pkispawn
@@ -30,10 +30,12 @@ try:
import ldap
import logging
import os
+ import requests
import socket
import struct
import subprocess
import time
+ import urllib2
from time import strftime as date
from pki.deployment import pkiconfig as config
from pki.deployment.pkiparser import PKIConfigParser
@@ -225,15 +227,33 @@ def main(argv):
print
print "Security Domain:"
- parser.read_text('Name', config.pki_subsystem, 'pki_security_domain_name')
- if config.pki_subsystem != "CA":
- parser.read_text('Hostname', config.pki_subsystem, 'pki_security_domain_hostname')
- parser.read_text('Secure HTTP port', config.pki_subsystem, 'pki_security_domain_https_port')
- parser.read_text('Username', config.pki_subsystem, 'pki_security_domain_user')
- parser.read_password(
- 'Password', config.pki_subsystem, 'pki_security_domain_password',
- verifyMessage='Verify password')
+ if config.pki_subsystem == "CA":
+ parser.read_text('Name', config.pki_subsystem, 'pki_security_domain_name')
+
+ else:
+ while True:
+ parser.read_text('Hostname', config.pki_subsystem, 'pki_security_domain_hostname')
+ parser.read_text('Secure HTTP port', config.pki_subsystem, 'pki_security_domain_https_port')
+
+ try:
+ parser.sd_connect()
+ info = parser.sd_get_info()
+ parser.print_text('Name: ' + info.name)
+ parser.set_property(config.pki_subsystem, 'pki_security_domain_name', info.name)
+ break
+ except requests.exceptions.ConnectionError as e:
+ parser.print_text('ERROR: ' + str(e))
+
+ while True:
+ parser.read_text('Username', config.pki_subsystem, 'pki_security_domain_user')
+ parser.read_password('Password', config.pki_subsystem, 'pki_security_domain_password')
+
+ try:
+ parser.sd_authenticate()
+ break
+ except requests.exceptions.HTTPError as e:
+ parser.print_text('ERROR: ' + str(e))
print
@@ -321,23 +341,40 @@ def main(argv):
config.pki_log.debug(pkilogging.format(config.pki_master_dict),
extra=config.PKI_INDENTATION_LEVEL_0)
- if not interactive:
+ if not interactive and\
+ not config.str2bool(config.pki_master_dict['pki_skip_configuration']):
try:
- if not config.str2bool(config.pki_master_dict['pki_skip_configuration']):
- parser.ds_connect()
- parser.ds_bind()
+ parser.ds_connect()
+ parser.ds_bind()
- if parser.ds_base_dn_exists() and\
- not config.str2bool(config.pki_master_dict['pki_ds_remove_data']):
- print 'ERROR: Base DN already exists.'
- sys.exit(1)
+ if parser.ds_base_dn_exists() and\
+ not config.str2bool(config.pki_master_dict['pki_ds_remove_data']):
+ print 'ERROR: Base DN already exists.'
+ sys.exit(1)
- parser.ds_close()
+ parser.ds_close()
except ldap.LDAPError as e:
- print 'ERROR: ' + e.message['desc']
+ print 'ERROR: Unable to access directory server: ' + e.message['desc']
sys.exit(1)
+ if config.pki_subsystem != "CA" or\
+ config.str2bool(config.pki_master_dict['pki_clone']) or\
+ config.str2bool(config.pki_master_dict['pki_subordinate']):
+ try:
+ parser.sd_connect()
+ info = parser.sd_get_info()
+ parser.set_property(config.pki_subsystem, 'pki_security_domain_name', info.name)
+ parser.sd_authenticate()
+
+ except requests.exceptions.ConnectionError as e:
+ print('ERROR: Unable to access security domain: ' + str(e))
+ sys.exit(1)
+
+ except requests.exceptions.HTTPError as e:
+ print('ERROR: Unable to access security domain: ' + str(e))
+ sys.exit(1)
+
print "Installing " + config.pki_subsystem + " into " + config.pki_master_dict['pki_instance_path'] + "."
# Process the various "scriptlets" to create the specified PKI subsystem.
diff --git a/base/deploy/src/scriptlets/pkilogging.py b/base/deploy/src/scriptlets/pkilogging.py
index 3c146a12c..319616145 100644
--- a/base/deploy/src/scriptlets/pkilogging.py
+++ b/base/deploy/src/scriptlets/pkilogging.py
@@ -43,42 +43,34 @@ def format(dict):
return pp.pformat(new_dict)
# PKI Deployment Logging Functions
-def enable_pki_logger(log_dir, log_name, log_level, console_log_level, logger):
+def enable_pki_logger(log_dir, log_name, log_level, console_log_level, name):
if not os.path.isdir(log_dir):
try:
os.makedirs(log_dir)
except OSError:
return OSError
- # Establish 'file' logger using 'basicConfig()'
- logging.LoggerAdapter(logging.getLogger(''), {'indent' : ''})
- logging.basicConfig(level=log_level,
- format='%(asctime)s %(name)-12s ' +\
- '%(levelname)-8s ' +\
- '%(indent)s%(message)s',
- datefmt='%Y-%m-%d %H:%M:%S',
- filename=log_dir + "/" + log_name,
- filemode='w')
+ # Configure logger
+ logger = logging.getLogger(name)
+ logger.setLevel(log_level)
- # Establish 'console' logger
+ # Configure console handler
console = logging.StreamHandler()
- logging.LoggerAdapter(console, {'indent' : ''})
console.setLevel(console_log_level)
console_format = logging.Formatter('%(name)-12s: ' +\
'%(levelname)-8s ' +\
'%(indent)s%(message)s')
console.setFormatter(console_format)
- logging.getLogger('').addHandler(console)
+ logger.addHandler(console)
- # Establish 'file' logger
-# file = logging.FileHandler(log_dir + "/" + log_name, 'w')
-# logging.LoggerAdapter(file, {'indent' : ''})
-# file.setLevel(log_level)
-# file_format = logging.Formatter('%(asctime)s %(name)-12s: ' +\
-# '%(levelname)-8s ' +\
-# '%(indent)s%(message)s',
-# '%Y-%m-%d %H:%M:%S')
-# file.setFormatter(file_format)
-# logging.getLogger('').addHandler(file)
+ # Configure file handler
+ file = logging.FileHandler(log_dir + "/" + log_name, 'w')
+ file.setLevel(log_level)
+ file_format = logging.Formatter('%(asctime)s %(name)-12s: ' +\
+ '%(levelname)-8s ' +\
+ '%(indent)s%(message)s',
+ '%Y-%m-%d %H:%M:%S')
+ file.setFormatter(file_format)
+ logger.addHandler(file)
- return logging.getLogger(logger)
+ return logger
diff --git a/base/deploy/src/scriptlets/pkiparser.py b/base/deploy/src/scriptlets/pkiparser.py
index eee56ca3e..32a3da154 100644
--- a/base/deploy/src/scriptlets/pkiparser.py
+++ b/base/deploy/src/scriptlets/pkiparser.py
@@ -38,6 +38,9 @@ import pkilogging
import pkiconfig as config
import pkimessages as log
+import pki.account
+import pki.client
+import pki.system
class PKIConfigParser:
@@ -391,6 +394,26 @@ class PKIConfigParser:
def ds_close(self):
self.ds_connection.unbind_s()
+ def sd_connect(self):
+ self.sd_connection = pki.client.PKIConnection(
+ protocol='https',
+ hostname=config.pki_master_dict['pki_security_domain_hostname'],
+ port=config.pki_master_dict['pki_security_domain_https_port'],
+ subsystem='ca')
+
+ def sd_get_info(self):
+ sd = pki.system.SecurityDomainClient(self.sd_connection)
+ return sd.getSecurityDomainInfo()
+
+ def sd_authenticate(self):
+ self.sd_connection.authenticate(
+ config.pki_master_dict['pki_security_domain_user'],
+ config.pki_master_dict['pki_security_domain_password'])
+
+ account = pki.account.AccountClient(self.sd_connection)
+ account.login()
+ account.logout()
+
def compose_pki_master_dictionary(self):
"Create a single master PKI dictionary from the sectional dictionaries"
try: