From 448a55ad6456d85c0ae2fa6cb18814d8d07b6c69 Mon Sep 17 00:00:00 2001 From: Adrian Likins Date: Wed, 30 Apr 2008 03:03:57 -0400 Subject: new file acls.py, start trying to write a class for the acls, so we can support reading/writing/updating them, and eventually, a minion module for it. --- func/minion/acls.py | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ func/minion/server.py | 30 ++------------- func/minion/utils.py | 39 -------------------- 3 files changed, 104 insertions(+), 65 deletions(-) create mode 100644 func/minion/acls.py diff --git a/func/minion/acls.py b/func/minion/acls.py new file mode 100644 index 0000000..786a9c5 --- /dev/null +++ b/func/minion/acls.py @@ -0,0 +1,100 @@ +""" +Copyright 2007, Red Hat, Inc +see AUTHORS + +This software may be freely redistributed under the terms of the GNU +general public license. + +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., 675 Mass Ave, Cambridge, MA 02139, USA. +""" + +import fnmatch +import glob +import os + + + +# TODO: need to track which file got which config from + +class Acls(object): + def __init__(self, acldir=None): + self.acldir = acldir + self.acls = {} + + def load(self): + """ + takes a dir of .acl files + returns a dict of hostname+hash = [methods, to, run] + + """ + + if not os.path.exists(self.acldir): + print 'acl dir does not exist: %s' % self.acldir + return self.acls + + # get the set of files + acl_glob = '%s/*.acl' % self.acldir + files = glob.glob(acl_glob) + + for acl_file in files: + + try: + fo = open(acl_file, 'r') + except (IOError, OSError), e: + print 'cannot open acl config file: %s - %s' % (acl_file, e) + continue + + for line in fo.readlines(): + if line.startswith('#'): continue + if line.strip() == '': continue + line = line.replace('\n', '') + (host, methods) = line.split('=') + host = host.strip().lower() + methods = methods.strip() + methods = methods.replace(',',' ') + methods = methods.split() + if not self.acls.has_key(host): + self.acls[host] = [] + self.acls[host].extend(methods) + + return self.acls + + def check(self, cm_cert, cert, ip, method, params): + + # certmaster always gets to run things + ca_cn = cm_cert.get_subject().CN + ca_hash = cm_cert.subject_name_hash() + ca_key = '%s-%s' % (ca_cn, ca_hash) + self.acls[ca_key] = ['*'] + + cn = cert.get_subject().CN + sub_hash = cert.subject_name_hash() + if self.acls: + allow_list = [] + hostkey = '%s-%s' % (cn, sub_hash) + # search all the keys, match to 'cn-subhash' + for hostmatch in self.acls.keys(): + if fnmatch.fnmatch(hostkey, hostmatch): + allow_list.extend(self.acls[hostmatch]) + # go through the allow_list and make sure this method is in there + for methodmatch in allow_list: + if fnmatch.fnmatch(method, methodmatch): + return True + + return False + + def save(self): + for + + def add(self, acl, host): + pass + + def delete(self, acl, host): + pass + + def update(self, acl, host): + pass + + diff --git a/func/minion/server.py b/func/minion/server.py index c511598..c371680 100755 --- a/func/minion/server.py +++ b/func/minion/server.py @@ -36,6 +36,7 @@ import codes import module_loader import func.utils as futils import func.minion.utils as fmutils +import func.minion.acls as acls_mod from certmaster import utils from certmaster import requester @@ -183,6 +184,8 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, self.ca = "%s/ca.cert" % self.cm_config.cert_dir self._our_ca = certs.retrieve_cert_from_file(self.ca) + + self.acls = acls_mod.Acls(acldir=self.config.acl_dir) AuthedXMLRPCServer.AuthedSSLXMLRPCServer.__init__(self, ("", 51234), self.key, self.cert, @@ -214,7 +217,7 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, async_dispatch = True method = method.replace("async.","",1) - if not self._check_acl(peer_cert, ip, method, params): + if not self.acls.check(self._our_ca, peer_cert, ip, method, params): raise codes.AccessToMethodDenied # Recognize ipython's tab completion calls @@ -239,31 +242,6 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer, peer_cert = request.get_peer_certificate() return peer_cert.get_subject().CN - def _check_acl(self, cert, ip, method, params): - acls = fmutils.get_acls_from_config(acldir=self.config.acl_dir) - - # certmaster always gets to run things - ca_cn = self._our_ca.get_subject().CN - ca_hash = self._our_ca.subject_name_hash() - ca_key = '%s-%s' % (ca_cn, ca_hash) - acls[ca_key] = ['*'] - - cn = cert.get_subject().CN - sub_hash = cert.subject_name_hash() - if acls: - allow_list = [] - hostkey = '%s-%s' % (cn, sub_hash) - # search all the keys, match to 'cn-subhash' - for hostmatch in acls.keys(): - if fnmatch.fnmatch(hostkey, hostmatch): - allow_list.extend(acls[hostmatch]) - # go through the allow_list and make sure this method is in there - for methodmatch in allow_list: - if fnmatch.fnmatch(method, methodmatch): - return True - - return False - def main(argv): diff --git a/func/minion/utils.py b/func/minion/utils.py index acdf613..e8d1b39 100755 --- a/func/minion/utils.py +++ b/func/minion/utils.py @@ -93,42 +93,3 @@ def daemonize(pidfile=None): if pidfile is not None: open(pidfile, "w").write(str(pid)) sys.exit(0) - -def get_acls_from_config(acldir='/etc/func/minion-acl.d'): - """ - takes a dir of .acl files - returns a dict of hostname+hash = [methods, to, run] - - """ - - acls = {} - if not os.path.exists(acldir): - print 'acl dir does not exist: %s' % acldir - return acls - - # get the set of files - acl_glob = '%s/*.acl' % acldir - files = glob.glob(acl_glob) - - for acl_file in files: - - try: - fo = open(acl_file, 'r') - except (IOError, OSError), e: - print 'cannot open acl config file: %s - %s' % (acl_file, e) - continue - - for line in fo.readlines(): - if line.startswith('#'): continue - if line.strip() == '': continue - line = line.replace('\n', '') - (host, methods) = line.split('=') - host = host.strip().lower() - methods = methods.strip() - methods = methods.replace(',',' ') - methods = methods.split() - if not acls.has_key(host): - acls[host] = [] - acls[host].extend(methods) - - return acls -- cgit