summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSeth Vidal <skvidal@fedoraproject.org>2007-10-08 14:59:28 -0400
committerSeth Vidal <skvidal@fedoraproject.org>2007-10-08 14:59:28 -0400
commit9033fe7cc3c6a59bd90c4742a47536699dee612d (patch)
tree7464fb9f366e121d86947f2f900755d681612e14
parentce379bdb3d6ade0a6326d5d7cf9446389cf4d94b (diff)
downloadfunc-9033fe7cc3c6a59bd90c4742a47536699dee612d.tar.gz
func-9033fe7cc3c6a59bd90c4742a47536699dee612d.tar.xz
func-9033fe7cc3c6a59bd90c4742a47536699dee612d.zip
fine-grained acls per minion
- adds minion-acl.conf
-rw-r--r--etc/minion-acl.conf5
-rw-r--r--etc/minion.conf2
-rw-r--r--func/commonconfig.py2
-rwxr-xr-xfunc/minion/server.py32
-rwxr-xr-xfunc/minion/utils.py37
5 files changed, 66 insertions, 12 deletions
diff --git a/etc/minion-acl.conf b/etc/minion-acl.conf
new file mode 100644
index 0000000..1a093a8
--- /dev/null
+++ b/etc/minion-acl.conf
@@ -0,0 +1,5 @@
+#config file for minion Access control lists
+#this specifies which methods a connecting client is allowed to run
+# format is: cn-certificate-hash = method1, method2, method3
+# default allows the certmaster key to run all methods
+
diff --git a/etc/minion.conf b/etc/minion.conf
index 9e18eac..dc4c0a1 100644
--- a/etc/minion.conf
+++ b/etc/minion.conf
@@ -4,4 +4,4 @@
log_level = DEBUG
certmaster = certmaster
cert_dir = /etc/pki/func
-
+acl_config = /etc/func/minion-acl.conf
diff --git a/func/commonconfig.py b/func/commonconfig.py
index cbf031e..e3b1760 100644
--- a/func/commonconfig.py
+++ b/func/commonconfig.py
@@ -13,3 +13,5 @@ class FuncdConfig(BaseConfig):
log_level = Option('INFO')
certmaster = Option('certmaster')
cert_dir = Option('/etc/pki/func')
+ acl_config = Option('/etc/func/minion-acl.conf')
+
diff --git a/func/minion/server.py b/func/minion/server.py
index 39a78cb..921aa03 100755
--- a/func/minion/server.py
+++ b/func/minion/server.py
@@ -20,6 +20,7 @@ import string
import sys
import traceback
import socket
+import fnmatch
from gettext import textdomain
I18N_DOMAIN = "func"
@@ -51,7 +52,7 @@ class XmlRpcInterface(object):
self.logger = logger.Logger().logger
self.audit_logger = logger.AuditLogger()
self.__setup_handlers()
-
+
# need a reference so we can log ip's, certs, etc
# self.server = server
@@ -213,18 +214,27 @@ class FuncSSLXMLRPCServer(AuthedXMLRPCServer.AuthedSSLXMLRPCServer,
return peer_cert.get_subject().CN
def _check_acl(self, cert, ip, method, params):
- cn = cert.get_subject().CN
- sub_hash = cert.subject_name_hash()
- # FIXME - make this be more useful, obviously :)
- # until we figure out the right config - just say - if the cert
- # is not the cert of our ca (which is where overlord/func/certmaster
- # runs then return False
+ acls = utils.get_acls_from_config(fn=self.config.acl_config)
+ # certmaster always gets to run things
ca_cn = self._our_ca.get_subject().CN
ca_hash = self._our_ca.subject_name_hash()
- if cn == ca_cn and sub_hash == ca_hash:
- return True
-
- # clearly other method/param checks here
+ 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 d13808e..447acc8 100755
--- a/func/minion/utils.py
+++ b/func/minion/utils.py
@@ -157,3 +157,40 @@ def daemonize(pidfile=None):
if pidfile is not None:
open(pidfile, "w").write(str(pid))
sys.exit(0)
+
+def get_acls_from_config(fn='/etc/func/minion-acl.conf'):
+ """
+ takes a fn = filename of config file
+ returns a dict of hostname+hash = [methods, to, run]
+
+ """
+
+ acls = {}
+ if not os.path.exists(fn):
+ print 'acl config file does not exist: %s' % fn
+ return acls
+ try:
+ fo = open(fn, 'r')
+ except (IOError, OSError), e:
+ print 'cannot open acl config file: %s' % e
+ return acls
+
+ 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
+
+
+
+
+