Imported Debian patch 4.7.2-3
This commit is contained in:
committed by
Mario Fetka
parent
27edeba051
commit
8bc559c5a1
@@ -1,89 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import os
|
||||
import socket
|
||||
|
||||
from ipapython import ipautil
|
||||
from ipaserver.dnssec._odsbase import AbstractODSDBConnection
|
||||
from ipaserver.dnssec._odsbase import AbstractODSSignerConn
|
||||
from ipaserver.dnssec._odsbase import ODS_SE_MAXLINE
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
|
||||
class ODSDBConnection(AbstractODSDBConnection):
|
||||
def get_zones(self):
|
||||
cur = self._db.execute("SELECT name from zones")
|
||||
rows = cur.fetchall()
|
||||
return [row['name'] for row in rows]
|
||||
|
||||
def get_zone_id(self, zone_name):
|
||||
cur = self._db.execute(
|
||||
"SELECT id FROM zones WHERE LOWER(name)=LOWER(?)",
|
||||
(zone_name,))
|
||||
rows = cur.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_keys_for_zone(self, zone_id):
|
||||
cur = self._db.execute(
|
||||
"SELECT kp.HSMkey_id, kp.generate, kp.algorithm, "
|
||||
"dnsk.publish, dnsk.active, dnsk.retire, dnsk.dead, "
|
||||
"dnsk.keytype, dnsk.state "
|
||||
"FROM keypairs AS kp "
|
||||
"JOIN dnsseckeys AS dnsk ON kp.id = dnsk.keypair_id "
|
||||
"WHERE dnsk.zone_id = ?", (zone_id,))
|
||||
for row in cur:
|
||||
yield row
|
||||
|
||||
|
||||
class ODSSignerConn(AbstractODSSignerConn):
|
||||
def read_cmd(self):
|
||||
cmd = self._conn.recv(ODS_SE_MAXLINE).strip()
|
||||
return cmd
|
||||
|
||||
def send_reply_and_close(self, reply):
|
||||
self._conn.send(reply + b'\n')
|
||||
self._conn.shutdown(socket.SHUT_RDWR)
|
||||
self._conn.close()
|
||||
|
||||
|
||||
class ODSTask():
|
||||
def run_ods_setup(self):
|
||||
"""Initialize a new kasp.db"""
|
||||
cmd = [paths.ODS_KSMUTIL, 'setup']
|
||||
return ipautil.run(cmd, stdin="y", runas=constants.ODS_USER)
|
||||
|
||||
def run_ods_notify(self, **kwargs):
|
||||
"""Notify ods-enforcerd to reload its conf."""
|
||||
cmd = [paths.ODS_KSMUTIL, 'notify']
|
||||
|
||||
# run commands as ODS user
|
||||
if os.geteuid() == 0:
|
||||
kwargs['runas'] = constants.ODS_USER
|
||||
|
||||
return ipautil.run(cmd, **kwargs)
|
||||
|
||||
def run_ods_policy_import(self, **kwargs):
|
||||
"""Run OpenDNSSEC manager command to import policy."""
|
||||
# This step is needed with OpenDNSSEC 2.1 only
|
||||
return
|
||||
|
||||
def run_ods_manager(self, params, **kwargs):
|
||||
"""Run OpenDNSSEC manager command (ksmutil, enforcer)
|
||||
|
||||
:param params: parameter for ODS command
|
||||
:param kwargs: additional arguments for ipautil.run()
|
||||
:return: result from ipautil.run()
|
||||
"""
|
||||
assert params[0] != 'setup'
|
||||
|
||||
cmd = [paths.ODS_KSMUTIL]
|
||||
cmd.extend(params)
|
||||
|
||||
# run commands as ODS user
|
||||
if os.geteuid() == 0:
|
||||
kwargs['runas'] = constants.ODS_USER
|
||||
|
||||
return ipautil.run(cmd, **kwargs)
|
||||
@@ -1,115 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
from datetime import datetime
|
||||
import os
|
||||
|
||||
from ipaserver.dnssec._odsbase import AbstractODSDBConnection
|
||||
from ipaserver.dnssec._odsbase import AbstractODSSignerConn
|
||||
from ipaserver.dnssec._odsbase import ODS_SE_MAXLINE
|
||||
from ipaplatform.constants import constants
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import ipautil
|
||||
|
||||
CLIENT_OPC_STDOUT = 0
|
||||
CLIENT_OPC_EXIT = 4
|
||||
|
||||
|
||||
class ODSDBConnection(AbstractODSDBConnection):
|
||||
def get_zones(self):
|
||||
cur = self._db.execute("SELECT name from zone")
|
||||
rows = cur.fetchall()
|
||||
return [row['name'] for row in rows]
|
||||
|
||||
def get_zone_id(self, zone_name):
|
||||
cur = self._db.execute(
|
||||
"SELECT id FROM zone WHERE LOWER(name)=LOWER(?)",
|
||||
(zone_name,))
|
||||
rows = cur.fetchall()
|
||||
return [row[0] for row in rows]
|
||||
|
||||
def get_keys_for_zone(self, zone_id):
|
||||
cur = self._db.execute(
|
||||
"SELECT hsmk.locator, hsmk.inception, hsmk.algorithm, "
|
||||
"hsmk.keyType, hsmk.state "
|
||||
"FROM hsmKey AS hsmk "
|
||||
"JOIN keyData AS kd ON hsmk.id = kd.hsmKeyId "
|
||||
"WHERE kd.zoneId = ?", (zone_id,))
|
||||
for row in cur:
|
||||
key = dict()
|
||||
key['HSMkey_id'] = row['locator']
|
||||
key['generate'] = str(datetime.fromtimestamp(row['inception']))
|
||||
key['algorithm'] = row['algorithm']
|
||||
key['publish'] = key['generate']
|
||||
key['active'] = None
|
||||
key['retire'] = None
|
||||
key['dead'] = None
|
||||
if row['keyType'] == 2:
|
||||
key['keytype'] = 256
|
||||
elif row['keyType'] == 1:
|
||||
key['keytype'] = 257
|
||||
key['state'] = row['state']
|
||||
yield key
|
||||
|
||||
|
||||
class ODSSignerConn(AbstractODSSignerConn):
|
||||
def read_cmd(self):
|
||||
msg = self._conn.recv(ODS_SE_MAXLINE)
|
||||
_opc = int(msg[0])
|
||||
msglen = int(msg[1]) << 8 + int(msg[2])
|
||||
cmd = msg[3:msglen - 1].strip()
|
||||
return cmd
|
||||
|
||||
def send_reply_and_close(self, reply):
|
||||
prefix = bytearray([CLIENT_OPC_STDOUT, len(reply) >> 8,
|
||||
len(reply) & 255])
|
||||
self._conn.sendall(prefix + reply)
|
||||
# 2nd message: CLIENT_OPC_EXIT, then len, msg len, exit code
|
||||
prefix = bytearray([CLIENT_OPC_EXIT, 0, 1, 0])
|
||||
self._conn.sendall(prefix)
|
||||
self._conn.close()
|
||||
|
||||
|
||||
class ODSTask():
|
||||
def run_ods_setup(self):
|
||||
"""Initialize a new kasp.db"""
|
||||
cmd = [paths.ODS_ENFORCER_DB_SETUP]
|
||||
return ipautil.run(cmd, stdin="y", runas=constants.ODS_USER)
|
||||
|
||||
def run_ods_notify(self, **kwargs):
|
||||
"""Notify ods-enforcerd to reload its conf."""
|
||||
cmd = [paths.ODS_ENFORCER, 'flush']
|
||||
|
||||
# run commands as ODS user
|
||||
if os.geteuid() == 0:
|
||||
kwargs['runas'] = constants.ODS_USER
|
||||
|
||||
return ipautil.run(cmd, **kwargs)
|
||||
|
||||
def run_ods_policy_import(self, **kwargs):
|
||||
"""Run OpenDNSSEC manager command to import policy."""
|
||||
cmd = [paths.ODS_ENFORCER, 'policy', 'import']
|
||||
|
||||
# run commands as ODS user
|
||||
if os.geteuid() == 0:
|
||||
kwargs['runas'] = constants.ODS_USER
|
||||
ipautil.run(cmd, **kwargs)
|
||||
|
||||
def run_ods_manager(self, params, **kwargs):
|
||||
"""Run OpenDNSSEC manager command (ksmutil, enforcer)
|
||||
|
||||
:param params: parameter for ODS command
|
||||
:param kwargs: additional arguments for ipautil.run()
|
||||
:return: result from ipautil.run()
|
||||
"""
|
||||
assert params[0] != 'setup'
|
||||
|
||||
cmd = [paths.ODS_ENFORCER]
|
||||
cmd.extend(params)
|
||||
|
||||
# run commands as ODS user
|
||||
if os.geteuid() == 0:
|
||||
kwargs['runas'] = constants.ODS_USER
|
||||
|
||||
return ipautil.run(cmd, **kwargs)
|
||||
@@ -1,52 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import six
|
||||
import abc
|
||||
import sqlite3
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
ODS_SE_MAXLINE = 1024 # from ODS common/config.h
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AbstractODSDBConnection():
|
||||
"""Abstract class representing the Connection to ODS database."""
|
||||
def __init__(self):
|
||||
"""Creates a connection to the kasp database."""
|
||||
self._db = sqlite3.connect(paths.OPENDNSSEC_KASP_DB)
|
||||
self._db.row_factory = sqlite3.Row
|
||||
self._db.execute('BEGIN')
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_zones(self):
|
||||
"""Returns a list of zone names."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_zone_id(self, zone_name):
|
||||
"""Returns a list of zone ids for the given zone_name."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def get_keys_for_zone(self, zone_id):
|
||||
"""Returns a list of keys for the given zone_id."""
|
||||
|
||||
def close(self):
|
||||
"""Closes the connection to the kasp database."""
|
||||
self._db.close()
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class AbstractODSSignerConn():
|
||||
"""Abstract class representing the Connection to ods-signer."""
|
||||
def __init__(self, conn):
|
||||
"""Initializes the object with a socket conn."""
|
||||
self._conn = conn
|
||||
|
||||
@abc.abstractmethod
|
||||
def read_cmd(self):
|
||||
"""Reads the next command on the connection."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def send_reply_and_close(self, reply):
|
||||
"""Sends the reply on the connection."""
|
||||
@@ -174,7 +174,7 @@ def ldap2p11helper_api_params(ldap_key):
|
||||
return unwrap_params
|
||||
|
||||
|
||||
class AbstractHSM:
|
||||
class AbstractHSM(object):
|
||||
def _filter_replica_keys(self, all_keys):
|
||||
replica_keys = {}
|
||||
for key_id, key in all_keys.items():
|
||||
|
||||
@@ -31,8 +31,7 @@ time_bindfmt = '%Y%m%d%H%M%S'
|
||||
FILE_PERM = (stat.S_IRUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IWUSR)
|
||||
DIR_PERM = (stat.S_IRWXU | stat.S_IRWXG)
|
||||
|
||||
|
||||
class BINDMgr:
|
||||
class BINDMgr(object):
|
||||
"""BIND key manager. It does LDAP->BIND key files synchronization.
|
||||
|
||||
One LDAP object with idnsSecKey object class will produce
|
||||
|
||||
@@ -5,14 +5,12 @@
|
||||
import logging
|
||||
|
||||
import dns.name
|
||||
import re
|
||||
try:
|
||||
from xml.etree import cElementTree as etree
|
||||
except ImportError:
|
||||
from xml.etree import ElementTree as etree
|
||||
|
||||
from ipapython import ipa_log_manager, ipautil
|
||||
from ipaserver.dnssec.opendnssec import tasks
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -21,7 +19,7 @@ ENTRYUUID_PREFIX = "/var/lib/ipa/dns/zone/entryUUID/"
|
||||
ENTRYUUID_PREFIX_LEN = len(ENTRYUUID_PREFIX)
|
||||
|
||||
|
||||
class ZoneListReader:
|
||||
class ZoneListReader(object):
|
||||
def __init__(self):
|
||||
self.names = set() # dns.name
|
||||
self.uuids = set() # UUID strings
|
||||
@@ -121,7 +119,7 @@ class LDAPZoneListReader(ZoneListReader):
|
||||
self._del_zone(zone_ldap['idnsname'][0], uuid)
|
||||
|
||||
|
||||
class ODSMgr:
|
||||
class ODSMgr(object):
|
||||
"""OpenDNSSEC zone manager. It does LDAP->ODS synchronization.
|
||||
|
||||
Zones with idnsSecInlineSigning attribute = TRUE in LDAP are added
|
||||
@@ -132,75 +130,42 @@ class ODSMgr:
|
||||
self.zl_ldap = LDAPZoneListReader()
|
||||
|
||||
def ksmutil(self, params):
|
||||
"""Call ods-ksmutil / ods-enforcer with parameters and return stdout.
|
||||
"""Call ods-ksmutil with given parameters and return stdout.
|
||||
|
||||
Raises CalledProcessError if returncode != 0.
|
||||
"""
|
||||
result = tasks.run_ods_manager(params, capture_output=True)
|
||||
cmd = ['ods-ksmutil'] + params
|
||||
result = ipautil.run(cmd, capture_output=True)
|
||||
return result.output
|
||||
|
||||
def get_ods_zonelist(self):
|
||||
stdout = self.ksmutil(['zonelist', 'export'])
|
||||
try:
|
||||
reader = ODSZoneListReader(stdout)
|
||||
except etree.ParseError:
|
||||
# With OpenDNSSEC 2, the above command returns a message
|
||||
# containing the zonelist filename instead of the XML text:
|
||||
# "Exported zonelist to /etc/opendnssec/zonelist.xml successfully"
|
||||
# extract the filename and read its content
|
||||
pattern = re.compile(r'.* (/.*) .*')
|
||||
matches = re.findall(pattern, stdout)
|
||||
if matches:
|
||||
with open(matches[0]) as f:
|
||||
content = f.read()
|
||||
reader = ODSZoneListReader(content)
|
||||
|
||||
reader = ODSZoneListReader(stdout)
|
||||
return reader
|
||||
|
||||
def add_ods_zone(self, uuid, name):
|
||||
zone_path = '%s%s' % (ENTRYUUID_PREFIX, uuid)
|
||||
if name != dns.name.root:
|
||||
name = name.relativize(dns.name.root)
|
||||
cmd = ['zone', 'add', '--zone', str(name), '--input', zone_path]
|
||||
output = None
|
||||
try:
|
||||
output = self.ksmutil(cmd)
|
||||
except ipautil.CalledProcessError as e:
|
||||
# Zone already exists in HSM
|
||||
if e.returncode == 1 \
|
||||
and str(e.output).endswith(str(name) + ' already exists!'):
|
||||
# Just return
|
||||
return
|
||||
if output is not None:
|
||||
logger.info('%s', output)
|
||||
self.notify_enforcer()
|
||||
output = self.ksmutil(cmd)
|
||||
logger.info('%s', output)
|
||||
self.notify_enforcer()
|
||||
|
||||
def del_ods_zone(self, name):
|
||||
# ods-ksmutil blows up if zone name has period at the end
|
||||
if name != dns.name.root:
|
||||
name = name.relativize(dns.name.root)
|
||||
name = name.relativize(dns.name.root)
|
||||
# detect if name is root zone
|
||||
if name == dns.name.empty:
|
||||
name = dns.name.root
|
||||
cmd = ['zone', 'delete', '--zone', str(name)]
|
||||
output = None
|
||||
try:
|
||||
output = self.ksmutil(cmd)
|
||||
except ipautil.CalledProcessError as e:
|
||||
# Zone already doesn't exist in HSM
|
||||
if e.returncode == 1 \
|
||||
and str(e.output).endswith(str(name) + ' not found!'):
|
||||
# Just cleanup signer, no need to notify enforcer
|
||||
self.cleanup_signer(name)
|
||||
return
|
||||
if output is not None:
|
||||
logger.info('%s', output)
|
||||
self.notify_enforcer()
|
||||
self.cleanup_signer(name)
|
||||
output = self.ksmutil(cmd)
|
||||
logger.info('%s', output)
|
||||
self.notify_enforcer()
|
||||
self.cleanup_signer(name)
|
||||
|
||||
def notify_enforcer(self):
|
||||
result = tasks.run_ods_notify(capture_output=True)
|
||||
logger.info('%s', result.output)
|
||||
cmd = ['notify']
|
||||
output = self.ksmutil(cmd)
|
||||
logger.info('%s', output)
|
||||
|
||||
def cleanup_signer(self, zone_name):
|
||||
cmd = ['ods-signer', 'ldap-cleanup', str(zone_name)]
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import os
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
# pylint: disable=unused-import
|
||||
if paths.ODS_KSMUTIL is not None and os.path.exists(paths.ODS_KSMUTIL):
|
||||
from ._ods14 import ODSDBConnection, ODSSignerConn, ODSTask
|
||||
else:
|
||||
from ._ods21 import ODSDBConnection, ODSSignerConn, ODSTask
|
||||
|
||||
tasks = ODSTask()
|
||||
@@ -6,8 +6,7 @@ import errno
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
|
||||
class TemporaryDirectory:
|
||||
class TemporaryDirectory(object):
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
|
||||
|
||||
Reference in New Issue
Block a user